Update Search & Replace floater to latest version from Kitty Barnett (Catznip viewer)

Ansariel 2014-09-02 12:17:52 +02:00
parent 487540a25f
commit f166eed059
21 changed files with 450 additions and 186 deletions

View File

@ -43,6 +43,9 @@
#include "llview.h"
#include "llwindow.h"
#include <boost/bind.hpp>
// [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6)
#include <boost/algorithm/string.hpp>
// [/SL:KB]
#include "fsregistrarutils.h"
@ -165,6 +168,9 @@ LLTextBase::Params::Params()
bg_readonly_color("bg_readonly_color"),
bg_writeable_color("bg_writeable_color"),
bg_focus_color("bg_focus_color"),
// [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6)
bg_highlighted_color("bg_highlighted_color"),
// [/SL:KB]
text_selected_color("text_selected_color"),
bg_selected_color("bg_selected_color"),
allow_scroll("allow_scroll", true),
@ -214,6 +220,9 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
mWriteableBgColor(p.bg_writeable_color),
mReadOnlyBgColor(p.bg_readonly_color),
mFocusBgColor(p.bg_focus_color),
// [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6)
mHighlightedBGColor(p.bg_highlighted_color),
// [/SL:KB]
mTextSelectedColor(p.text_selected_color),
mSelectedBGColor(p.bg_selected_color),
mReflowIndex(S32_MAX),
@ -372,17 +381,32 @@ void LLTextBase::onValueChange(S32 start, S32 end)
{
}
// Draws the black box behind the selected text
//void LLTextBase::drawSelectionBackground()
// [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6)
void LLTextBase::drawSelectionBackground()
{
// Draw selection even if we don't have keyboard focus for search/replace
if( hasSelection() && !mLineInfoList.empty())
{
highlight_list_t highlights;
highlights.push_back(range_pair_t(llmin(mSelectionStart, mSelectionEnd), llmax(mSelectionStart, mSelectionEnd)));
drawHighlightsBackground(highlights, mSelectedBGColor);
}
}
void LLTextBase::drawHighlightsBackground(const highlight_list_t& highlights, const LLColor4& color)
// [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6)
{
// // Draw selection even if we don't have keyboard focus for search/replace
// if( hasSelection() && !mLineInfoList.empty())
// [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6)
if (!mLineInfoList.empty())
// [/SL:KB]
{
std::vector<LLRect> selection_rects;
S32 selection_left = llmin( mSelectionStart, mSelectionEnd );
S32 selection_right = llmax( mSelectionStart, mSelectionEnd );
// S32 selection_left = llmin( mSelectionStart, mSelectionEnd );
// S32 selection_right = llmax( mSelectionStart, mSelectionEnd );
// Skip through the lines we aren't drawing.
LLRect content_display_rect = getVisibleDocumentRect();
@ -391,73 +415,103 @@ void LLTextBase::drawSelectionBackground()
line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mTop, compare_bottom());
line_list_t::const_iterator end_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mBottom, compare_top());
bool done = false;
// bool done = false;
// [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6)
highlight_list_t::const_iterator itHighlight = highlights.begin();
// [/SL:KB]
// Find the coordinates of the selected area
for (;line_iter != end_iter && !done; ++line_iter)
// for (;line_iter != end_iter && !done; ++line_iter)
// [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6)
for (; (line_iter != end_iter) && (itHighlight != highlights.end()); ++line_iter)
// [/SL:KB]
{
// is selection visible on this line?
if (line_iter->mDocIndexEnd > selection_left && line_iter->mDocIndexStart < selection_right)
// [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6)
// Find a highlight range with an end index larger than the start of this line
while ( (itHighlight != highlights.end()) && (line_iter->mDocIndexStart > itHighlight->second) )
++itHighlight;
// Draw all highlights on the current line
while ( (itHighlight != highlights.end()) && (itHighlight->first < line_iter->mDocIndexEnd) )
{
segment_set_t::iterator segment_iter;
S32 segment_offset;
getSegmentAndOffset(line_iter->mDocIndexStart, &segment_iter, &segment_offset);
LLRect selection_rect;
selection_rect.mLeft = line_iter->mRect.mLeft;
selection_rect.mRight = line_iter->mRect.mLeft;
selection_rect.mBottom = line_iter->mRect.mBottom;
selection_rect.mTop = line_iter->mRect.mTop;
for(;segment_iter != mSegments.end(); ++segment_iter, segment_offset = 0)
// Keep the names of these to change fewer lines of LL code
S32 selection_left = llmin(itHighlight->first, itHighlight->second);
S32 selection_right = llmax(itHighlight->first, itHighlight->second) ;
// [/SL:KB]
// is selection visible on this line?
if (line_iter->mDocIndexEnd > selection_left && line_iter->mDocIndexStart < selection_right)
{
LLTextSegmentPtr segmentp = *segment_iter;
S32 segment_line_start = segmentp->getStart() + segment_offset;
S32 segment_line_end = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd);
if (segment_line_start > segment_line_end) break;
S32 segment_width = 0;
S32 segment_height = 0;
// if selection after beginning of segment
if(selection_left >= segment_line_start)
segment_set_t::iterator segment_iter;
S32 segment_offset;
getSegmentAndOffset(line_iter->mDocIndexStart, &segment_iter, &segment_offset);
LLRect selection_rect;
selection_rect.mLeft = line_iter->mRect.mLeft;
selection_rect.mRight = line_iter->mRect.mLeft;
selection_rect.mBottom = line_iter->mRect.mBottom;
selection_rect.mTop = line_iter->mRect.mTop;
for(;segment_iter != mSegments.end(); ++segment_iter, segment_offset = 0)
{
S32 num_chars = llmin(selection_left, segment_line_end) - segment_line_start;
segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height);
selection_rect.mLeft += segment_width;
}
LLTextSegmentPtr segmentp = *segment_iter;
// if selection_right == segment_line_end then that means we are the first character of the next segment
// or first character of the next line, in either case we want to add the length of the current segment
// to the selection rectangle and continue.
// if selection right > segment_line_end then selection spans end of current segment...
if (selection_right >= segment_line_end)
{
// extend selection slightly beyond end of line
// to indicate selection of newline character (use "n" character to determine width)
S32 num_chars = segment_line_end - segment_line_start;
segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height);
selection_rect.mRight += segment_width;
}
// else if selection ends on current segment...
else
{
S32 num_chars = selection_right - segment_line_start;
segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height);
selection_rect.mRight += segment_width;
S32 segment_line_start = segmentp->getStart() + segment_offset;
S32 segment_line_end = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd);
break;
if (segment_line_start > segment_line_end) break;
S32 segment_width = 0;
S32 segment_height = 0;
// if selection after beginning of segment
if(selection_left >= segment_line_start)
{
S32 num_chars = llmin(selection_left, segment_line_end) - segment_line_start;
segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height);
selection_rect.mLeft += segment_width;
}
// if selection_right == segment_line_end then that means we are the first character of the next segment
// or first character of the next line, in either case we want to add the length of the current segment
// to the selection rectangle and continue.
// if selection right > segment_line_end then selection spans end of current segment...
if (selection_right >= segment_line_end)
{
// extend selection slightly beyond end of line
// to indicate selection of newline character (use "n" character to determine width)
S32 num_chars = segment_line_end - segment_line_start;
segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height);
selection_rect.mRight += segment_width;
}
// else if selection ends on current segment...
else
{
S32 num_chars = selection_right - segment_line_start;
segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height);
selection_rect.mRight += segment_width;
// [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6)
continue;
// [/SL:KB]
// break;
}
}
selection_rects.push_back(selection_rect);
}
selection_rects.push_back(selection_rect);
// [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6)
// Only advance if the highlight ends on the current line
if (itHighlight->second > line_iter->mDocIndexEnd)
break;
++itHighlight;
}
// [/SL:KB]
}
// Draw the selection box (we're using a box instead of reversing the colors on the selected text).
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
const LLColor4& color = mSelectedBGColor;
// const LLColor4& color = mSelectedBGColor;
F32 alpha = hasFocus() ? 0.7f : 0.3f;
alpha *= getDrawContext().mAlpha;
LLColor4 selection_color(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], alpha);
@ -1270,6 +1324,12 @@ void LLTextBase::draw()
drawChild(mDocumentView);
}
// [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6)
if (mHighlightsDirty)
refreshHighlights();
if (!mHighlights.empty())
drawHighlightsBackground(mHighlights, mHighlightedBGColor);
// [/SL:KB]
drawSelectionBackground();
drawText();
drawCursor();
@ -2302,6 +2362,10 @@ void LLTextBase::needsReflow(S32 index)
{
LL_DEBUGS() << "reflow on object " << (void*)this << " index = " << mReflowIndex << ", new index = " << index << LL_ENDL;
mReflowIndex = llmin(mReflowIndex, index);
// [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6)
mHighlightsDirty = true;
// [/SL:KB]
}
void LLTextBase::appendLineBreakSegment(const LLStyle::Params& style_params)
@ -2818,6 +2882,53 @@ bool LLTextBase::scrolledToEnd()
return mScroller->isAtBottom();
}
// [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6)
void LLTextBase::clearHighlights()
{
mHighlightWord.clear();
mHighlights.clear();
mHighlightsDirty = false;
}
void LLTextBase::refreshHighlights()
{
if (mHighlightsDirty)
{
mHighlights.clear();
if (!mHighlightWord.empty())
{
const LLWString& wstrText = getWText();
std::list<boost::iterator_range<LLWString::const_iterator> > highlightRanges;
if (mHighlightCaseInsensitive)
boost::ifind_all(highlightRanges, wstrText, mHighlightWord);
else
boost::find_all(highlightRanges, wstrText, mHighlightWord);
for (std::list<boost::iterator_range<LLWString::const_iterator> >::const_iterator itRange = highlightRanges.begin(); itRange != highlightRanges.end(); ++itRange)
{
S32 idxStart = itRange->begin() - wstrText.begin();
mHighlights.push_back(range_pair_t(idxStart, idxStart + itRange->size()));
}
}
mHighlightsDirty = false;
}
}
void LLTextBase::setHighlightWord(const std::string& strHighlight, bool fCaseInsensitive)
{
if (strHighlight.empty())
{
clearHighlights();
return;
}
mHighlightWord = utf8str_to_wstring(strHighlight);
mHighlightCaseInsensitive = fCaseInsensitive;
mHighlightsDirty = true;
}
// [/SL:KB]
bool LLTextBase::setCursor(S32 row, S32 column)
{
if (row < 0 || column < 0) return false;

View File

@ -302,6 +302,9 @@ public:
bg_readonly_color,
bg_writeable_color,
bg_focus_color,
// [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6)
bg_highlighted_color,
// [/SL:KB]
text_selected_color,
bg_selected_color;
@ -468,6 +471,13 @@ public:
bool scrolledToStart();
bool scrolledToEnd();
// [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6)
// highlighting
void clearHighlights();
void refreshHighlights();
void setHighlightWord(const std::string& strHighlight, bool fCaseInsensitive);
// [/SL:KB]
const LLFontGL* getFont() const { return mFont; }
virtual void appendLineBreakSegment(const LLStyle::Params& style_params);
@ -485,6 +495,10 @@ protected:
struct compare_top;
struct line_end_compare;
typedef std::vector<LLTextSegmentPtr> segment_vec_t;
// [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6)
typedef std::pair<S32, S32> range_pair_t;
typedef std::list<range_pair_t> highlight_list_t;
// [/SL:KB]
// Abstract inner base class representing an undoable editor command.
// Concrete sub-classes can be defined for operations such as insert, remove, etc.
@ -552,6 +566,9 @@ protected:
// draw methods
void drawSelectionBackground(); // draws the black box behind the selected text
// [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6)
void drawHighlightsBackground(const highlight_list_t& highlights, const LLColor4& color);
// [/SL:KB]
void drawCursor();
void drawText();
@ -638,6 +655,9 @@ protected:
LLUIColor mFocusBgColor;
LLUIColor mTextSelectedColor;
LLUIColor mSelectedBGColor;
// [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6)
LLUIColor mHighlightedBGColor;
// [/SL:KB]
// cursor
S32 mCursorPos; // I-beam is just after the mCursorPos-th character.
@ -659,6 +679,14 @@ protected:
std::list<std::pair<U32, U32> > mMisspellRanges;
std::vector<std::string> mSuggestionList;
// [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6)
// highlighting
LLWString mHighlightWord;
bool mHighlightCaseInsensitive;
highlight_list_t mHighlights;
bool mHighlightsDirty;
// [/SL:KB]
// configuration
S32 mHPad; // padding on left of text
S32 mVPad; // padding above text

View File

@ -342,6 +342,15 @@ void LLTextEditor::setText(const LLStringExplicit &utf8str, const LLStyle::Param
resetDirty();
}
// [SL:KB] - Patch: UI-FloaterSearchReplace | Checked: 2013-12-30 (Catznip-3.6)
std::string LLTextEditor::getSelectionString() const
{
S32 idxSel = 0, lenSel = 0;
getSelectionRange(&idxSel, &lenSel);
return (lenSel > 0) ? wstring_to_utf8str(getWText().substr(idxSel, lenSel)) : LLStringUtil::null;
}
// [/SL:KB]
//void LLTextEditor::selectNext(const std::string& search_text_in, BOOL case_insensitive, BOOL wrap)
// [SL:KB] - Patch: UI-FloaterSearchReplace | Checked: 2010-10-29 (Catznip-2.3.0a) | Added: Catznip-2.3.0a
void LLTextEditor::selectNext(const std::string& search_text_in, BOOL case_insensitive, BOOL wrap, BOOL search_up)

View File

@ -148,6 +148,7 @@ public:
// void selectNext(const std::string& search_text_in, BOOL case_insensitive, BOOL wrap = TRUE);
// [SL:KB] - Patch: UI-FloaterSearchReplace | Checked: 2010-10-29 (Catznip-2.3.0a) | Added: Catznip-2.3.0a
std::string getSelectionString() const;
void selectNext(const std::string& search_text_in, BOOL case_insensitive, BOOL wrap = TRUE, BOOL search_up = FALSE);
BOOL replaceText(const std::string& search_text, const std::string& replace_text, BOOL case_insensitive, BOOL wrap = TRUE, BOOL search_up = FALSE);
// [/SL:KB]

View File

@ -1,39 +1,39 @@
/**
* @file llfloatersearchreplace.cpp
* @brief LLFloaterSearchReplace class implementation
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
* Copyright (c) 2010-2013, Kitty Barnett
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
* The source code in this file is provided to you under the terms of the
* GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. Terms of the LGPL can be found in doc/LGPL-licence.txt
* in this distribution, or online at http://www.gnu.org/licenses/lgpl-2.1.txt
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* By copying, modifying or distributing this software, you acknowledge that
* you have read and understood your obligations described above, and agree to
* abide by those obligations.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llfloatersearchreplace.h"
#include "llcheckboxctrl.h"
#include "llfloaterreg.h"
#include "llfloatersearchreplace.h"
#include "lllineeditor.h"
#include "llmultifloater.h"
#include "lltexteditor.h"
#include "llviewermenu.h"
// ============================================================================
// LLFloaterSearchReplace class
//
LLFloaterSearchReplace::LLFloaterSearchReplace(const LLSD& sdKey)
: LLFloater(sdKey), mEditor(NULL)
: LLFloater(sdKey)
, m_pSearchEditor(NULL)
, m_pReplaceEditor(NULL)
, m_pCaseInsensitiveCheck(NULL)
, m_pSearchUpCheck(NULL)
{
}
@ -41,84 +41,63 @@ LLFloaterSearchReplace::~LLFloaterSearchReplace()
{
}
//static
void LLFloaterSearchReplace::show(LLTextEditor* pEditor)
{
LLFloaterSearchReplace* pSelf = LLFloaterReg::getTypedInstance<LLFloaterSearchReplace>("search_replace");
if (!pSelf)
return;
pSelf->mEditor = pEditor;
if (pEditor)
{
LLFloater *pDependeeNew = NULL, *pDependeeOld = pSelf->getDependee();
LLView* pView = pEditor->getParent();
while (pView)
{
pDependeeNew = dynamic_cast<LLFloater*>(pView);
if (pDependeeNew)
{
if (pDependeeNew != pDependeeOld)
{
if (pDependeeOld)
pDependeeOld->removeDependentFloater(pSelf);
if (!pDependeeNew->getHost())
pDependeeNew->addDependentFloater(pSelf);
else
pDependeeNew->getHost()->addDependentFloater(pSelf);
}
break;
}
pView = pView->getParent();
}
pSelf->getChildView("replace_text")->setEnabled(!pEditor->getReadOnly());
pSelf->getChildView("replace_btn")->setEnabled(!pEditor->getReadOnly());
pSelf->getChildView("replace_all_btn")->setEnabled(!pEditor->getReadOnly());
pSelf->getChildView("search_text")->setFocus(TRUE);
pSelf->openFloater();
}
}
BOOL LLFloaterSearchReplace::postBuild()
{
childSetAction("search_btn", boost::bind(&LLFloaterSearchReplace::onBtnSearch, this));
childSetAction("replace_btn", boost::bind(&LLFloaterSearchReplace::onBtnReplace, this));
childSetAction("replace_all_btn", boost::bind(&LLFloaterSearchReplace::onBtnReplaceAll, this));
m_pSearchEditor = getChild<LLLineEditor>("search_text");
m_pSearchEditor->setCommitCallback(boost::bind(&LLFloaterSearchReplace::onSearchClick, this));
m_pSearchEditor->setCommitOnFocusLost(false);
m_pSearchEditor->setKeystrokeCallback(boost::bind(&LLFloaterSearchReplace::refreshHighlight, this), NULL);
m_pReplaceEditor = getChild<LLLineEditor>("replace_text");
setDefaultBtn("search_btn");
m_pCaseInsensitiveCheck = getChild<LLCheckBoxCtrl>("case_text");
m_pCaseInsensitiveCheck->setCommitCallback(boost::bind(&LLFloaterSearchReplace::refreshHighlight, this));
m_pSearchUpCheck = getChild<LLCheckBoxCtrl>("find_previous");
LLButton* pSearchBtn = getChild<LLButton>("search_btn");
pSearchBtn->setCommitCallback(boost::bind(&LLFloaterSearchReplace::onSearchClick, this));
setDefaultBtn(pSearchBtn);
LLButton* pReplaceBtn = getChild<LLButton>("replace_btn");
pReplaceBtn->setCommitCallback(boost::bind(&LLFloaterSearchReplace::onReplaceClick, this));
LLButton* pReplaceAllBtn = getChild<LLButton>("replace_all_btn");
pReplaceAllBtn->setCommitCallback(boost::bind(&LLFloaterSearchReplace::onReplaceAllClick, this));
return TRUE;
}
void LLFloaterSearchReplace::onBtnSearch()
void LLFloaterSearchReplace::onOpen(const LLSD& sdKey)
{
LLCheckBoxCtrl* caseChk = getChild<LLCheckBoxCtrl>("case_text");
LLCheckBoxCtrl* prevChk = getChild<LLCheckBoxCtrl>("find_previous");
mEditor->selectNext(getChild<LLUICtrl>("search_text")->getValue().asString(), caseChk->get(), TRUE, prevChk->get());
LLTextEditor* pEditor = getEditor();
if (pEditor)
{
// HACK-Catznip: hasSelection() is inaccessible but canCopy() is (currently) a synonym *sighs*
if (pEditor->canCopy())
{
m_pSearchEditor->setText(pEditor->getSelectionString());
m_pSearchEditor->setCursorToEnd();
}
pEditor->setHighlightWord(m_pSearchEditor->getText(), m_pCaseInsensitiveCheck->get());
m_pReplaceEditor->setEnabled( (pEditor) && (!pEditor->getReadOnly()) );
getChild<LLButton>("replace_btn")->setEnabled( (pEditor) && (!pEditor->getReadOnly()) );
getChild<LLButton>("replace_all_btn")->setEnabled( (pEditor) && (!pEditor->getReadOnly()) );
}
m_pSearchEditor->setFocus(TRUE);
}
void LLFloaterSearchReplace::onBtnReplace()
void LLFloaterSearchReplace::onClose(bool fQuiting)
{
LLCheckBoxCtrl* caseChk = getChild<LLCheckBoxCtrl>("case_text");
LLCheckBoxCtrl* prevChk = getChild<LLCheckBoxCtrl>("find_previous");
mEditor->replaceText(
getChild<LLUICtrl>("search_text")->getValue().asString(), getChild<LLUICtrl>("replace_text")->getValue().asString(), caseChk->get(), TRUE, prevChk->get());
}
void LLFloaterSearchReplace::onBtnReplaceAll()
{
LLCheckBoxCtrl* caseChk = getChild<LLCheckBoxCtrl>("case_text");
mEditor->replaceTextAll(getChild<LLUICtrl>("search_text")->getValue().asString(), getChild<LLUICtrl>("replace_text")->getValue().asString(), caseChk->get());
LLTextEditor* pEditor = getEditor();
if (pEditor)
{
pEditor->clearHighlights();
}
}
bool LLFloaterSearchReplace::hasAccelerators() const
{
// Pass this on to the editor we're operating on (or any view up along its hierarchy
// (allows Ctrl-F to work when the floater itself has focus - see changeset 0c8947e5f433)
const LLView* pView = (LLView*)mEditor;
const LLView* pView = dynamic_cast<LLTextEditor*>(m_EditorHandle.get());
while (pView)
{
if (pView->hasAccelerators())
@ -130,21 +109,108 @@ bool LLFloaterSearchReplace::hasAccelerators() const
BOOL LLFloaterSearchReplace::handleKeyHere(KEY key, MASK mask)
{
// return mEditorCore->handleKeyHere(key, mask);
// VWR-23608 Satomi Ahn
if ( KEY_RETURN == key )
{
if (getChild<LLUICtrl>("search_text")->hasFocus()) { onBtnSearch(); return TRUE; }
else if (getChild<LLUICtrl>("replace_text")->hasFocus()) { onBtnReplace(); return TRUE; }
}
// Pass this on to the editor we're operating on (or any view up along its hierarchy
// Pass this on to the editor we're operating on (or any view up along its hierarchy) if we don't handle the key ourselves
// (allows Ctrl-F to work when the floater itself has focus - see changeset 0c8947e5f433)
LLView* pView = (LLView*)mEditor;
BOOL handled = LLFloater::handleKeyHere(key, mask);
if (!handled)
{
// Check if one of our children currently has keyboard focus and if so route edit accellerators to it
if (gFocusMgr.childHasKeyboardFocus(this))
{
LLView* pEditView = dynamic_cast<LLView*>(LLEditMenuHandler::gEditMenuHandler);
if ( (pEditView) && (pEditView->hasAncestor(this)) && (gEditMenu) && (gEditMenu->handleAcceleratorKey(key, mask)) )
{
return TRUE;
}
}
LLView* pView = m_EditorHandle.get();
while (pView)
{
if ( (pView->hasAccelerators()) && (pView->handleKeyHere(key, mask)) )
return TRUE;
pView = pView->getParent();
}
}
return handled;
}
//static
void LLFloaterSearchReplace::show(LLTextEditor* pEditor)
{
LLFloaterSearchReplace* pSelf = LLFloaterReg::getTypedInstance<LLFloaterSearchReplace>("search_replace");
if ( (!pSelf) || (!pEditor) )
return;
LLFloater *pDependeeNew = NULL, *pDependeeOld = pSelf->getDependee();
LLView* pView = pEditor->getParent();
while (pView)
{
if (pView->hasAccelerators())
return pView->handleKeyHere(key, mask);
pDependeeNew = dynamic_cast<LLFloater*>(pView);
if (pDependeeNew)
{
if (pDependeeNew != pDependeeOld)
{
if (pDependeeOld)
{
if (pSelf->getEditor())
pSelf->getEditor()->clearHighlights();
pDependeeOld->removeDependentFloater(pSelf);
}
if (!pDependeeNew->getHost())
pDependeeNew->addDependentFloater(pSelf);
else
pDependeeNew->getHost()->addDependentFloater(pSelf);
}
break;
}
pView = pView->getParent();
}
return FALSE;
pSelf->m_EditorHandle = pEditor->getHandle();
pSelf->openFloater();
}
LLTextEditor* LLFloaterSearchReplace::getEditor() const
{
return dynamic_cast<LLTextEditor*>(m_EditorHandle.get());
}
void LLFloaterSearchReplace::refreshHighlight()
{
LLTextEditor* pEditor = getEditor();
if (pEditor)
{
pEditor->setHighlightWord(m_pSearchEditor->getText(), m_pCaseInsensitiveCheck->get());
}
}
void LLFloaterSearchReplace::onSearchClick()
{
LLTextEditor* pEditor = getEditor();
if (pEditor)
{
pEditor->selectNext(m_pSearchEditor->getText(), m_pCaseInsensitiveCheck->get(), TRUE, m_pSearchUpCheck->get());
}
}
void LLFloaterSearchReplace::onReplaceClick()
{
LLTextEditor* pEditor = getEditor();
if (pEditor)
{
pEditor->replaceText(m_pSearchEditor->getText(), m_pReplaceEditor->getText(), m_pCaseInsensitiveCheck->get(), TRUE, m_pSearchUpCheck->get());
}
}
void LLFloaterSearchReplace::onReplaceAllClick()
{
LLTextEditor* pEditor = getEditor();
if (pEditor)
{
pEditor->replaceTextAll(m_pSearchEditor->getText(), m_pReplaceEditor->getText(), m_pCaseInsensitiveCheck->get());
}
}
// ============================================================================

View File

@ -1,60 +1,76 @@
/**
* @file llfloatersearchreplace.h
* @brief LLFloaterSearchReplace class implementation
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
* Copyright (c) 2010-2013, Kitty Barnett
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
* The source code in this file is provided to you under the terms of the
* GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. Terms of the LGPL can be found in doc/LGPL-licence.txt
* in this distribution, or online at http://www.gnu.org/licenses/lgpl-2.1.txt
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* By copying, modifying or distributing this software, you acknowledge that
* you have read and understood your obligations described above, and agree to
* abide by those obligations.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_FLOATERSEARCHREPLACE_H
#define LL_FLOATERSEARCHREPLACE_H
#include "llfloater.h"
#include "llfloaterreg.h"
// ============================================================================
// Forward declarations
//
class LLCheckBoxCtrl;
class LLLineEditor;
class LLTextEditor;
// ============================================================================
// LLFloaterSearchReplace class
//
class LLFloaterSearchReplace : public LLFloater
{
public:
LLFloaterSearchReplace(const LLSD& sdKey);
~LLFloaterSearchReplace();
/*virtual*/ bool hasAccelerators() const;
/*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
/*virtual*/ BOOL postBuild();
/*
* LLView overrides
*/
public:
LLTextEditor* getEditor() { return mEditor; }
static void show(LLTextEditor* pEditor);
/*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
/*virtual*/ bool hasAccelerators() const;
/*virtual*/ BOOL postBuild();
/*virtual*/ void onOpen(const LLSD& sdKey);
/*virtual*/ void onClose(bool fQuiting);
/*
* Member functions
*/
public:
static void show(LLTextEditor* pEditor);
protected:
void onBtnSearch();
void onBtnReplace();
void onBtnReplaceAll();
LLTextEditor* getEditor() const;
void refreshHighlight();
void onSearchClick();
void onSearchKeystroke();
void onReplaceClick();
void onReplaceAllClick();
/*
* Member variables
*/
private:
LLTextEditor* mEditor;
LLLineEditor* m_pSearchEditor;
LLLineEditor* m_pReplaceEditor;
LLCheckBoxCtrl* m_pCaseInsensitiveCheck;
LLCheckBoxCtrl* m_pSearchUpCheck;
LLHandle<LLUICtrl> m_EditorHandle;
};
#endif // LL_FLOATERSEARCHREPLACE_H
// ============================================================================
#endif // LL_FLOATERSEARCHREPLACE_H

View File

@ -1100,6 +1100,9 @@
<color
name="TextBgWriteableColor"
reference="LtGray" />
<color
name="TextBgHighlightColor"
reference="EmphasisColorLight" />
<color
name="TextCursorColor"
reference="Black" />

View File

@ -1063,6 +1063,9 @@
<color
name="TextBgWriteableColor"
reference="Black" />
<color
name="TextBgHighlightColor"
reference="EmphasisColorLight" />
<color
name="TextCursorColor"
reference="White" />

View File

@ -1100,6 +1100,9 @@
<color
name="TextBgWriteableColor"
reference="LtGray" />
<color
name="TextBgHighlightColor"
reference="EmphasisColorLight" />
<color
name="TextCursorColor"
reference="Black" />

View File

@ -1054,6 +1054,9 @@
<color
name="TextBgWriteableColor"
reference="Black" />
<color
name="TextBgHighlightColor"
reference="EmphasisColorLight" />
<color
name="TextCursorColor"
reference="White" />

View File

@ -1044,6 +1044,9 @@
<color
name="TextBgWriteableColor"
reference="LtGray" />
<color
name="TextBgHighlightColor"
reference="EmphasisColorLight" />
<color
name="TextCursorColor"
reference="Black" />

View File

@ -2,7 +2,7 @@
<floater
legacy_header_height="18"
default_tab_group="1"
height="120"
height="115"
layout="topleft"
name="search replace"
help_topic="search_replace"

View File

@ -21,6 +21,7 @@
bg_visible="true"
bg_readonly_color="TextBgReadOnlyColor"
bg_writeable_color="TextBgWriteableColor"
bg_highlighted_color="TextBgHighlightColor"
bg_selected_color="EmphasisColor"
bg_focus_color="TextBgFocusColor">
</simple_text_editor>

View File

@ -30,6 +30,9 @@
<color
name="EmphasisColor"
value="0.612 0.537 0.784 1.0" />
<color
name="EmphasisColorLight"
value="0.712 0.637 0.884 0.66" />
<color
name="SchemeLightest"
value="0.612 0.537 0.784 1.0" />
@ -818,6 +821,9 @@
<color
name="TextBgWriteableColor"
reference="LtGray" />
<color
name="TextBgHighlightColor"
reference="EmphasisColorLight" />
<color
name="TextCursorColor"
reference="Black" />

View File

@ -21,6 +21,7 @@
bg_visible="true"
bg_readonly_color="TextBgReadOnlyColor"
bg_writeable_color="TextBgWriteableColor"
bg_highlighted_color="TextBgHighlightColor"
bg_selected_color="simpleeditor_bg_selected"
bg_focus_color="TextBgFocusColor">
</simple_text_editor>

View File

@ -210,6 +210,9 @@
<color
name="TextBgWriteableColor"
value="0.729 0.765 0.745 1.0" />
<color
name="TextBgHighlightColor"
value="0.45 0.46 0.745 0.66" />
<color
name="TextBgReadOnlyColor"
reference="DkGray" />

View File

@ -21,6 +21,7 @@
bg_visible="true"
bg_readonly_color="TextBgReadOnlyColor"
bg_writeable_color="TextBgWriteableColor"
bg_highlighted_color="TextBgHighlightColor"
bg_selected_color="TextBgSelectedColor"
bg_focus_color="TextBgFocusColor">
</simple_text_editor>

View File

@ -21,6 +21,7 @@
bg_visible="true"
bg_readonly_color="TextBgReadOnlyColor"
bg_writeable_color="TextBgWriteableColor"
bg_highlighted_color="EmphasisColor_35"
bg_selected_color="EmphasisColor"
bg_focus_color="TextBgFocusColor">
</simple_text_editor>

View File

@ -21,6 +21,7 @@
bg_visible="true"
bg_readonly_color="TextBgReadOnlyColor"
bg_writeable_color="TextBgWriteableColor"
bg_highlighted_color="SL-EmphasisColor"
bg_selected_color="SL-EmphasisColor"
bg_focus_color="TextBgFocusColor">
</simple_text_editor>

View File

@ -214,6 +214,9 @@
<color
name="TextBgWriteableColor"
value="0.729 0.765 0.745 1.0" />
<color
name="TextBgHighlightColor"
value="0.45 0.46 0.745 0.66" />
<color
name="TextBgReadOnlyColor"
reference="DkGray" />

View File

@ -21,6 +21,7 @@
bg_visible="true"
bg_readonly_color="TextBgReadOnlyColor"
bg_writeable_color="TextBgWriteableColor"
bg_highlighted_color="TextBgHighlightColor"
bg_selected_color="TextBgSelectedColor"
bg_focus_color="TextBgFocusColor">
</simple_text_editor>