diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index bcafe27443fd839df6a74c033d36e81e217eae14..2a9d40269e70b9872f87f5f3b77d892d6d547dd2 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -6,6 +6,7 @@ * $LicenseInfo:firstyear=2009&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2009-2010, Linden Research, Inc. + * Copyright (C) 2010-2016, Kitty Barnett * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -44,6 +45,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] const F32 CURSOR_FLASH_DELAY = 1.0f; // in seconds const S32 CURSOR_THICKNESS = 2; @@ -146,6 +150,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), @@ -197,6 +204,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), @@ -362,15 +372,31 @@ 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(); @@ -379,73 +405,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); + // 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) + { + 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; + 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) - { - LLTextSegmentPtr segmentp = *segment_iter; + for(;segment_iter != mSegments.end(); ++segment_iter, segment_offset = 0) + { + LLTextSegmentPtr segmentp = *segment_iter; - S32 segment_line_start = segmentp->getStart() + segment_offset; - S32 segment_line_end = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd); + 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; + if (segment_line_start > segment_line_end) break; - S32 segment_width = 0; - S32 segment_height = 0; + 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 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; + // 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; - break; +// [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); @@ -1327,6 +1383,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(); @@ -2325,6 +2387,10 @@ void LLTextBase::needsReflow(S32 index) LL_DEBUGS() << "reflow on object " << (void*)this << " index = " << mReflowIndex << ", new index = " << index << LL_ENDL; #endif mReflowIndex = llmin(mReflowIndex, index); + +// [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6) + mHighlightsDirty = true; +// [/SL:KB] } S32 LLTextBase::removeFirstLine() @@ -2891,6 +2957,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; diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index c6a2c812fd31861fee8cd17797ea2d98ba07efeb..a0bee6fdfd461db89aeb98bd66e0697496c34604 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -303,6 +303,9 @@ class LLTextBase 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; @@ -455,7 +458,7 @@ class LLTextBase LLRect getDocRectFromDocIndex(S32 pos) const; void setReadOnly(bool read_only) { mReadOnly = read_only; } - bool getReadOnly() { return mReadOnly; } + bool getReadOnly() const { return mReadOnly; } void setSkipLinkUnderline(bool skip_link_underline) { mSkipLinkUnderline = skip_link_underline; } bool getSkipLinkUnderline() { return mSkipLinkUnderline; } @@ -479,6 +482,13 @@ class LLTextBase 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); @@ -519,6 +529,10 @@ class LLTextBase }; 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. @@ -574,6 +588,9 @@ class LLTextBase // draw methods virtual 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(); @@ -612,6 +629,9 @@ class LLTextBase S32 getFirstVisibleLine() const; std::pair<S32, S32> getVisibleLines(bool fully_visible = false); S32 getLeftOffset(S32 width); +// [SL:KB] - Patch: Control-TextEditor | Checked: Catznip-5.2 +protected: +// [/SL:KB void reflow(); // cursor @@ -666,6 +686,9 @@ class LLTextBase LLUIColor mWriteableBgColor; LLUIColor mReadOnlyBgColor; LLUIColor mFocusBgColor; +// [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6) + LLUIColor mHighlightedBGColor; +// [/SL:KB] LLUIColor mTextSelectedColor; LLUIColor mSelectedBGColor; @@ -689,6 +712,14 @@ class LLTextBase 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 diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 9fb338a287a78d1620926127dcf1e44c8278aff2..21d6b84ec7044fd9a4b00ec7aa3422e00f374489 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -336,11 +336,26 @@ void LLTextEditor::setText(const LLStringExplicit &utf8str, const LLStyle::Param resetDirty(); } -void LLTextEditor::selectNext(const std::string& search_text_in, BOOL case_insensitive, BOOL wrap) +// [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) +bool LLTextEditor::selectNext(const std::string& search_text_in, BOOL case_insensitive, BOOL wrap, BOOL search_up, BOOL keep_selection) +// [/SL:KB] { if (search_text_in.empty()) { - return; +// [SL:KB] - Patch: Chat-Logs | Checked: Catznip-5.2 + return false; +// [/SL:KB] +// return; } LLWString text = getWText(); @@ -357,37 +372,76 @@ void LLTextEditor::selectNext(const std::string& search_text_in, BOOL case_insen if (selected_text == search_text) { - // We already have this word selected, we are searching for the next. - setCursorPos(mCursorPos + search_text.size()); +// [SL:KB] - Patch: UI-FloaterSearchReplace | Checked: 2010-10-29 (Catznip-2.3) + if (search_up) + { + // We already have this word selected, we are searching for the previous. + setCursorPos(llmax(0, llmin(mSelectionStart, mSelectionEnd) - 1)); + } + else + { + // We already have this word selected, we are searching for the next. + setCursorPos(llmax(mSelectionStart, mSelectionEnd) + 1); + } +// [/SL:KB] +// // We already have this word selected, we are searching for the next. +// setCursorPos(mCursorPos + search_text.size()); } } - size_t loc = text.find(search_text,mCursorPos); - +// [SL:KB] - Patch: UI-FloaterSearchReplace | Checked: 2010-10-29 (Catznip-2.3) + size_t loc = (search_up) ? text.rfind(search_text, llmax(0, mCursorPos - (S32)search_text.size())) : text.find(search_text,mCursorPos); +// [/SL:KB] +// S32 loc = text.find(search_text,mCursorPos); + // If Maybe we wrapped, search again if (wrap && (std::string::npos == loc)) { - loc = text.find(search_text); +// [SL:KB] - Patch: UI-FloaterSearchReplace | Checked: 2010-10-29 (Catznip-2.3) + loc = (search_up) ? text.rfind(search_text) : text.find(search_text); +// [/SL:KB] +// loc = text.find(search_text); } // If still -1, then search_text just isn't found. - if (-1 == loc) + if (std::string::npos == loc) { - mIsSelecting = FALSE; - mSelectionEnd = 0; - mSelectionStart = 0; - return; +// [SL:KB] - Patch: Chat-Logs | Checked: Catznip-5.2 + if (!keep_selection) + { + mIsSelecting = FALSE; + mSelectionEnd = 0; + mSelectionStart = 0; + } + return false; +// [/SL:KB] +// mIsSelecting = FALSE; +// mSelectionEnd = 0; +// mSelectionStart = 0; +// return; } setCursorPos(loc); +// [SL:KB] - Patch: UI-FloaterSearchReplace | Checked: 2010-11-05 (Catznip-2.3) + if (mReadOnly) + { + updateScrollFromCursor(); + } +// [/SL:KB] mIsSelecting = TRUE; mSelectionEnd = mCursorPos; mSelectionStart = llmin((S32)getLength(), (S32)(mCursorPos + search_text.size())); +// [SL:KB] - Patch: Chat-Logs | Checked: Catznip-5.2 + return true; +// [/SL:KB] } -BOOL LLTextEditor::replaceText(const std::string& search_text_in, const std::string& replace_text, - BOOL case_insensitive, BOOL wrap) +//BOOL LLTextEditor::replaceText(const std::string& search_text_in, const std::string& replace_text, +// BOOL case_insensitive, BOOL wrap) +// [SL:KB] - Patch: UI-FloaterSearchReplace | Checked: 2010-10-29 (Catznip-2.3) +BOOL LLTextEditor::replaceText(const std::string& search_text_in, const std::string& replace_text, BOOL case_insensitive, BOOL wrap, BOOL search_up) +// [/SL:KB] { BOOL replaced = FALSE; @@ -415,7 +469,10 @@ BOOL LLTextEditor::replaceText(const std::string& search_text_in, const std::str } } - selectNext(search_text_in, case_insensitive, wrap); +// selectNext(search_text_in, case_insensitive, wrap); +// [SL:KB] - Patch: UI-FloaterSearchReplace | Checked: 2010-10-29 (Catznip-2.3) + selectNext(search_text_in, case_insensitive, wrap, search_up); +// [/SL:KB] return replaced; } diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index c996658d93fdbf9a2c5d26c488b90544f1fe8229..5a38d55c476fdd4cd531eb657967cb811eebb66e 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -143,8 +143,13 @@ class LLTextEditor : virtual bool canLoadOrSaveToFile(); - void selectNext(const std::string& search_text_in, BOOL case_insensitive, BOOL wrap = TRUE); - BOOL replaceText(const std::string& search_text, const std::string& replace_text, BOOL case_insensitive, BOOL wrap = TRUE); +// [SL:KB] - Patch: UI-FloaterSearchReplace | Checked: 2010-10-29 (Catznip-2.3) + std::string getSelectionString() const; + bool selectNext(const std::string& search_text_in, BOOL case_insensitive, BOOL wrap = TRUE, BOOL search_up = FALSE, BOOL keep_selection = 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] +// void selectNext(const std::string& search_text_in, BOOL case_insensitive, BOOL wrap = TRUE); +// BOOL replaceText(const std::string& search_text, const std::string& replace_text, BOOL case_insensitive, BOOL wrap = TRUE); void replaceTextAll(const std::string& search_text, const std::string& replace_text, BOOL case_insensitive); // Undo/redo stack diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 439580fb4776fa161a6647cb64829c5577ee7dfa..be5950a5941b94c5abe71bbde7b5be416d4e2f50 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -324,6 +324,7 @@ set(viewer_SOURCE_FILES llfloaterscriptedprefs.cpp llfloaterscriptlimits.cpp llfloatersearch.cpp + llfloatersearchreplace.cpp llfloatersellland.cpp llfloatersettingsdebug.cpp llfloatersidepanelcontainer.cpp @@ -986,6 +987,7 @@ set(viewer_HEADER_FILES llfloaterscriptedprefs.h llfloaterscriptlimits.h llfloatersearch.h + llfloatersearchreplace.h llfloatersellland.h llfloatersettingsdebug.h llfloatersidepanelcontainer.h diff --git a/indra/newview/llfloatersearchreplace.cpp b/indra/newview/llfloatersearchreplace.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b0d014a1f6c2c139c73ee99ca9188673e15d2bb8 --- /dev/null +++ b/indra/newview/llfloatersearchreplace.cpp @@ -0,0 +1,216 @@ +/** + * + * Copyright (c) 2010-2013, Kitty Barnett + * + * 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 + * + * 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. + * + */ + +#include "llviewerprecompiledheaders.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) + , m_pSearchEditor(NULL) + , m_pReplaceEditor(NULL) + , m_pCaseInsensitiveCheck(NULL) + , m_pSearchUpCheck(NULL) +{ +} + +LLFloaterSearchReplace::~LLFloaterSearchReplace() +{ +} + +BOOL LLFloaterSearchReplace::postBuild() +{ + 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"); + + 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::onOpen(const LLSD& sdKey) +{ + 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::onClose(bool fQuiting) +{ + LLTextEditor* pEditor = getEditor(); + if (pEditor) + { + pEditor->clearHighlights(); + } +} + +bool LLFloaterSearchReplace::hasAccelerators() const +{ + const LLView* pView = dynamic_cast<LLTextEditor*>(m_EditorHandle.get()); + while (pView) + { + if (pView->hasAccelerators()) + return true; + pView = pView->getParent(); + } + return false; +} + +BOOL LLFloaterSearchReplace::handleKeyHere(KEY key, MASK mask) +{ + // 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) + 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) + { + 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(); + } + + 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()); + } +} + +// ============================================================================ diff --git a/indra/newview/llfloatersearchreplace.h b/indra/newview/llfloatersearchreplace.h new file mode 100644 index 0000000000000000000000000000000000000000..4a53047b26522aa4d238413352829cebdb5337d1 --- /dev/null +++ b/indra/newview/llfloatersearchreplace.h @@ -0,0 +1,76 @@ +/** + * + * Copyright (c) 2010-2013, Kitty Barnett + * + * 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 + * + * 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. + * + */ + +#ifndef LL_FLOATERSEARCHREPLACE_H +#define LL_FLOATERSEARCHREPLACE_H + +#include "llfloater.h" + +// ============================================================================ +// Forward declarations +// + +class LLCheckBoxCtrl; +class LLLineEditor; +class LLTextEditor; + +// ============================================================================ +// LLFloaterSearchReplace class +// + +class LLFloaterSearchReplace : public LLFloater +{ +public: + LLFloaterSearchReplace(const LLSD& sdKey); + ~LLFloaterSearchReplace(); + + /* + * LLView overrides + */ +public: + /*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: + LLTextEditor* getEditor() const; + void refreshHighlight(); + void onSearchClick(); + void onSearchKeystroke(); + void onReplaceClick(); + void onReplaceAllClick(); + + /* + * Member variables + */ +private: + LLLineEditor* m_pSearchEditor; + LLLineEditor* m_pReplaceEditor; + LLCheckBoxCtrl* m_pCaseInsensitiveCheck; + LLCheckBoxCtrl* m_pSearchUpCheck; + LLHandle<LLUICtrl> m_EditorHandle; +}; + +// ============================================================================ + +#endif // LL_FLOATERSEARCHREPLACE_H diff --git a/indra/newview/llpreview.cpp b/indra/newview/llpreview.cpp index fc2de4844e617ee082bf35f9bc145d8edb119327..4b7f90deda7c77108ac404ff70149416916588da 100644 --- a/indra/newview/llpreview.cpp +++ b/indra/newview/llpreview.cpp @@ -34,6 +34,12 @@ #include "llresmgr.h" #include "lltextbox.h" #include "llfloaterreg.h" +// [SL:KB] - Patch: UI-FloaterSearchReplace | Checked: 2010-11-05 (Catznip-3.0) +#include "llfloatersearchreplace.h" +#include "llpreviewnotecard.h" +#include "llpreviewscript.h" +#include "llscripteditor.h" +// [/SL:KB] #include "llfocusmgr.h" #include "lltooldraganddrop.h" #include "llradiogroup.h" @@ -525,6 +531,30 @@ void LLMultiPreview::tabOpen(LLFloater* opened_floater, bool from_click) { opened_preview->loadAsset(); } + +// [SL:KB] - Patch: UI-FloaterSearchReplace | Checked: 2010-11-05 (Catznip-2.3) + LLFloaterSearchReplace* pSearchFloater = LLFloaterReg::getTypedInstance<LLFloaterSearchReplace>("search_replace"); + if ( (pSearchFloater) && (pSearchFloater->getDependee() == this) ) + { + LLPreviewNotecard* pPreviewNotecard = NULL; LLPreviewLSL* pPreviewScript = NULL; LLLiveLSLEditor* pPreviewScriptLive = NULL; + if ((pPreviewNotecard = dynamic_cast<LLPreviewNotecard*>(opened_preview)) != NULL) + { + LLFloaterSearchReplace::show(pPreviewNotecard->getEditor()); + } + else if ((pPreviewScript = dynamic_cast<LLPreviewLSL*>(opened_preview)) != NULL) + { + LLFloaterSearchReplace::show(pPreviewScript->getEditor()); + } + else if ((pPreviewScriptLive = dynamic_cast<LLLiveLSLEditor*>(opened_preview)) != NULL) + { + LLFloaterSearchReplace::show(pPreviewScriptLive->getEditor()); + } + else + { + pSearchFloater->setVisible(FALSE); + } + } +// [/SL:KB] } diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp index f037ba8840ef46775772817d5dc47b852b3c7cba..e1a8da55a6a4543a0269ab359b33db533b8936a1 100644 --- a/indra/newview/llpreviewnotecard.cpp +++ b/indra/newview/llpreviewnotecard.cpp @@ -36,6 +36,9 @@ #include "llviewerwindow.h" #include "llbutton.h" #include "llfloaterreg.h" +// [SL:KB] - Patch: UI-FloaterSearchReplace | Checked: 2010-11-05 (Catznip-2.3) +#include "llfloatersearchreplace.h" +// [/SL:KB] #include "llinventorydefines.h" #include "llinventorymodel.h" #include "lllineeditor.h" @@ -145,6 +148,14 @@ BOOL LLPreviewNotecard::handleKeyHere(KEY key, MASK mask) return TRUE; } +// [SL:KB] - Patch: UI-FloaterSearchReplace | Checked: 2010-11-05 (Catznip-2.3) + if(('F' == key) && (MASK_CONTROL == (mask & MASK_CONTROL))) + { + LLFloaterSearchReplace::show(getEditor()); + return TRUE; + } +// [/SL:KB] + return LLPreview::handleKeyHere(key, mask); } @@ -190,6 +201,13 @@ const LLInventoryItem* LLPreviewNotecard::getDragItem() return NULL; } +// [SL:KB] - Patch: UI-FloaterSearchReplace | Checked: 2010-11-05 (Catznip-2.3) +LLTextEditor* LLPreviewNotecard::getEditor() +{ + return getChild<LLViewerTextEditor>("Notecard Editor"); +} +// [/SL:KB] + bool LLPreviewNotecard::hasEmbeddedInventory() { LLViewerTextEditor* editor = NULL; diff --git a/indra/newview/llpreviewnotecard.h b/indra/newview/llpreviewnotecard.h index 12c4980a85fa44c959a31112083d6a2dcc9ee89c..fa2bd9665434fe82ede69e2feee61096bb49c47c 100644 --- a/indra/newview/llpreviewnotecard.h +++ b/indra/newview/llpreviewnotecard.h @@ -40,6 +40,9 @@ class LLViewerTextEditor; class LLButton; +// [SL:KB] - Patch: UI-FloaterSearchReplace | Checked: 2010-11-05 (Catznip-2.3) +class LLTextEditor; +// [/SL:KB] class LLPreviewNotecard final : public LLPreview { @@ -52,6 +55,9 @@ class LLPreviewNotecard final : public LLPreview // llview void draw() override; +// [SL:KB] - Patch: UI-FloaterSearchReplace | Checked: 2010-11-05 (Catznip-2.3) + virtual bool hasAccelerators() const { return true; } +// [/SL:KB] BOOL handleKeyHere(KEY key, MASK mask) override; void setEnabled( BOOL enabled ) override; @@ -64,7 +70,9 @@ class LLPreviewNotecard final : public LLPreview // reach into the text editor, and grab the drag item const LLInventoryItem* getDragItem(); - +// [SL:KB] - Patch: UI-FloaterSearchReplace | Checked: 2010-11-05 (Catznip-2.3) + LLTextEditor* getEditor(); +// [/SL:KB] // return true if there is any embedded inventory. bool hasEmbeddedInventory(); diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 3407ca9dd013a2ff2475e8232a2211b5cbef4631..31d55de51b26ee3ac899e605cde6f28cebd152b8 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -36,6 +36,9 @@ #include "llexternaleditor.h" #include "llfilepicker.h" #include "llfloaterreg.h" +// [SL:KB] - Patch: UI-FloaterSearchReplace | Checked: 2010-10-26 (Catznip-2.3) +#include "llfloatersearchreplace.h" +// [/SL:KB] #include "llinventorydefines.h" #include "llinventorymodel.h" #include "llkeyboard.h" @@ -150,180 +153,180 @@ bool LLLiveLSLFile::loadFile() /// --------------------------------------------------------------------------- /// LLFloaterScriptSearch /// --------------------------------------------------------------------------- -class LLFloaterScriptSearch final : public LLFloater -{ -public: - LLFloaterScriptSearch(LLScriptEdCore* editor_core); - ~LLFloaterScriptSearch(); - - /*virtual*/ BOOL postBuild(); - static void show(LLScriptEdCore* editor_core); - static void onBtnSearch(void* userdata); - void handleBtnSearch(); - - static void onBtnReplace(void* userdata); - void handleBtnReplace(); - - static void onBtnReplaceAll(void* userdata); - void handleBtnReplaceAll(); - - LLScriptEdCore* getEditorCore() { return mEditorCore; } - static LLFloaterScriptSearch* getInstance() { return sInstance; } - - virtual bool hasAccelerators() const; - virtual BOOL handleKeyHere(KEY key, MASK mask); - -private: - - LLScriptEdCore* mEditorCore; - static LLFloaterScriptSearch* sInstance; - -protected: - LLLineEditor* mSearchBox; - LLLineEditor* mReplaceBox; - void onSearchBoxCommit(); -}; - -LLFloaterScriptSearch* LLFloaterScriptSearch::sInstance = NULL; - -LLFloaterScriptSearch::LLFloaterScriptSearch(LLScriptEdCore* editor_core) -: LLFloater(LLSD()), - mSearchBox(NULL), - mReplaceBox(NULL), - mEditorCore(editor_core) -{ - buildFromFile("floater_script_search.xml"); - - sInstance = this; - - // find floater in which script panel is embedded - LLView* viewp = (LLView*)editor_core; - while(viewp) - { - LLFloater* floaterp = dynamic_cast<LLFloater*>(viewp); - if (floaterp) - { - floaterp->addDependentFloater(this); - break; - } - viewp = viewp->getParent(); - } -} - -BOOL LLFloaterScriptSearch::postBuild() -{ - mReplaceBox = getChild<LLLineEditor>("replace_text"); - mSearchBox = getChild<LLLineEditor>("search_text"); - mSearchBox->setCommitCallback(boost::bind(&LLFloaterScriptSearch::onSearchBoxCommit, this)); - mSearchBox->setCommitOnFocusLost(FALSE); - childSetAction("search_btn", onBtnSearch,this); - childSetAction("replace_btn", onBtnReplace,this); - childSetAction("replace_all_btn", onBtnReplaceAll,this); - - setDefaultBtn("search_btn"); - - return TRUE; -} +//class LLFloaterScriptSearch : public LLFloater +//{ +//public: +// LLFloaterScriptSearch(LLScriptEdCore* editor_core); +// ~LLFloaterScriptSearch(); +// +// /*virtual*/ BOOL postBuild(); +// static void show(LLScriptEdCore* editor_core); +// static void onBtnSearch(void* userdata); +// void handleBtnSearch(); +// +// static void onBtnReplace(void* userdata); +// void handleBtnReplace(); +// +// static void onBtnReplaceAll(void* userdata); +// void handleBtnReplaceAll(); +// +// LLScriptEdCore* getEditorCore() { return mEditorCore; } +// static LLFloaterScriptSearch* getInstance() { return sInstance; } +// +// virtual bool hasAccelerators() const; +// virtual BOOL handleKeyHere(KEY key, MASK mask); +// +//private: +// +// LLScriptEdCore* mEditorCore; +// static LLFloaterScriptSearch* sInstance; +// +//protected: +// LLLineEditor* mSearchBox; +// LLLineEditor* mReplaceBox; +// void onSearchBoxCommit(); +//}; + +//LLFloaterScriptSearch* LLFloaterScriptSearch::sInstance = NULL; + +//LLFloaterScriptSearch::LLFloaterScriptSearch(LLScriptEdCore* editor_core) +//: LLFloater(LLSD()), +// mSearchBox(NULL), +// mReplaceBox(NULL), +// mEditorCore(editor_core) +//{ +// buildFromFile("floater_script_search.xml"); +// +// sInstance = this; +// +// // find floater in which script panel is embedded +// LLView* viewp = (LLView*)editor_core; +// while(viewp) +// { +// LLFloater* floaterp = dynamic_cast<LLFloater*>(viewp); +// if (floaterp) +// { +// floaterp->addDependentFloater(this); +// break; +// } +// viewp = viewp->getParent(); +// } +//} + +//BOOL LLFloaterScriptSearch::postBuild() +//{ +// mReplaceBox = getChild<LLLineEditor>("replace_text"); +// mSearchBox = getChild<LLLineEditor>("search_text"); +// mSearchBox->setCommitCallback(boost::bind(&LLFloaterScriptSearch::onSearchBoxCommit, this)); +// mSearchBox->setCommitOnFocusLost(FALSE); +// childSetAction("search_btn", onBtnSearch,this); +// childSetAction("replace_btn", onBtnReplace,this); +// childSetAction("replace_all_btn", onBtnReplaceAll,this); +// +// setDefaultBtn("search_btn"); +// +// return TRUE; +//} //static -void LLFloaterScriptSearch::show(LLScriptEdCore* editor_core) -{ - LLSD::String search_text; - LLSD::String replace_text; - if (sInstance && sInstance->mEditorCore && sInstance->mEditorCore != editor_core) - { - search_text=sInstance->mSearchBox->getValue().asString(); - replace_text=sInstance->mReplaceBox->getValue().asString(); - sInstance->closeFloater(); - delete sInstance; - } - - if (!sInstance) - { - // sInstance will be assigned in the constructor. - new LLFloaterScriptSearch(editor_core); - sInstance->mSearchBox->setValue(search_text); - sInstance->mReplaceBox->setValue(replace_text); - } - - sInstance->openFloater(); -} - -LLFloaterScriptSearch::~LLFloaterScriptSearch() -{ - sInstance = NULL; -} +//void LLFloaterScriptSearch::show(LLScriptEdCore* editor_core) +//{ +// LLSD::String search_text; +// LLSD::String replace_text; +// if (sInstance && sInstance->mEditorCore && sInstance->mEditorCore != editor_core) +// { +// search_text=sInstance->mSearchBox->getValue().asString(); +// replace_text=sInstance->mReplaceBox->getValue().asString(); +// sInstance->closeFloater(); +// delete sInstance; +// } +// +// if (!sInstance) +// { +// // sInstance will be assigned in the constructor. +// new LLFloaterScriptSearch(editor_core); +// sInstance->mSearchBox->setValue(search_text); +// sInstance->mReplaceBox->setValue(replace_text); +// } +// +// sInstance->openFloater(); +//} + +//LLFloaterScriptSearch::~LLFloaterScriptSearch() +//{ +// sInstance = NULL; +//} // static -void LLFloaterScriptSearch::onBtnSearch(void *userdata) -{ - LLFloaterScriptSearch* self = (LLFloaterScriptSearch*)userdata; - self->handleBtnSearch(); -} - -void LLFloaterScriptSearch::handleBtnSearch() -{ - LLCheckBoxCtrl* caseChk = getChild<LLCheckBoxCtrl>("case_text"); - mEditorCore->mEditor->selectNext(mSearchBox->getValue().asString(), caseChk->get()); -} +//void LLFloaterScriptSearch::onBtnSearch(void *userdata) +//{ +// LLFloaterScriptSearch* self = (LLFloaterScriptSearch*)userdata; +// self->handleBtnSearch(); +//} + +//void LLFloaterScriptSearch::handleBtnSearch() +//{ +// LLCheckBoxCtrl* caseChk = getChild<LLCheckBoxCtrl>("case_text"); +// mEditorCore->mEditor->selectNext(mSearchBox->getValue().asString(), caseChk->get()); +//} // static -void LLFloaterScriptSearch::onBtnReplace(void *userdata) -{ - LLFloaterScriptSearch* self = (LLFloaterScriptSearch*)userdata; - self->handleBtnReplace(); -} - -void LLFloaterScriptSearch::handleBtnReplace() -{ - LLCheckBoxCtrl* caseChk = getChild<LLCheckBoxCtrl>("case_text"); - mEditorCore->mEditor->replaceText(mSearchBox->getValue().asString(), mReplaceBox->getValue().asString(), caseChk->get()); -} +//void LLFloaterScriptSearch::onBtnReplace(void *userdata) +//{ +// LLFloaterScriptSearch* self = (LLFloaterScriptSearch*)userdata; +// self->handleBtnReplace(); +//} + +//void LLFloaterScriptSearch::handleBtnReplace() +//{ +// LLCheckBoxCtrl* caseChk = getChild<LLCheckBoxCtrl>("case_text"); +// mEditorCore->mEditor->replaceText(mSearchBox->getValue().asString(), mReplaceBox->getValue().asString(), caseChk->get()); +//} // static -void LLFloaterScriptSearch::onBtnReplaceAll(void *userdata) -{ - LLFloaterScriptSearch* self = (LLFloaterScriptSearch*)userdata; - self->handleBtnReplaceAll(); -} - -void LLFloaterScriptSearch::handleBtnReplaceAll() -{ - LLCheckBoxCtrl* caseChk = getChild<LLCheckBoxCtrl>("case_text"); - mEditorCore->mEditor->replaceTextAll(mSearchBox->getValue().asString(), mReplaceBox->getValue().asString(), caseChk->get()); -} - -bool LLFloaterScriptSearch::hasAccelerators() const -{ - if (mEditorCore) - { - return mEditorCore->hasAccelerators(); - } - return FALSE; -} - -BOOL LLFloaterScriptSearch::handleKeyHere(KEY key, MASK mask) -{ - if (mEditorCore) - { - BOOL handled = mEditorCore->handleKeyHere(key, mask); - if (!handled) - { - LLFloater::handleKeyHere(key, mask); - } - } - - return FALSE; -} - -void LLFloaterScriptSearch::onSearchBoxCommit() -{ - if (mEditorCore && mEditorCore->mEditor) - { - LLCheckBoxCtrl* caseChk = getChild<LLCheckBoxCtrl>("case_text"); - mEditorCore->mEditor->selectNext(mSearchBox->getValue().asString(), caseChk->get()); - } -} +//void LLFloaterScriptSearch::onBtnReplaceAll(void *userdata) +//{ +// LLFloaterScriptSearch* self = (LLFloaterScriptSearch*)userdata; +// self->handleBtnReplaceAll(); +//} + +//void LLFloaterScriptSearch::handleBtnReplaceAll() +//{ +// LLCheckBoxCtrl* caseChk = getChild<LLCheckBoxCtrl>("case_text"); +// mEditorCore->mEditor->replaceTextAll(mSearchBox->getValue().asString(), mReplaceBox->getValue().asString(), caseChk->get()); +//} + +//bool LLFloaterScriptSearch::hasAccelerators() const +//{ +// if (mEditorCore) +// { +// return mEditorCore->hasAccelerators(); +// } +// return FALSE; +//} + +//BOOL LLFloaterScriptSearch::handleKeyHere(KEY key, MASK mask) +//{ +// if (mEditorCore) +// { +// BOOL handled = mEditorCore->handleKeyHere(key, mask); +// if (!handled) +// { +// LLFloater::handleKeyHere(key, mask); +// } +// } +// +// return FALSE; +//} + +//void LLFloaterScriptSearch::onSearchBoxCommit() +//{ +// if (mEditorCore && mEditorCore->mEditor) +// { +// LLCheckBoxCtrl* caseChk = getChild<LLCheckBoxCtrl>("case_text"); +// mEditorCore->mEditor->selectNext(mSearchBox->getValue().asString(), caseChk->get()); +// } +//} /// --------------------------------------------------------------------------- /// LLScriptEdCore @@ -343,17 +346,20 @@ LLScriptEdCore::LLScriptEdCore( const LLHandle<LLFloater>& floater_handle, void (*load_callback)(void*), void (*save_callback)(void*, BOOL), - void (*search_replace_callback) (void* userdata), +// void (*search_replace_callback) (void* userdata), void* userdata, bool live, S32 bottom_pad) : LLPanel(), mSampleText(sample), +// [SL:KB] - Patch: Build-ScriptEditor | Checked: 2014-01-29 (Catznip-3.6) + mMenuBar(NULL), +// [/SL:KB] mEditor( NULL ), mLoadCallback( load_callback ), mSaveCallback( save_callback ), - mSearchReplaceCallback( search_replace_callback ), +// mSearchReplaceCallback( search_replace_callback ), mUserdata( userdata ), mForceClose( FALSE ), mLastHelpToken(NULL), @@ -378,12 +384,12 @@ LLScriptEdCore::~LLScriptEdCore() deleteBridges(); // If the search window is up for this editor, close it. - LLFloaterScriptSearch* script_search = LLFloaterScriptSearch::getInstance(); - if (script_search && script_search->getEditorCore() == this) - { - script_search->closeFloater(); - delete script_search; - } +// LLFloaterScriptSearch* script_search = LLFloaterScriptSearch::getInstance(); +// if (script_search && script_search->getEditorCore() == this) +// { +// script_search->closeFloater(); +// delete script_search; +// } delete mLiveFile; if (mSyntaxIDConnection.connected()) @@ -443,6 +449,10 @@ void LLLiveLSLEditor::onToggleExperience( LLUICtrl *ui, void* userdata ) BOOL LLScriptEdCore::postBuild() { +// [SL:KB] - Patch: Build-ScriptEditor | Checked: 2014-01-29 (Catznip-3.6) + mMenuBar = getChild<LLMenuBarGL>("script_menu"); +// [/SL:KB] + mErrorList = getChild<LLScrollListCtrl>("lsl errors"); mFunctions = getChild<LLComboBox>("Insert..."); @@ -534,6 +544,12 @@ void LLScriptEdCore::initMenu() menuItem->setClickCallback(boost::bind(&LLTextEditor::paste, mEditor)); menuItem->setEnableCallback(boost::bind(&LLTextEditor::canPaste, mEditor)); +// [SL:KB] - Patch: Build-ScriptEditor | Checked: 2014-01-29 (Catznip-3.6) + menuItem = getChild<LLMenuItemCallGL>("Delete"); + menuItem->setClickCallback(boost::bind(&LLTextEditor::doDelete, mEditor)); + menuItem->setEnableCallback(boost::bind(&LLTextEditor::canDoDelete, mEditor)); +// [/SL:KB] + menuItem = getChild<LLMenuItemCallGL>("Select All"); menuItem->setClickCallback(boost::bind(&LLTextEditor::selectAll, mEditor)); menuItem->setEnableCallback(boost::bind(&LLTextEditor::canSelectAll, mEditor)); @@ -543,7 +559,10 @@ void LLScriptEdCore::initMenu() menuItem->setEnableCallback(boost::bind(&LLTextEditor::canDeselect, mEditor)); menuItem = getChild<LLMenuItemCallGL>("Search / Replace..."); - menuItem->setClickCallback(boost::bind(&LLFloaterScriptSearch::show, this)); +// [SL:KB] - Patch: UI-FloaterSearchReplace | Checked: 2010-10-26 (Catznip-2.3) + menuItem->setClickCallback(boost::bind(&LLFloaterSearchReplace::show, mEditor)); +// [/SL:KB] +// menuItem->setClickCallback(boost::bind(&LLFloaterScriptSearch::show, this)); menuItem = getChild<LLMenuItemCallGL>("Go to line..."); menuItem->setClickCallback(boost::bind(&LLFloaterGotoLine::show, this)); @@ -1171,28 +1190,35 @@ void LLScriptEdCore::deleteBridges() // virtual BOOL LLScriptEdCore::handleKeyHere(KEY key, MASK mask) { - bool just_control = MASK_CONTROL == (mask & MASK_MODIFIERS); - - if(('S' == key) && just_control) +// [SL:KB] - Patch: Build-ScriptEditor | Checked: 2014-01-29 (Catznip-3.6) + if (mMenuBar->handleAcceleratorKey(key, mask)) { - if(mSaveCallback) - { - // don't close after saving - mSaveCallback(mUserdata, FALSE); - } - return TRUE; } +// [/SL:KB] - if(('F' == key) && just_control) - { - if(mSearchReplaceCallback) - { - mSearchReplaceCallback(mUserdata); - } - - return TRUE; - } +// bool just_control = MASK_CONTROL == (mask & MASK_MODIFIERS); +// +// if(('S' == key) && just_control) +// { +// if(mSaveCallback) +// { +// // don't close after saving +// mSaveCallback(mUserdata, FALSE); +// } +// +// return TRUE; +// } +// +// if(('F' == key) && just_control) +// { +// if(mSearchReplaceCallback) +// { +// mSearchReplaceCallback(mUserdata); +// } +// +// return TRUE; +// } return FALSE; } @@ -1493,7 +1519,7 @@ void* LLPreviewLSL::createScriptEdPanel(void* userdata) self->getHandle(), LLPreviewLSL::onLoad, LLPreviewLSL::onSave, - LLPreviewLSL::onSearchReplace, +// LLPreviewLSL::onSearchReplace, self, false, 0); @@ -1635,12 +1661,15 @@ void LLPreviewLSL::closeIfNeeded() } } -void LLPreviewLSL::onSearchReplace(void* userdata) -{ - LLPreviewLSL* self = (LLPreviewLSL*)userdata; - LLScriptEdCore* sec = self->mScriptEd; - LLFloaterScriptSearch::show(sec); -} +//void LLPreviewLSL::onSearchReplace(void* userdata) +//{ +// LLPreviewLSL* self = (LLPreviewLSL*)userdata; +// LLScriptEdCore* sec = self->mScriptEd; +//// [SL:KB] - Patch: UI-FloaterSearchReplace | Checked: 2010-10-26 (Catznip-2.3) +// LLFloaterSearchReplace::show(sec->mEditor); +//// [/SL:KB] +//// LLFloaterScriptSearch::show(sec); +//} // static void LLPreviewLSL::onLoad(void* userdata) @@ -1798,7 +1827,7 @@ void* LLLiveLSLEditor::createScriptEdPanel(void* userdata) self->getHandle(), &LLLiveLSLEditor::onLoad, &LLLiveLSLEditor::onSave, - &LLLiveLSLEditor::onSearchReplace, +// &LLLiveLSLEditor::onSearchReplace, self, true, 0); @@ -2166,13 +2195,16 @@ void LLLiveLSLEditor::draw() } -void LLLiveLSLEditor::onSearchReplace(void* userdata) -{ - LLLiveLSLEditor* self = (LLLiveLSLEditor*)userdata; - - LLScriptEdCore* sec = self->mScriptEd; - LLFloaterScriptSearch::show(sec); -} +//void LLLiveLSLEditor::onSearchReplace(void* userdata) +//{ +// LLLiveLSLEditor* self = (LLLiveLSLEditor*)userdata; +// +// LLScriptEdCore* sec = self->mScriptEd; +//// [SL:KB] - Patch: UI-FloaterSearchReplace | Checked: 2010-10-26 (Catznip-2.3) +// LLFloaterSearchReplace::show(sec->mEditor); +//// [/SL:KB] +//// LLFloaterScriptSearch::show(sec); +//} struct LLLiveLSLSaveData { diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h index 1c85587d1051eb37892aad5152d14e3ca9a6ec03..437e7a04cce79c2b65d2c615be12613de3586fb6 100644 --- a/indra/newview/llpreviewscript.h +++ b/indra/newview/llpreviewscript.h @@ -46,7 +46,7 @@ class LLScrollListCtrl; class LLViewerObject; struct LLEntryAndEdCore; class LLMenuBarGL; -class LLFloaterScriptSearch; +//class LLFloaterScriptSearch; class LLKeywordToken; class LLVFS; class LLViewerInventoryItem; @@ -77,7 +77,7 @@ class LLScriptEdCore final : public LLPanel friend class LLPreviewScript; friend class LLPreviewLSL; friend class LLLiveLSLEditor; - friend class LLFloaterScriptSearch; +// friend class LLFloaterScriptSearch; friend class LLScriptEdContainer; friend class LLFloaterGotoLine; @@ -89,7 +89,7 @@ class LLScriptEdCore final : public LLPanel const LLHandle<LLFloater>& floater_handle, void (*load_callback)(void* userdata), void (*save_callback)(void* userdata, BOOL close_after_save), - void (*search_replace_callback)(void* userdata), +// void (*search_replace_callback)(void* userdata), void* userdata, bool live, S32 bottom_pad = 0); // pad below bottom row of buttons @@ -169,10 +169,13 @@ class LLScriptEdCore final : public LLPanel private: std::string mSampleText; std::string mScriptName; +// [SL:KB] - Patch: Build-ScriptEditor | Checked: 2014-01-29 (Catznip-3.6) + LLMenuBarGL* mMenuBar; +// [/SL:KB] LLScriptEditor* mEditor; void (*mLoadCallback)(void* userdata); void (*mSaveCallback)(void* userdata, BOOL close_after_save); - void (*mSearchReplaceCallback) (void* userdata); +// void (*mSearchReplaceCallback) (void* userdata); void* mUserdata; LLComboBox *mFunctions; BOOL mForceClose; @@ -223,6 +226,10 @@ class LLPreviewLSL final : public LLScriptEdContainer /*virtual*/ BOOL postBuild(); +// [SL:KB] - Patch: UI-FloaterSearchReplace | Checked: 2010-11-05 (Catznip-2.3) + LLScriptEditor* getEditor() { return (mScriptEd) ? mScriptEd->mEditor : NULL; } +// [/SL:KB] + protected: virtual void draw(); virtual BOOL canClose(); @@ -231,7 +238,7 @@ class LLPreviewLSL final : public LLScriptEdContainer virtual void loadAsset(); /*virtual*/ void saveIfNeeded(bool sync = true); - static void onSearchReplace(void* userdata); +// static void onSearchReplace(void* userdata); static void onLoad(void* userdata); static void onSave(void* userdata, BOOL close_after_save); @@ -281,6 +288,10 @@ class LLLiveLSLEditor final : public LLScriptEdContainer void experienceChanged(); void addAssociatedExperience(const LLSD& experience); +// [SL:KB] - Patch: UI-FloaterSearchReplace | Checked: 2010-11-05 (Catznip-2.3) + LLScriptEditor* getEditor() { return (mScriptEd) ? mScriptEd->mEditor : NULL; } +// [/SL:KB] + private: virtual BOOL canClose(); void closeIfNeeded(); @@ -292,7 +303,7 @@ class LLLiveLSLEditor final : public LLScriptEdContainer BOOL monoChecked() const; - static void onSearchReplace(void* userdata); +// static void onSearchReplace(void* userdata); static void onLoad(void* userdata); static void onSave(void* userdata, BOOL close_after_save); diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index f1b1c50a6c17722ff0fcdf12af97876690b411e1..220125a464e0499f394aefbef774fe3b4bcf0f15 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -124,6 +124,9 @@ #include "llfloaterscriptedprefs.h" #include "llfloaterscriptlimits.h" #include "llfloatersearch.h" +// [SL:KB] - Patch: UI-FloaterSearchReplace | Checked: 2010-10-26 (Catznip-2.3) +#include "llfloatersearchreplace.h" +// [/SL:KB] #include "llfloatersellland.h" #include "llfloatersettingsdebug.h" #include "llfloatersidepanelcontainer.h" @@ -369,6 +372,9 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("snapshot", "floater_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSnapshot>); LLFloaterReg::add("outfit_snapshot", "floater_outfit_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOutfitSnapshot>); LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>); +// [SL:KB] - Patch: UI-FloaterSearchReplace | Checked: 2010-10-26 (Catznip-2.3) + LLFloaterReg::add("search_replace", "floater_search_replace.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearchReplace>); +// [/SL:KB] LLFloaterReg::add("profile", "floater_profile.xml",(LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterProfile>); LLFloaterReg::add("how_to", "floater_how_to.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create); diff --git a/indra/newview/skins/alchemy/colors.xml b/indra/newview/skins/alchemy/colors.xml index 7582a1297ed19d4f64ed06f5bb0e477a0314dcec..f2a79bec21e91e0553e64585ae3c0f7b674b28ac 100644 --- a/indra/newview/skins/alchemy/colors.xml +++ b/indra/newview/skins/alchemy/colors.xml @@ -889,6 +889,9 @@ <color name="TextBgFocusColor" reference="MouseGray" /> <!-- example: LSL Editor --> + <color + name="TextBgHighlightColor" + reference="AlWarningOrange" /> <color name="TextBgReadOnlyColor" reference="AlchemyBlack1" /> diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index fa93bd03223100f01306960a3ac10a385f3b26cb..4fc59000c5ad220516889a31096236f9de883071 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -791,6 +791,9 @@ <color name="TextBgFocusColor" reference="White" /> + <color + name="TextBgHighlightColor" + value="0.95 0.90 0 1" /> <color name="TextBgReadOnlyColor" reference="White_05" /> diff --git a/indra/newview/skins/default/xui/en/floater_search_replace.xml b/indra/newview/skins/default/xui/en/floater_search_replace.xml new file mode 100644 index 0000000000000000000000000000000000000000..51ed65f6449ec764a897186fb7c35024fe316dc7 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_search_replace.xml @@ -0,0 +1,111 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + legacy_header_height="18" + default_tab_group="1" + height="110" + layout="topleft" + name="search replace" + help_topic="search_replace" + title="SEARCH / REPLACE" + width="300"> + <check_box + control_name="LSLFindCaseInsensitivity" + height="16" + label="Case Insensitive" + layout="topleft" + left="55" + name="case_text" + top="61" + width="120" /> + <check_box + control_name="LSLFindDirection" + height="16" + label="Search Up" + layout="topleft" + left_pad="0" + name="find_previous" + top="61" + width="120" /> + <panel + background_visible="false" + follows="left|right|bottom" + height="25" + label="bottom_panel" + layout="topleft" + left="6" + name="bottom_panel" + top_pad="2" > + <button + image_hover_unselected="Toolbar_Left_Over" + image_selected="Toolbar_Left_Selected" + image_unselected="Toolbar_Left_Off" + label="Search" + left="0" + name="search_btn" + top="1" + width="95" /> + <button + image_hover_unselected="Toolbar_Middle_Over" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + label="Replace" + left_pad="1" + name="replace_btn" + top="1" + width="95" /> + <button + image_hover_unselected="Toolbar_Right_Over" + image_selected="Toolbar_Right_Selected" + image_unselected="Toolbar_Right_Off" + label="Replace All" + left_pad="1" + name="replace_all_btn" + top="1" + width="95" /> + </panel> + <text + type="string" + length="1" + follows="left|top" + height="16" + layout="topleft" + left="5" + name="txt" + top="21" + width="45"> + Search + </text> + <text + type="string" + length="1" + follows="left|top" + height="16" + layout="topleft" + left_delta="0" + name="txt2" + top_pad="5" + width="45"> + Replace + </text> + <line_editor + border_style="line" + border_thickness="1" + follows="left|top" + height="16" + layout="topleft" + left="55" + name="search_text" + tab_group="1" + top="21" + width="240" /> + <line_editor + border_style="line" + border_thickness="1" + follows="left|top" + height="16" + layout="topleft" + left_delta="0" + name="replace_text" + top_pad="5" + width="240" /> +</floater> diff --git a/indra/newview/skins/default/xui/en/panel_script_ed.xml b/indra/newview/skins/default/xui/en/panel_script_ed.xml index ed37e9e2ccdf8844e315518f90213eb73ad60768..c7e1ae9bda448d53a64b1bd78be47c69211abd8c 100644 --- a/indra/newview/skins/default/xui/en/panel_script_ed.xml +++ b/indra/newview/skins/default/xui/en/panel_script_ed.xml @@ -49,7 +49,8 @@ <menu_item_call label="Save" layout="topleft" - name="Save" /> + name="Save" + shortcut="control|S" /> <menu_item_separator layout="topleft" /> <menu_item_call @@ -89,57 +90,63 @@ enabled="false" label="Undo" layout="topleft" - name="Undo" /> + name="Undo" + shortcut="control|Z" /> <menu_item_call enabled="false" label="Redo" layout="topleft" - name="Redo" /> + name="Redo" + shortcut="control|Y" /> <menu_item_separator layout="topleft" /> <menu_item_call enabled="false" label="Cut" layout="topleft" - name="Cut" /> + name="Cut" + shortcut="control|X" /> <menu_item_call enabled="false" label="Copy" layout="topleft" - name="Copy" /> + name="Copy" + shortcut="control|C" /> <menu_item_call enabled="false" label="Paste" layout="topleft" - name="Paste" /> - <menu_item_separator - layout="topleft" - name="separator2" /> + name="Paste" + shortcut="control|V" /> <menu_item_call - label="Select All" + enabled="false" + label="Delete" layout="topleft" - name="Select All" /> + name="Delete" + shortcut="Del" /> <menu_item_call - enabled="false" - label="Deselect" + label="Select All" layout="topleft" - name="Deselect" /> + name="Select All" + shortcut="control|A" /> <menu_item_separator layout="topleft" name="separator3" /> <menu_item_call label="Search / Replace..." layout="topleft" - name="Search / Replace..." /> + name="Search / Replace..." + shortcut="control|F" /> <menu_item_call label="Go to line..." layout="topleft" - name="Go to line..." /> + name="Go to line..." + shortcut="control|G" /> </menu> <menu top="0" height="34" - label="Help" + label="LSL Reference" layout="topleft" mouse_opaque="false" name="Help" @@ -147,11 +154,13 @@ <menu_item_call label="Help..." layout="topleft" - name="Help..." /> + name="Help..." + shortcut="F1" /> <menu_item_call label="Keyword Help..." layout="topleft" - name="Keyword Help..." /> + name="Keyword Help..." + shortcut="shift|F1" /> </menu> </menu_bar> <script_editor diff --git a/indra/newview/skins/default/xui/en/widgets/simple_text_editor.xml b/indra/newview/skins/default/xui/en/widgets/simple_text_editor.xml index a120b1aec80013ebc3135da66b1b05096c0e4760..3fd9e66562c58ceaf7e30727d60aaf39def5d220 100644 --- a/indra/newview/skins/default/xui/en/widgets/simple_text_editor.xml +++ b/indra/newview/skins/default/xui/en/widgets/simple_text_editor.xml @@ -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>