Update Search & Replace floater to latest version from Kitty Barnett (Catznip viewer)
parent
487540a25f
commit
f166eed059
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1100,6 +1100,9 @@
|
|||
<color
|
||||
name="TextBgWriteableColor"
|
||||
reference="LtGray" />
|
||||
<color
|
||||
name="TextBgHighlightColor"
|
||||
reference="EmphasisColorLight" />
|
||||
<color
|
||||
name="TextCursorColor"
|
||||
reference="Black" />
|
||||
|
|
|
|||
|
|
@ -1063,6 +1063,9 @@
|
|||
<color
|
||||
name="TextBgWriteableColor"
|
||||
reference="Black" />
|
||||
<color
|
||||
name="TextBgHighlightColor"
|
||||
reference="EmphasisColorLight" />
|
||||
<color
|
||||
name="TextCursorColor"
|
||||
reference="White" />
|
||||
|
|
|
|||
|
|
@ -1100,6 +1100,9 @@
|
|||
<color
|
||||
name="TextBgWriteableColor"
|
||||
reference="LtGray" />
|
||||
<color
|
||||
name="TextBgHighlightColor"
|
||||
reference="EmphasisColorLight" />
|
||||
<color
|
||||
name="TextCursorColor"
|
||||
reference="Black" />
|
||||
|
|
|
|||
|
|
@ -1054,6 +1054,9 @@
|
|||
<color
|
||||
name="TextBgWriteableColor"
|
||||
reference="Black" />
|
||||
<color
|
||||
name="TextBgHighlightColor"
|
||||
reference="EmphasisColorLight" />
|
||||
<color
|
||||
name="TextCursorColor"
|
||||
reference="White" />
|
||||
|
|
|
|||
|
|
@ -1044,6 +1044,9 @@
|
|||
<color
|
||||
name="TextBgWriteableColor"
|
||||
reference="LtGray" />
|
||||
<color
|
||||
name="TextBgHighlightColor"
|
||||
reference="EmphasisColorLight" />
|
||||
<color
|
||||
name="TextCursorColor"
|
||||
reference="Black" />
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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" />
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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" />
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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" />
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Reference in New Issue