From e72c803df01e95d4ce73c0b207b1da9ea89eb144 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Sat, 9 Jul 2022 00:19:14 +0300 Subject: SL-17741 Paste is not disabled when copying 'no copy' items We should allow to copy 'no copy' items for the ability to paste them as links, but regular 'paste' should be disabled in such case Also fixed library items enabling 'paste as link', we can not link library items. --- indra/llui/llfolderviewmodel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h index 093e213be3..618169a8fe 100644 --- a/indra/llui/llfolderviewmodel.h +++ b/indra/llui/llfolderviewmodel.h @@ -172,7 +172,7 @@ public: virtual BOOL removeItem() = 0; virtual void removeBatch(std::vector& batch) = 0; - virtual BOOL isItemCopyable() const = 0; + virtual bool isItemCopyable(bool can_copy_as_link = true) const = 0; virtual BOOL copyToClipboard() const = 0; virtual BOOL cutToClipboard() = 0; virtual bool isCutToClipboard() { return false; }; -- cgit v1.3 From 477f173ad55ca145ff027cb54f86c6553cf6f62d Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 19 Jul 2022 01:25:30 +0300 Subject: SL-16745 Some checkboxes are truncated after changing 'UI size' --- indra/llui/llcheckboxctrl.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp index 08da599ef2..362fe0c19e 100644 --- a/indra/llui/llcheckboxctrl.cpp +++ b/indra/llui/llcheckboxctrl.cpp @@ -203,11 +203,9 @@ void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent) // it will work fine in case of decrease of space, but if we get more space or text // becomes longer, label will fail to grow so reinit label's dimentions. - static LLUICachedControl llcheckboxctrl_hpad("UICheckboxctrlHPad", 0); LLRect label_rect = mLabel->getRect(); - S32 new_width = getRect().getWidth() - label_rect.mLeft - llcheckboxctrl_hpad; - label_rect.mRight = label_rect.mLeft + new_width; - mLabel->setRect(label_rect); + S32 new_width = rect.getWidth() - label_rect.mLeft; + mLabel->reshape(new_width, label_rect.getHeight(), TRUE); S32 label_top = label_rect.mTop; mLabel->reshapeToFitText(TRUE); -- cgit v1.3 From 4c3f343799ca4be4b618dca8cf13a86e8941fb44 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 26 Jul 2022 19:40:10 +0300 Subject: SL-17045 LSL editor cursor position desynchronization 1. Fixed cursor position calculations 2. Fixed selection rect calculation --- indra/llprimitive/llmodel.h | 2 + indra/llui/lltextbase.cpp | 197 ++++++++++++++++++++++----------------- indra/llui/lltextbase.h | 2 + indra/newview/llscripteditor.cpp | 79 +--------------- 4 files changed, 117 insertions(+), 163 deletions(-) (limited to 'indra/llui') diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index 3881b1338c..599f19a2a3 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -56,6 +56,8 @@ public: mutable std::vector mJointNums; typedef std::vector> matrix_list_t; matrix_list_t mInvBindMatrix; + + // bones/joints position overrides matrix_list_t mAlternateBindMatrix; LL_ALIGN_16(LLMatrix4a mBindShapeMatrix); diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 0dc99fdde6..44546c7897 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -353,95 +353,113 @@ void LLTextBase::onValueChange(S32 start, S32 end) { } - -// Draws the black box behind the selected text -void LLTextBase::drawSelectionBackground() +std::vector LLTextBase::getSelctionRects() { - // Draw selection even if we don't have keyboard focus for search/replace - if( hasSelection() && !mLineInfoList.empty()) - { - std::vector selection_rects; + // Nor supposed to be called without selection + llassert(hasSelection()); + llassert(!mLineInfoList.empty()); - S32 selection_left = llmin( mSelectionStart, mSelectionEnd ); - S32 selection_right = llmax( mSelectionStart, mSelectionEnd ); + std::vector selection_rects; - // Skip through the lines we aren't drawing. - LLRect content_display_rect = getVisibleDocumentRect(); + S32 selection_left = llmin(mSelectionStart, mSelectionEnd); + S32 selection_right = llmax(mSelectionStart, mSelectionEnd); - // binary search for line that starts before top of visible buffer - 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()); + // Skip through the lines we aren't drawing. + LLRect content_display_rect = getVisibleDocumentRect(); - bool done = false; + // binary search for line that starts before top of visible buffer + 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()); - // Find the coordinates of the selected area - for (;line_iter != end_iter && !done; ++line_iter) - { - // 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; - - for(;segment_iter != mSegments.end(); ++segment_iter, segment_offset = 0) - { - LLTextSegmentPtr segmentp = *segment_iter; + bool done = false; - S32 segment_line_start = segmentp->getStart() + segment_offset; - S32 segment_line_end = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd); + // Find the coordinates of the selected area + for (; line_iter != end_iter && !done; ++line_iter) + { + // 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); - if (segment_line_start > segment_line_end) break; + // Use F32 otherwise a string of multiple segments + // will accumulate a large error + F32 left_precise = line_iter->mRect.mLeft; + F32 right_precise = line_iter->mRect.mLeft; - S32 segment_width = 0; - S32 segment_height = 0; + 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); + + if (segment_line_start > segment_line_end) break; + + F32 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->getDimensionsF32(segment_offset, num_chars, segment_width, segment_height); + left_precise += 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->getDimensionsF32(segment_offset, num_chars, segment_width, segment_height); + right_precise += segment_width; + } + // else if selection ends on current segment... + else + { + S32 num_chars = selection_right - segment_line_start; + segmentp->getDimensionsF32(segment_offset, num_chars, segment_width, segment_height); + right_precise += segment_width; + + break; + } + } - // 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; - } + LLRect selection_rect; + selection_rect.mLeft = left_precise; + selection_rect.mRight = right_precise; + selection_rect.mBottom = line_iter->mRect.mBottom; + selection_rect.mTop = line_iter->mRect.mTop; - // 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; + selection_rects.push_back(selection_rect); + } + } - break; - } - } - selection_rects.push_back(selection_rect); - } - } + return selection_rects; +} + +// Draws the black box behind the selected text +void LLTextBase::drawSelectionBackground() +{ + // Draw selection even if we don't have keyboard focus for search/replace + if (hasSelection() && !mLineInfoList.empty()) + { + std::vector selection_rects = getSelctionRects(); // 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; F32 alpha = hasFocus() ? 0.7f : 0.3f; alpha *= getDrawContext().mAlpha; + LLColor4 selection_color(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], alpha); + LLRect content_display_rect = getVisibleDocumentRect(); for (std::vector::iterator rect_it = selection_rects.begin(); rect_it != selection_rects.end(); @@ -2508,7 +2526,7 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round, } S32 pos = getLength(); - S32 start_x = line_iter->mRect.mLeft + doc_rect.mLeft; + F32 start_x = line_iter->mRect.mLeft + doc_rect.mLeft; segment_set_t::iterator line_seg_iter; S32 line_seg_offset; @@ -2520,8 +2538,9 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round, S32 segment_line_start = segmentp->getStart() + line_seg_offset; S32 segment_line_length = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd) - segment_line_start; - S32 text_width, text_height; - bool newline = segmentp->getDimensions(line_seg_offset, segment_line_length, text_width, text_height); + F32 text_width; + S32 text_height; + bool newline = segmentp->getDimensionsF32(line_seg_offset, segment_line_length, text_width, text_height); if(newline) { @@ -2541,8 +2560,9 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round, S32 offset; if (!segmentp->canEdit()) { - S32 segment_width, segment_height; - segmentp->getDimensions(0, segmentp->getEnd() - segmentp->getStart(), segment_width, segment_height); + F32 segment_width; + S32 segment_height; + segmentp->getDimensionsF32(0, segmentp->getEnd() - segmentp->getStart(), segment_width, segment_height); if (round && local_x - start_x > segment_width / 2) { offset = segment_line_length; @@ -2589,17 +2609,11 @@ LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const return LLRect(); } - LLRect doc_rect; - // clamp pos to valid values pos = llclamp(pos, 0, mLineInfoList.back().mDocIndexEnd - 1); line_list_t::const_iterator line_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), pos, line_end_compare()); - doc_rect.mLeft = line_iter->mRect.mLeft; - doc_rect.mBottom = line_iter->mRect.mBottom; - doc_rect.mTop = line_iter->mRect.mTop; - segment_set_t::iterator line_seg_iter; S32 line_seg_offset; segment_set_t::iterator cursor_seg_iter; @@ -2607,6 +2621,8 @@ LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const getSegmentAndOffset(line_iter->mDocIndexStart, &line_seg_iter, &line_seg_offset); getSegmentAndOffset(pos, &cursor_seg_iter, &cursor_seg_offset); + F32 doc_left_precise = line_iter->mRect.mLeft; + while(line_seg_iter != mSegments.end()) { const LLTextSegmentPtr segmentp = *line_seg_iter; @@ -2614,18 +2630,20 @@ LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const if (line_seg_iter == cursor_seg_iter) { // cursor advanced to right based on difference in offset of cursor to start of line - S32 segment_width, segment_height; - segmentp->getDimensions(line_seg_offset, cursor_seg_offset - line_seg_offset, segment_width, segment_height); - doc_rect.mLeft += segment_width; + F32 segment_width; + S32 segment_height; + segmentp->getDimensionsF32(line_seg_offset, cursor_seg_offset - line_seg_offset, segment_width, segment_height); + doc_left_precise += segment_width; break; } else { // add remainder of current text segment to cursor position - S32 segment_width, segment_height; - segmentp->getDimensions(line_seg_offset, (segmentp->getEnd() - segmentp->getStart()) - line_seg_offset, segment_width, segment_height); - doc_rect.mLeft += segment_width; + F32 segment_width; + S32 segment_height; + segmentp->getDimensionsF32(line_seg_offset, (segmentp->getEnd() - segmentp->getStart()) - line_seg_offset, segment_width, segment_height); + doc_left_precise += segment_width; // offset will be 0 for all segments after the first line_seg_offset = 0; // go to next text segment on this line @@ -2633,6 +2651,11 @@ LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const } } + LLRect doc_rect; + doc_rect.mLeft = doc_left_precise; + doc_rect.mBottom = line_iter->mRect.mBottom; + doc_rect.mTop = line_iter->mRect.mTop; + // set rect to 0 width doc_rect.mRight = doc_rect.mLeft; diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index a4e83b42b4..82844200cf 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -635,6 +635,8 @@ protected: return mLabel.getString() + getToolTip(); } + std::vector getSelctionRects(); + protected: // text segmentation and flow segment_set_t mSegments; diff --git a/indra/newview/llscripteditor.cpp b/indra/newview/llscripteditor.cpp index c6bb2f19dd..140cbbedbe 100644 --- a/indra/newview/llscripteditor.cpp +++ b/indra/newview/llscripteditor.cpp @@ -187,82 +187,8 @@ void LLScriptEditor::drawSelectionBackground() // Draw selection even if we don't have keyboard focus for search/replace if( hasSelection() && !mLineInfoList.empty()) { - std::vector selection_rects; - - 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(); - - // binary search for line that starts before top of visible buffer - line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mTop, LLTextBase::compare_bottom()); - line_list_t::const_iterator end_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mBottom, LLTextBase::compare_top()); - - bool done = false; - - // Find the coordinates of the selected area - for (;line_iter != end_iter && !done; ++line_iter) - { - // 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; - - 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); - - 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; - - break; - } - } - selection_rects.push_back(selection_rect); - } - } - + std::vector selection_rects = getSelctionRects(); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); const LLColor4& color = mReadOnly ? mReadOnlyFgColor : mFgColor; F32 alpha = hasFocus() ? 0.7f : 0.3f; @@ -272,6 +198,7 @@ void LLScriptEditor::drawSelectionBackground() (1.f + color.mV[VGREEN]) * 0.5f, (1.f + color.mV[VBLUE]) * 0.5f, alpha); + LLRect content_display_rect = getVisibleDocumentRect(); for (std::vector::iterator rect_it = selection_rects.begin(); rect_it != selection_rects.end(); -- cgit v1.3 From 3f3735c1f810f6a6c5635a5895689f5a366571de Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Tue, 2 Aug 2022 14:59:04 +0300 Subject: SL-17851 Highlight matching notifications when using Search Box in Preference --- indra/llui/llscrolllistctrl.cpp | 39 ++++++++++++++++++++++ indra/llui/llscrolllistctrl.h | 2 ++ indra/newview/llfloaterpreference.cpp | 21 ++++++++++++ indra/newview/llfloaterpreference.h | 1 + .../newview/skins/default/xui/en/notifications.xml | 2 +- 5 files changed, 64 insertions(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 11b0eb9f80..f3211b23c9 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -3307,3 +3307,42 @@ boost::signals2::connection LLScrollListCtrl::setIsFriendCallback(const is_frien } return mIsFriendSignal->connect(cb); } + +bool LLScrollListCtrl::highlightMatchingItems(const std::string& filter_str) +{ + if (filter_str == "" || filter_str == " ") + { + clearHighlightedItems(); + return false; + } + + bool res = false; + + setHighlightedColor(LLUIColorTable::instance().getColor("SearchableControlHighlightColor", LLColor4::red)); + + std::string filter_str_lc(filter_str); + LLStringUtil::toLower(filter_str_lc); + + std::vector data = getAllData(); + std::vector::iterator iter = data.begin(); + while (iter != data.end()) + { + LLScrollListCell* cell = (*iter)->getColumn(0); + if (cell) + { + std::string value = cell->getValue().asString(); + LLStringUtil::toLower(value); + if (value.find(filter_str_lc) == std::string::npos) + { + (*iter)->setHighlighted(false); + } + else + { + (*iter)->setHighlighted(true); + res = true; + } + } + iter++; + } + return res; +} diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index 08134bbfc8..af553843bd 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -410,6 +410,8 @@ public: void setNeedsSort(bool val = true) { mSorted = !val; } void dirtyColumns(); // some operation has potentially affected column layout or ordering + bool highlightMatchingItems(const std::string& filter_str); + boost::signals2::connection setSortCallback(sort_signal_t::slot_type cb ) { if (!mSortCallback) mSortCallback = new sort_signal_t(); diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 2bbf3b751f..98ac79dd96 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -1512,6 +1512,10 @@ void LLFloaterPreference::onClickEnablePopup() } buildPopupLists(); + if (!mFilterEdit->getText().empty()) + { + filterIgnorableNotifications(); + } } void LLFloaterPreference::onClickDisablePopup() @@ -1527,6 +1531,10 @@ void LLFloaterPreference::onClickDisablePopup() } buildPopupLists(); + if (!mFilterEdit->getText().empty()) + { + filterIgnorableNotifications(); + } } void LLFloaterPreference::resetAllIgnored() @@ -3547,11 +3555,24 @@ void LLFloaterPreference::onUpdateFilterTerm(bool force) return; mSearchData->mRootTab->hightlightAndHide( seachValue ); + filterIgnorableNotifications(); + LLTabContainer *pRoot = getChild< LLTabContainer >( "pref core" ); if( pRoot ) pRoot->selectFirstTab(); } +void LLFloaterPreference::filterIgnorableNotifications() +{ + bool visible = getChildRef("enabled_popups").highlightMatchingItems(mFilterEdit->getValue()); + visible |= getChildRef("disabled_popups").highlightMatchingItems(mFilterEdit->getValue()); + + if (visible) + { + getChildRef("pref core").setTabVisibility( getChild("msgs"), true ); + } +} + void collectChildren( LLView const *aView, ll::prefs::PanelDataPtr aParentPanel, ll::prefs::TabContainerDataPtr aParentTabContainer ) { if( !aView ) diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index 5797f7be8d..484f82aa7f 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -227,6 +227,7 @@ private: void onUpdateFilterTerm( bool force = false ); void collectSearchableItems(); + void filterIgnorableNotifications(); std::map mIgnorableNotifs; }; diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index aa93601669..b8ccc8c3e0 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -9628,7 +9628,7 @@ Do you wish to continue? The selected object affects the navmesh. Changing it to a Flexible Path will remove it from the navmesh. confirm -- cgit v1.3 From 1f53d3abbf612531dd10672127552e189255da01 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 14 Jul 2022 22:39:23 +0300 Subject: SL-17628 Added attachments can be moved past limit #2 --- indra/llui/llspinctrl.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp index ef7c8ec012..c411aafb1a 100644 --- a/indra/llui/llspinctrl.cpp +++ b/indra/llui/llspinctrl.cpp @@ -101,7 +101,10 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p) // Spin buttons LLButton::Params up_button_params(p.up_button); up_button_params.rect = LLRect(btn_left, getRect().getHeight(), btn_right, getRect().getHeight() - spinctrl_btn_height); - up_button_params.click_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2)); + // Click callback starts within the button and ends within the button, + // but LLSpinCtrl handles the action continuosly so subsribers needs to + // be informed about click ending even if outside view, use 'up' instead + up_button_params.mouse_up_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2)); up_button_params.mouse_held_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2)); up_button_params.commit_on_capture_lost = true; @@ -110,7 +113,7 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p) LLButton::Params down_button_params(p.down_button); down_button_params.rect = LLRect(btn_left, getRect().getHeight() - spinctrl_btn_height, btn_right, getRect().getHeight() - 2 * spinctrl_btn_height); - down_button_params.click_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2)); + down_button_params.mouse_up_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2)); down_button_params.mouse_held_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2)); down_button_params.commit_on_capture_lost = true; mDownBtn = LLUICtrlFactory::create(down_button_params); -- cgit v1.3 From 0191ee5f6f96eafa20e838ee1737eea58dafb1de Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Wed, 17 Aug 2022 14:50:03 +0300 Subject: SL-17973 FIXED region name is not shown in the IM chat --- indra/llui/llchat.h | 3 ++- indra/newview/llchathistory.cpp | 7 ++++--- indra/newview/llfloaterimsession.cpp | 5 +++++ indra/newview/llimprocessing.cpp | 12 +++++++++++- indra/newview/llimview.cpp | 21 +++++++++++---------- indra/newview/llimview.h | 10 +++++----- 6 files changed, 38 insertions(+), 20 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llchat.h b/indra/llui/llchat.h index c39e44200c..b4fd5f60aa 100644 --- a/indra/llui/llchat.h +++ b/indra/llui/llchat.h @@ -38,7 +38,8 @@ typedef enum e_chat_source_type CHAT_SOURCE_AGENT = 1, CHAT_SOURCE_OBJECT = 2, CHAT_SOURCE_TELEPORT = 3, - CHAT_SOURCE_UNKNOWN = 4 + CHAT_SOURCE_UNKNOWN = 4, + CHAT_SOURCE_REGION = 5, } EChatSourceType; typedef enum e_chat_type diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index bdd516e1de..79b7372610 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -602,7 +602,7 @@ public: void showInspector() { - if (mAvatarID.isNull() && CHAT_SOURCE_SYSTEM != mSourceType) return; + if (mAvatarID.isNull() && CHAT_SOURCE_SYSTEM != mSourceType && CHAT_SOURCE_REGION != mSourceType) return; if (mSourceType == CHAT_SOURCE_OBJECT) { @@ -744,6 +744,7 @@ public: icon->setValue(LLSD("OBJECT_Icon")); break; case CHAT_SOURCE_SYSTEM: + case CHAT_SOURCE_REGION: icon->setValue(LLSD("SL_Logo")); break; case CHAT_SOURCE_TELEPORT: @@ -893,7 +894,7 @@ protected: void showInfoCtrl() { - const bool isVisible = !mAvatarID.isNull() && !mFrom.empty() && CHAT_SOURCE_SYSTEM != mSourceType; + const bool isVisible = !mAvatarID.isNull() && !mFrom.empty() && CHAT_SOURCE_SYSTEM != mSourceType && CHAT_SOURCE_REGION != mSourceType; if (isVisible) { const LLRect sticky_rect = mUserNameTextBox->getRect(); @@ -1286,7 +1287,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL mEditor->appendText(chat.mFromName + delimiter, prependNewLineState, link_params); prependNewLineState = false; } - else if ( chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log) + else if ( chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log && chat.mSourceType != CHAT_SOURCE_REGION) { LLStyle::Params link_params(body_message_params); link_params.overwriteFrom(LLStyleMap::instance().lookupAgent(chat.mFromID)); diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp index 48e2b8dc14..ee9dc35283 100644 --- a/indra/newview/llfloaterimsession.cpp +++ b/indra/newview/llfloaterimsession.cpp @@ -842,6 +842,7 @@ void LLFloaterIMSession::updateMessages() std::string from = msg["from"].asString(); std::string message = msg["message"].asString(); bool is_history = msg["is_history"].asBoolean(); + bool is_region_msg = msg["is_region_msg"].asBoolean(); LLChat chat; chat.mFromID = from_id; @@ -849,6 +850,10 @@ void LLFloaterIMSession::updateMessages() chat.mFromName = from; chat.mTimeStr = time; chat.mChatStyle = is_history ? CHAT_STYLE_HISTORY : chat.mChatStyle; + if (is_region_msg) + { + chat.mSourceType = CHAT_SOURCE_REGION; + } // process offer notification if (msg.has("notification_id")) diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp index 0524313a5c..d29e0314b4 100644 --- a/indra/newview/llimprocessing.cpp +++ b/indra/newview/llimprocessing.cpp @@ -55,6 +55,7 @@ #include "llviewerwindow.h" #include "llviewerregion.h" #include "llvoavatarself.h" +#include "llworld.h" #include "boost/lexical_cast.hpp" #if LL_MSVC @@ -572,6 +573,15 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, } if (!mute_im) { + bool region_message = false; + if (region_id.isNull()) + { + LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(from_id); + if (regionp) + { + region_message = true; + } + } gIMMgr->addMessage( session_id, from_id, @@ -583,7 +593,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, parent_estate_id, region_id, position, - true); + region_message); } else { diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index b7e0a6a794..c3131a513a 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -771,7 +771,7 @@ void LLIMModel::LLIMSession::sessionInitReplyReceived(const LLUUID& new_session_ } } -void LLIMModel::LLIMSession::addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time, const bool is_history) +void LLIMModel::LLIMSession::addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time, const bool is_history, bool is_region_msg) { LLSD message; message["from"] = from; @@ -780,6 +780,7 @@ void LLIMModel::LLIMSession::addMessage(const std::string& from, const LLUUID& f message["time"] = time; message["index"] = (LLSD::Integer)mMsgs.size(); message["is_history"] = is_history; + message["is_region_msg"] = is_region_msg; mMsgs.push_front(message); @@ -1148,7 +1149,7 @@ void LLIMModel::sendNoUnreadMessages(const LLUUID& session_id) mNoUnreadMsgsSignal(arg); } -bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text) { +bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text, bool is_region_msg) { LLIMSession* session = findIMSession(session_id); @@ -1158,7 +1159,7 @@ bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from, return false; } - session->addMessage(from, from_id, utf8_text, LLLogChat::timestamp(false)); //might want to add date separately + session->addMessage(from, from_id, utf8_text, LLLogChat::timestamp(false), false, is_region_msg); //might want to add date separately return true; } @@ -1196,9 +1197,9 @@ bool LLIMModel::proccessOnlineOfflineNotification( } bool LLIMModel::addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, - const std::string& utf8_text, bool log2file /* = true */) { + const std::string& utf8_text, bool log2file, bool is_region_msg) { - LLIMSession* session = addMessageSilently(session_id, from, from_id, utf8_text, log2file); + LLIMSession* session = addMessageSilently(session_id, from, from_id, utf8_text, log2file, is_region_msg); if (!session) return false; //good place to add some1 to recent list @@ -1223,7 +1224,7 @@ bool LLIMModel::addMessage(const LLUUID& session_id, const std::string& from, co } LLIMModel::LLIMSession* LLIMModel::addMessageSilently(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, - const std::string& utf8_text, bool log2file /* = true */) + const std::string& utf8_text, bool log2file, bool is_region_msg) { LLIMSession* session = findIMSession(session_id); @@ -1239,7 +1240,7 @@ LLIMModel::LLIMSession* LLIMModel::addMessageSilently(const LLUUID& session_id, from_name = SYSTEM_FROM; } - addToHistory(session_id, from_name, from_id, utf8_text); + addToHistory(session_id, from_name, from_id, utf8_text, is_region_msg); if (log2file) { logToFile(getHistoryFileName(session_id), from_name, from_id, utf8_text); @@ -2695,7 +2696,7 @@ void LLIMMgr::addMessage( U32 parent_estate_id, const LLUUID& region_id, const LLVector3& position, - bool link_name) // If this is true, then we insert the name and link it to a profile + bool is_region_msg) { LLUUID other_participant_id = target_id; @@ -2767,7 +2768,7 @@ void LLIMMgr::addMessage( //<< "*** region_id: " << region_id << std::endl //<< "*** position: " << position << std::endl; - LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, bonus_info.str()); + LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, bonus_info.str(), true, is_region_msg); } // Logically it would make more sense to reject the session sooner, in another area of the @@ -2797,7 +2798,7 @@ void LLIMMgr::addMessage( if (!LLMuteList::getInstance()->isMuted(other_participant_id, LLMute::flagTextChat) && !skip_message) { - LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, msg); + LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, msg, true, is_region_msg); } // Open conversation floater if offline messages are present diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index 79c831ebb6..707c8ef79f 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -82,7 +82,7 @@ public: void sessionInitReplyReceived(const LLUUID& new_session_id); void addMessagesFromHistory(const std::list& history); - void addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time, const bool is_history = false); + void addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time, const bool is_history = false, bool is_region_msg = false); void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state, const LLVoiceChannel::EDirection& direction); /** @deprecated */ @@ -212,13 +212,13 @@ public: * and also saved into a file if log2file is specified. * It sends new message signal for each added message. */ - bool addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& other_participant_id, const std::string& utf8_text, bool log2file = true); + bool addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& other_participant_id, const std::string& utf8_text, bool log2file = true, bool is_region_msg = false); /** * Similar to addMessage(...) above but won't send a signal about a new message added */ LLIMModel::LLIMSession* addMessageSilently(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, - const std::string& utf8_text, bool log2file = true); + const std::string& utf8_text, bool log2file = true, bool is_region_msg = false); /** * Add a system message to an IM Model @@ -296,7 +296,7 @@ private: /** * Add message to a list of message associated with session specified by session_id */ - bool addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text); + bool addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text, bool is_region_msg = false); }; @@ -338,7 +338,7 @@ public: U32 parent_estate_id = 0, const LLUUID& region_id = LLUUID::null, const LLVector3& position = LLVector3::zero, - bool link_name = false); + bool is_region_msg = false); void addSystemMessage(const LLUUID& session_id, const std::string& message_name, const LLSD& args); -- cgit v1.3 From 1fb1a9df7a6664946f1f758330a0e6cfaef0dd8f Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Wed, 19 Oct 2022 16:17:26 -0400 Subject: Fix leak of context menu branches Introduce menu bloat logging code --- indra/llui/llmenugl.cpp | 58 +++++++++++++++++++++++++++------------- indra/llui/llmenugl.h | 3 +-- indra/newview/llviewerwindow.cpp | 53 ++++++++++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+), 20 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 4264028338..5cb840fd61 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -4087,25 +4087,39 @@ void LLTearOffMenu::closeTearOff() } LLContextMenuBranch::LLContextMenuBranch(const LLContextMenuBranch::Params& p) -: LLMenuItemGL(p), - mBranch( p.branch()->getHandle() ) +: LLMenuItemGL(p) { - mBranch.get()->hide(); - mBranch.get()->setParentMenuItem(this); + LLContextMenu* branch = static_cast(p.branch); + if (branch) + { + mBranch = branch->getHandle(); + branch->hide(); + branch->setParentMenuItem(this); + } +} + +LLContextMenuBranch::~LLContextMenuBranch() +{ + if (mBranch.get()) + { + mBranch.get()->die(); + } } // called to rebuild the draw label void LLContextMenuBranch::buildDrawLabel( void ) { + auto menu = getBranch(); + if (menu) { // default enablement is this -- if any of the subitems are // enabled, this item is enabled. JC - U32 sub_count = mBranch.get()->getItemCount(); + U32 sub_count = menu->getItemCount(); U32 i; BOOL any_enabled = FALSE; for (i = 0; i < sub_count; i++) { - LLMenuItemGL* item = mBranch.get()->getItem(i); + LLMenuItemGL* item = menu->getItem(i); item->buildDrawLabel(); if (item->getEnabled() && !item->getDrawTextDisabled() ) { @@ -4127,13 +4141,17 @@ void LLContextMenuBranch::buildDrawLabel( void ) void LLContextMenuBranch::showSubMenu() { - LLMenuItemGL* menu_item = mBranch.get()->getParentMenuItem(); - if (menu_item != NULL && menu_item->getVisible()) + auto menu = getBranch(); + if(menu) { - S32 center_x; - S32 center_y; - localPointToScreen(getRect().getWidth(), getRect().getHeight() , ¢er_x, ¢er_y); - mBranch.get()->show(center_x, center_y); + LLMenuItemGL* menu_item = menu->getParentMenuItem(); + if (menu_item != NULL && menu_item->getVisible()) + { + S32 center_x; + S32 center_y; + localPointToScreen(getRect().getWidth(), getRect().getHeight(), ¢er_x, ¢er_y); + menu->show(center_x, center_y); + } } } @@ -4147,13 +4165,17 @@ void LLContextMenuBranch::setHighlight( BOOL highlight ) { if (highlight == getHighlight()) return; LLMenuItemGL::setHighlight(highlight); - if( highlight ) - { - showSubMenu(); - } - else + auto menu = getBranch(); + if (menu) { - mBranch.get()->hide(); + if (highlight) + { + showSubMenu(); + } + else + { + menu->hide(); + } } } diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index abbfd9a24a..f84c4d41eb 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -745,8 +745,7 @@ public: LLContextMenuBranch(const Params&); - virtual ~LLContextMenuBranch() - {} + virtual ~LLContextMenuBranch(); // called to rebuild the draw label virtual void buildDrawLabel( void ); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 5ce46b143a..49f5756976 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -3420,6 +3420,59 @@ void LLViewerWindow::updateUI() root_view = mRootView; } + static LLCachedControl dump_menu_holder(gSavedSettings, "DumpMenuHolderSize", false); + if (dump_menu_holder) + { + static bool init = false; + static LLFrameTimer child_count_timer; + static std::vector child_vec; + if (!init) + { + child_count_timer.resetWithExpiry(5.f); + init = true; + } + if (child_count_timer.hasExpired()) + { + LL_INFOS() << "gMenuHolder child count: " << gMenuHolder->getChildCount() << LL_ENDL; + std::vector local_child_vec; + LLView::child_list_t child_list = *gMenuHolder->getChildList(); + for (auto child : child_list) + { + local_child_vec.emplace_back(child->getName()); + } + if (!local_child_vec.empty() && local_child_vec != child_vec) + { + std::vector out_vec; + std::sort(local_child_vec.begin(), local_child_vec.end()); + std::sort(child_vec.begin(), child_vec.end()); + std::set_difference(child_vec.begin(), child_vec.end(), local_child_vec.begin(), local_child_vec.end(), std::inserter(out_vec, out_vec.begin())); + if (!out_vec.empty()) + { + LL_INFOS() << "gMenuHolder removal diff size: '"< Date: Wed, 19 Oct 2022 16:19:33 -0400 Subject: Reduce folderview menu bloat via lazy creation on right click --- indra/llui/llfolderview.cpp | 58 +++++++++++++++++++++++--------- indra/llui/llfolderview.h | 3 ++ indra/newview/llfloaterimcontainer.cpp | 1 + indra/newview/llfloaterimsessiontab.cpp | 1 + indra/newview/llinventorypanel.cpp | 7 +++- indra/newview/llpanelmaininventory.cpp | 12 +++++-- indra/newview/llpanelobjectinventory.cpp | 1 + 7 files changed, 63 insertions(+), 20 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp index ea2ca68e47..e1869e8125 100644 --- a/indra/llui/llfolderview.cpp +++ b/indra/llui/llfolderview.cpp @@ -163,6 +163,7 @@ LLFolderView::LLFolderView(const Params& p) : LLFolderViewFolder(p), mScrollContainer( NULL ), mPopupMenuHandle(), + mMenuFileName(p.options_menu), mAllowMultiSelect(p.allow_multiselect), mAllowDrag(p.allow_drag), mShowEmptyMessage(p.show_empty_message), @@ -182,6 +183,7 @@ LLFolderView::LLFolderView(const Params& p) mMinWidth(0), mDragAndDropThisFrame(FALSE), mCallbackRegistrar(NULL), + mEnableRegistrar(NULL), mUseEllipses(p.use_ellipses), mDraggingOverItem(NULL), mStatusTextBox(NULL), @@ -244,17 +246,6 @@ LLFolderView::LLFolderView(const Params& p) mStatusTextBox->setFollowsTop(); addChild(mStatusTextBox); - - // make the popup menu available - llassert(LLMenuGL::sMenuContainer != NULL); - LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile(p.options_menu, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance()); - if (!menu) - { - menu = LLUICtrlFactory::getDefaultWidget("inventory_menu"); - } - menu->setBackgroundColor(LLUIColorTable::instance().getColor("MenuPopupBgColor")); - mPopupMenuHandle = menu->getHandle(); - mViewModelItem->openItem(); mAreChildrenInited = true; // root folder is a special case due to not being loaded normally, assume that it's inited. @@ -276,6 +267,7 @@ LLFolderView::~LLFolderView( void ) mStatusTextBox = NULL; if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die(); + mPopupMenuHandle.markDead(); mAutoOpenItems.removeAllNodes(); clearSelection(); @@ -1438,22 +1430,56 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask ) BOOL handled = childrenHandleRightMouseDown(x, y, mask) != NULL; S32 count = mSelectedItems.size(); - LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); + LLMenuGL* menu = static_cast(mPopupMenuHandle.get()); + if (!menu) + { + if (mCallbackRegistrar) + { + mCallbackRegistrar->pushScope(); + } + if (mEnableRegistrar) + { + mEnableRegistrar->pushScope(); + } + llassert(LLMenuGL::sMenuContainer != NULL); + menu = LLUICtrlFactory::getInstance()->createFromFile(mMenuFileName, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance()); + if (!menu) + { + menu = LLUICtrlFactory::getDefaultWidget("inventory_menu"); + } + menu->setBackgroundColor(LLUIColorTable::instance().getColor("MenuPopupBgColor")); + mPopupMenuHandle = menu->getHandle(); + if (mEnableRegistrar) + { + mEnableRegistrar->popScope(); + } + if (mCallbackRegistrar) + { + mCallbackRegistrar->popScope(); + } + } bool hide_folder_menu = mSuppressFolderMenu && isFolderSelected(); - if ((handled - && ( count > 0 && (hasVisibleChildren()) ) // show menu only if selected items are visible - && menu ) && + if (menu && (handled + && ( count > 0 && (hasVisibleChildren()) )) && // show menu only if selected items are visible !hide_folder_menu) { if (mCallbackRegistrar) { mCallbackRegistrar->pushScope(); } + if (mEnableRegistrar) + { + mEnableRegistrar->pushScope(); + } updateMenuOptions(menu); menu->updateParent(LLMenuGL::sMenuContainer); LLMenuGL::showPopup(this, menu, x, y); + if (mEnableRegistrar) + { + mEnableRegistrar->popScope(); + } if (mCallbackRegistrar) { mCallbackRegistrar->popScope(); @@ -1531,7 +1557,7 @@ void LLFolderView::deleteAllChildren() { closeRenamer(); if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die(); - mPopupMenuHandle = LLHandle(); + mPopupMenuHandle.markDead(); mScrollContainer = NULL; mRenameItem = NULL; mRenamer = NULL; diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h index 6bb5e6c02e..7dfa04828a 100644 --- a/indra/llui/llfolderview.h +++ b/indra/llui/llfolderview.h @@ -235,6 +235,7 @@ public: bool showItemLinkOverlays() { return mShowItemLinkOverlays; } void setCallbackRegistrar(LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* registrar) { mCallbackRegistrar = registrar; } + void setEnableRegistrar(LLUICtrl::EnableCallbackRegistry::ScopedRegistrar* registrar) { mEnableRegistrar = registrar; } LLPanel* getParentPanel() { return mParentPanel.get(); } // DEBUG only @@ -272,6 +273,7 @@ protected: protected: LLHandle mPopupMenuHandle; + std::string mMenuFileName; selected_items_t mSelectedItems; bool mKeyboardSelection, @@ -327,6 +329,7 @@ protected: LLFolderViewItem* mDraggingOverItem; // See EXT-719 LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* mCallbackRegistrar; + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar* mEnableRegistrar; public: static F32 sAutoOpenTime; diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index 703b5d0011..2720b7fcf7 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -211,6 +211,7 @@ BOOL LLFloaterIMContainer::postBuild() p.options_menu = "menu_conversation.xml"; mConversationsRoot = LLUICtrlFactory::create(p); mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar); + mConversationsRoot->setEnableRegistrar(&mEnableCallbackRegistrar); // Add listener to conversation model events mConversationsEventStream.listen("ConversationsRefresh", boost::bind(&LLFloaterIMContainer::onConversationModelEvent, this, _1)); diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index 93a0b39e02..f973ae43cc 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -317,6 +317,7 @@ BOOL LLFloaterIMSessionTab::postBuild() p.name = "root"; mConversationsRoot = LLUICtrlFactory::create(p); mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar); + mConversationsRoot->setEnableRegistrar(&mEnableCallbackRegistrar); // Attach that root to the scroller mScroller->addChild(mConversationsRoot); mConversationsRoot->setScrollContainer(mScroller); diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 6b102c7500..c065c76dca 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -211,7 +211,11 @@ LLFolderView * LLInventoryPanel::createFolderRoot(LLUUID root_id ) p.allow_drop = mParams.allow_drop_on_root; p.options_menu = "menu_inventory.xml"; - return LLUICtrlFactory::create(p); + LLFolderView* fv = LLUICtrlFactory::create(p); + fv->setCallbackRegistrar(&mCommitCallbackRegistrar); + fv->setEnableRegistrar(&mEnableCallbackRegistrar); + + return fv; } void LLInventoryPanel::clearFolderRoot() @@ -264,6 +268,7 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params) } mCommitCallbackRegistrar.popScope(); mFolderRoot.get()->setCallbackRegistrar(&mCommitCallbackRegistrar); + mFolderRoot.get()->setEnableRegistrar(&mEnableCallbackRegistrar); // Scroller LLRect scroller_view_rect = getRect(); diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index 89256b40c4..81acb1c8b4 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -307,6 +307,13 @@ LLPanelMainInventory::~LLPanelMainInventory( void ) gInventory.removeObserver(this); delete mSavedFolderState; + + auto menu = mMenuAddHandle.get(); + if(menu) + { + menu->die(); + mMenuAddHandle.markDead(); + } } LLInventoryPanel* LLPanelMainInventory::getAllItemsPanel() @@ -1177,13 +1184,12 @@ void LLPanelMainInventory::initListCommandsHandlers() mEnableCallbackRegistrar.add("Inventory.GearDefault.Check", boost::bind(&LLPanelMainInventory::isActionChecked, this, _2)); mEnableCallbackRegistrar.add("Inventory.GearDefault.Enable", boost::bind(&LLPanelMainInventory::isActionEnabled, this, _2)); mMenuGearDefault = LLUICtrlFactory::getInstance()->createFromFile("menu_inventory_gear_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - mGearMenuButton->setMenu(mMenuGearDefault); + mGearMenuButton->setMenu(mMenuGearDefault, LLMenuButton::MP_TOP_LEFT, true); LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile("menu_inventory_add.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); mMenuAddHandle = menu->getHandle(); mMenuVisibility = LLUICtrlFactory::getInstance()->createFromFile("menu_inventory_search_visibility.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - mVisibilityMenuButton->setMenu(mMenuVisibility); - mVisibilityMenuButton->setMenuPosition(LLMenuButton::MP_BOTTOM_LEFT); + mVisibilityMenuButton->setMenu(mMenuVisibility, LLMenuButton::MP_BOTTOM_LEFT, true); // Update the trash button when selected item(s) get worn or taken off. LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&LLPanelMainInventory::updateListCommands, this)); diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index cfaa9456be..17b4528d97 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -1360,6 +1360,7 @@ void LLPanelObjectInventory::reset() mFolders = LLUICtrlFactory::create(p); mFolders->setCallbackRegistrar(&mCommitCallbackRegistrar); + mFolders->setEnableRegistrar(&mEnableCallbackRegistrar); if (hasFocus()) { -- cgit v1.3 From bbd8df15de6b8f9b321f251c3e764ea654d5ecc7 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Wed, 19 Oct 2022 16:23:25 -0400 Subject: Fix menu leaks and lazy creation in text editing and scroll lists --- indra/llui/lllineeditor.cpp | 16 +++++++++------- indra/llui/llscrolllistctrl.cpp | 28 ++++++++++++++++++++-------- indra/llui/llscrolllistctrl.h | 2 +- indra/llui/lltextbase.cpp | 6 ++++++ indra/llui/lltexteditor.cpp | 31 +++++++++++++++++++++---------- indra/llui/lltexteditor.h | 2 +- indra/llui/lltoolbar.cpp | 7 ++++++- indra/newview/lllistcontextmenu.cpp | 10 +++------- 8 files changed, 67 insertions(+), 35 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 33037b5001..f16f8c3e8d 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -209,13 +209,6 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p) setPrevalidateInput(p.prevalidate_input_callback()); setPrevalidate(p.prevalidate_callback()); - - llassert(LLMenuGL::sMenuContainer != NULL); - LLContextMenu* menu = LLUICtrlFactory::instance().createFromFile - ("menu_text_editor.xml", - LLMenuGL::sMenuContainer, - LLMenuHolderGL::child_registry_t::instance()); - setContextMenu(menu); } LLLineEditor::~LLLineEditor() @@ -2637,6 +2630,15 @@ LLWString LLLineEditor::getConvertedText() const void LLLineEditor::showContextMenu(S32 x, S32 y) { LLContextMenu* menu = static_cast(mContextMenuHandle.get()); + if (!menu) + { + llassert(LLMenuGL::sMenuContainer != NULL); + menu = LLUICtrlFactory::createFromFile + ("menu_text_editor.xml", + LLMenuGL::sMenuContainer, + LLMenuHolderGL::child_registry_t::instance()); + setContextMenu(menu); + } if (menu) { diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 65c7b420ce..167593bd52 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -196,7 +196,6 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p) mHighlightedItem(-1), mBorder(NULL), mSortCallback(NULL), - mPopupMenu(NULL), mCommentTextView(NULL), mNumDynamicWidthColumns(0), mTotalStaticColumnWidth(0), @@ -348,6 +347,13 @@ LLScrollListCtrl::~LLScrollListCtrl() mItemList.clear(); clearColumns(); //clears columns and deletes headers delete mIsFriendSignal; + + auto menu = mPopupMenuHandle.get(); + if (menu) + { + menu->die(); + mPopupMenuHandle.markDead(); + } } @@ -1997,17 +2003,23 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask) // create the context menu from the XUI file and display it std::string menu_name = is_group ? "menu_url_group.xml" : "menu_url_agent.xml"; - delete mPopupMenu; + auto menu = mPopupMenuHandle.get(); + if (menu) + { + menu->die(); + mPopupMenuHandle.markDead(); + } llassert(LLMenuGL::sMenuContainer != NULL); - mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile( + menu = LLUICtrlFactory::getInstance()->createFromFile( menu_name, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance()); - if (mPopupMenu) + if (menu) { + mPopupMenuHandle = menu->getHandle(); if (mIsFriendSignal) { bool isFriend = *(*mIsFriendSignal)(uuid); - LLView* addFriendButton = mPopupMenu->getChild("add_friend"); - LLView* removeFriendButton = mPopupMenu->getChild("remove_friend"); + LLView* addFriendButton = menu->getChild("add_friend"); + LLView* removeFriendButton = menu->getChild("remove_friend"); if (addFriendButton && removeFriendButton) { @@ -2016,8 +2028,8 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask) } } - mPopupMenu->show(x, y); - LLMenuGL::showPopup(this, mPopupMenu, x, y); + menu->show(x, y); + LLMenuGL::showPopup(this, menu, x, y); return TRUE; } } diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index 77d10fdec7..6f7d4768e1 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -526,7 +526,7 @@ private: S32 mHighlightedItem; class LLViewBorder* mBorder; - LLContextMenu *mPopupMenu; + LLHandle mPopupMenuHandle; LLView *mCommentTextView; diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 7e4aaa53bf..fcfdd64e6a 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -273,6 +273,12 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p) LLTextBase::~LLTextBase() { mSegments.clear(); + LLContextMenu* menu = static_cast(mPopupMenuHandle.get()); + if (menu) + { + menu->die(); + mPopupMenuHandle.markDead(); + } delete mURLClickSignal; delete mIsFriendSignal; delete mIsObjectBlockedSignal; diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index b1f8b00cab..3d2a426913 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -257,7 +257,6 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) : mMouseDownY(0), mTabsToNextField(p.ignore_tab), mPrevalidateFunc(p.prevalidate_callback()), - mContextMenu(NULL), mShowContextMenu(p.show_context_menu), mEnableTooltipPaste(p.enable_tooltip_paste), mPassDelete(FALSE), @@ -301,8 +300,13 @@ LLTextEditor::~LLTextEditor() // Scrollbar is deleted by LLView std::for_each(mUndoStack.begin(), mUndoStack.end(), DeletePointer()); mUndoStack.clear(); - // context menu is owned by menu holder, not us - //delete mContextMenu; + // Mark the menu as dead or its retained in memory till shutdown. + LLContextMenu* menu = static_cast(mContextMenuHandle.get()); + if(menu) + { + menu->die(); + mContextMenuHandle.markDead(); + } } //////////////////////////////////////////////////////////// @@ -2051,12 +2055,19 @@ void LLTextEditor::setEnabled(BOOL enabled) void LLTextEditor::showContextMenu(S32 x, S32 y) { - if (!mContextMenu) + LLContextMenu* menu = static_cast(mContextMenuHandle.get()); + if (!menu) { llassert(LLMenuGL::sMenuContainer != NULL); - mContextMenu = LLUICtrlFactory::instance().createFromFile("menu_text_editor.xml", + menu = LLUICtrlFactory::createFromFile("menu_text_editor.xml", LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance()); + if(!menu) + { + LL_WARNS() << "Failed to create menu for LLTextEditor: " << getName() << LL_ENDL; + return; + } + mContextMenuHandle = menu->getHandle(); } // Route menu to this class @@ -2102,11 +2113,11 @@ void LLTextEditor::showContextMenu(S32 x, S32 y) } } - mContextMenu->setItemVisible("Suggestion Separator", (use_spellcheck) && (!mSuggestionList.empty())); - mContextMenu->setItemVisible("Add to Dictionary", (use_spellcheck) && (is_misspelled)); - mContextMenu->setItemVisible("Add to Ignore", (use_spellcheck) && (is_misspelled)); - mContextMenu->setItemVisible("Spellcheck Separator", (use_spellcheck) && (is_misspelled)); - mContextMenu->show(screen_x, screen_y, this); + menu->setItemVisible("Suggestion Separator", (use_spellcheck) && (!mSuggestionList.empty())); + menu->setItemVisible("Add to Dictionary", (use_spellcheck) && (is_misspelled)); + menu->setItemVisible("Add to Ignore", (use_spellcheck) && (is_misspelled)); + menu->setItemVisible("Spellcheck Separator", (use_spellcheck) && (is_misspelled)); + menu->show(screen_x, screen_y, this); } diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index 1a10d2fd1e..f3939248c2 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -329,7 +329,7 @@ private: keystroke_signal_t mKeystrokeSignal; LLTextValidate::validate_func_t mPrevalidateFunc; - LLContextMenu* mContextMenu; + LLHandle mContextMenuHandle; }; // end class LLTextEditor // Build time optimization, generate once in .cpp file diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp index 5150df25f2..2707f7a15c 100644 --- a/indra/llui/lltoolbar.cpp +++ b/indra/llui/lltoolbar.cpp @@ -127,7 +127,12 @@ LLToolBar::LLToolBar(const LLToolBar::Params& p) LLToolBar::~LLToolBar() { - delete mPopupMenuHandle.get(); + auto menu = mPopupMenuHandle.get(); + if (menu) + { + menu->die(); + mPopupMenuHandle.markDead(); + } delete mButtonAddSignal; delete mButtonEnterSignal; delete mButtonLeaveSignal; diff --git a/indra/newview/lllistcontextmenu.cpp b/indra/newview/lllistcontextmenu.cpp index 6bda8b1d0d..77185411c5 100644 --- a/indra/newview/lllistcontextmenu.cpp +++ b/indra/newview/lllistcontextmenu.cpp @@ -51,6 +51,7 @@ LLListContextMenu::~LLListContextMenu() if (!mMenuHandle.isDead()) { mMenuHandle.get()->die(); + mMenuHandle.markDead(); } } @@ -59,13 +60,8 @@ void LLListContextMenu::show(LLView* spawning_view, const uuid_vec_t& uuids, S32 LLContextMenu* menup = mMenuHandle.get(); if (menup) { - //preventing parent (menu holder) from deleting already "dead" context menus on exit - LLView* parent = menup->getParent(); - if (parent) - { - parent->removeChild(menup); - } - delete menup; + menup->die(); + mMenuHandle.markDead(); mUUIDs.clear(); } -- cgit v1.3 From 2745465c732d3c0bcaba6e560d69d3fc8adcff28 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Wed, 19 Oct 2022 22:15:07 -0400 Subject: Fix leak of item pairs during LLFlatListView destruction --- indra/llui/llflatlistview.cpp | 11 +++++++++++ indra/llui/llflatlistview.h | 1 + 2 files changed, 12 insertions(+) (limited to 'indra/llui') diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp index 5e00bf7f45..b13e7389cc 100644 --- a/indra/llui/llflatlistview.cpp +++ b/indra/llui/llflatlistview.cpp @@ -505,6 +505,17 @@ LLFlatListView::LLFlatListView(const LLFlatListView::Params& p) } }; +LLFlatListView::~LLFlatListView() +{ + for (pairs_iterator_t it = mItemPairs.begin(); it != mItemPairs.end(); ++it) + { + mItemsPanel->removeChild((*it)->first); + (*it)->first->die(); + delete *it; + } + mItemPairs.clear(); +} + // virtual void LLFlatListView::draw() { diff --git a/indra/llui/llflatlistview.h b/indra/llui/llflatlistview.h index 230ea200d8..d47c1cf333 100644 --- a/indra/llui/llflatlistview.h +++ b/indra/llui/llflatlistview.h @@ -299,6 +299,7 @@ public: virtual S32 notify(const LLSD& info) ; + virtual ~LLFlatListView(); protected: /** Pairs LLpanel representing a single item LLPanel and LLSD associated with it */ -- cgit v1.3 From 589a167147fd4a316f4cf588bbb2aaa103c9d3bb Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Wed, 19 Oct 2022 22:19:22 -0400 Subject: Fix leak of LLFolderViewModel sorter and filter with unique_ptr --- indra/llui/llfolderviewmodel.h | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h index 093e213be3..dd5eb47a63 100644 --- a/indra/llui/llfolderviewmodel.h +++ b/indra/llui/llfolderviewmodel.h @@ -419,21 +419,15 @@ public: mFilter(filter) {} - virtual ~LLFolderViewModel() - { - delete mSorter; - mSorter = NULL; - delete mFilter; - mFilter = NULL; - } + virtual ~LLFolderViewModel() {} virtual SortType& getSorter() { return *mSorter; } virtual const SortType& getSorter() const { return *mSorter; } - virtual void setSorter(const SortType& sorter) { mSorter = new SortType(sorter); requestSortAll(); } + virtual void setSorter(const SortType& sorter) { mSorter.reset(new SortType(sorter)); requestSortAll(); } virtual FilterType& getFilter() { return *mFilter; } virtual const FilterType& getFilter() const { return *mFilter; } - virtual void setFilter(const FilterType& filter) { mFilter = new FilterType(filter); } + virtual void setFilter(const FilterType& filter) { mFilter.reset(new FilterType(filter)); } // By default, we assume the content is available. If a network fetch mechanism is implemented for the model, // this method needs to be overloaded and return the relevant fetch status. @@ -471,8 +465,8 @@ public: } protected: - SortType* mSorter; - FilterType* mFilter; + std::unique_ptr mSorter; + std::unique_ptr mFilter; }; #endif // LLFOLDERVIEWMODEL_H -- cgit v1.3 From 8de9beeb6f1d2d3c3e6f5fde396e4cde0a54d36a Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Mon, 24 Oct 2022 21:46:14 +0300 Subject: SL-18388 Searchable debug settings UI --- indra/llui/llscrolllistctrl.cpp | 10 +- indra/llui/llscrolllistctrl.h | 4 +- indra/newview/app_settings/settings.xml | 11 + indra/newview/llfloatersettingsdebug.cpp | 272 ++++++++++++++++----- indra/newview/llfloatersettingsdebug.h | 21 +- .../default/xui/en/floater_settings_debug.xml | 134 +++++++--- 6 files changed, 343 insertions(+), 109 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 167593bd52..3922a94390 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -1313,14 +1313,14 @@ LLScrollListItem* LLScrollListCtrl::getItemByLabel(const std::string& label, BOO } -BOOL LLScrollListCtrl::selectItemByPrefix(const std::string& target, BOOL case_sensitive) +BOOL LLScrollListCtrl::selectItemByPrefix(const std::string& target, BOOL case_sensitive, S32 column) { - return selectItemByPrefix(utf8str_to_wstring(target), case_sensitive); + return selectItemByPrefix(utf8str_to_wstring(target), case_sensitive, column); } // Selects first enabled item that has a name where the name's first part matched the target string. // Returns false if item not found. -BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sensitive) +BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sensitive, S32 column) { BOOL found = FALSE; @@ -1335,7 +1335,7 @@ BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sen { LLScrollListItem* item = *iter; // Only select enabled items with matching names - LLScrollListCell* cellp = item->getColumn(getSearchColumn()); + LLScrollListCell* cellp = item->getColumn(column == -1 ? getSearchColumn() : column); BOOL select = cellp ? item->getEnabled() && ('\0' == cellp->getValue().asString()[0]) : FALSE; if (select) { @@ -1358,7 +1358,7 @@ BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sen LLScrollListItem* item = *iter; // Only select enabled items with matching names - LLScrollListCell* cellp = item->getColumn(getSearchColumn()); + LLScrollListCell* cellp = item->getColumn(column == -1 ? getSearchColumn() : column); if (!cellp) { continue; diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index 6f7d4768e1..a908dbc968 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -261,8 +261,8 @@ public: virtual LLScrollListItem* addSimpleElement(const std::string& value, EAddPosition pos = ADD_BOTTOM, const LLSD& id = LLSD()); BOOL selectItemByLabel( const std::string& item, BOOL case_sensitive = TRUE, S32 column = 0 ); // FALSE if item not found - BOOL selectItemByPrefix(const std::string& target, BOOL case_sensitive = TRUE); - BOOL selectItemByPrefix(const LLWString& target, BOOL case_sensitive = TRUE); + BOOL selectItemByPrefix(const std::string& target, BOOL case_sensitive = TRUE, S32 column = -1); + BOOL selectItemByPrefix(const LLWString& target, BOOL case_sensitive = TRUE, S32 column = -1); LLScrollListItem* getItemByLabel( const std::string& item, BOOL case_sensitive = TRUE, S32 column = 0 ); const std::string getSelectedItemLabel(S32 column = 0) const; LLSD getSelectedValue(); diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 6861153d43..e9444efd43 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -16876,5 +16876,16 @@ Value + DebugSettingsHideDefault + + Comment + Show non-default settings only in Debug Settings list + Persist + 0 + Type + Boolean + Value + 0 + diff --git a/indra/newview/llfloatersettingsdebug.cpp b/indra/newview/llfloatersettingsdebug.cpp index 186994c857..25cf8b2bf7 100644 --- a/indra/newview/llfloatersettingsdebug.cpp +++ b/indra/newview/llfloatersettingsdebug.cpp @@ -2,9 +2,9 @@ * @file llfloatersettingsdebug.cpp * @brief floater for debugging internal viewer settings * - * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2022, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -27,8 +27,8 @@ #include "llviewerprecompiledheaders.h" #include "llfloatersettingsdebug.h" #include "llfloater.h" +#include "llfiltereditor.h" #include "lluictrlfactory.h" -//#include "llfirstuse.h" #include "llcombobox.h" #include "llspinctrl.h" #include "llcolorswatch.h" @@ -37,12 +37,11 @@ LLFloaterSettingsDebug::LLFloaterSettingsDebug(const LLSD& key) -: LLFloater(key) +: LLFloater(key), + mSettingList(NULL) { - mCommitCallbackRegistrar.add("SettingSelect", boost::bind(&LLFloaterSettingsDebug::onSettingSelect, this,_1)); mCommitCallbackRegistrar.add("CommitSettings", boost::bind(&LLFloaterSettingsDebug::onCommitSettings, this)); mCommitCallbackRegistrar.add("ClickDefault", boost::bind(&LLFloaterSettingsDebug::onClickDefault, this)); - } LLFloaterSettingsDebug::~LLFloaterSettingsDebug() @@ -50,59 +49,43 @@ LLFloaterSettingsDebug::~LLFloaterSettingsDebug() BOOL LLFloaterSettingsDebug::postBuild() { - LLComboBox* settings_combo = getChild("settings_combo"); + enableResizeCtrls(true, false, true); - struct f : public LLControlGroup::ApplyFunctor - { - LLComboBox* combo; - f(LLComboBox* c) : combo(c) {} - virtual void apply(const std::string& name, LLControlVariable* control) - { - if (!control->isHiddenFromSettingsEditor()) - { - combo->add(name, (void*)control); - } - } - } func(settings_combo); + mComment = getChild("comment_text"); - std::string key = getKey().asString(); - if (key == "all" || key == "base") - { - gSavedSettings.applyToAll(&func); - } - if (key == "all" || key == "account") - { - gSavedPerAccountSettings.applyToAll(&func); - } + getChild("filter_input")->setCommitCallback(boost::bind(&LLFloaterSettingsDebug::setSearchFilter, this, _2)); + + mSettingList = getChild("setting_list"); + mSettingList->setCommitOnSelectionChange(TRUE); + mSettingList->setCommitCallback(boost::bind(&LLFloaterSettingsDebug::onSettingSelect, this)); + + updateList(); + + gSavedSettings.getControl("DebugSettingsHideDefault")->getCommitSignal()->connect(boost::bind(&LLFloaterSettingsDebug::updateList, this, false)); - settings_combo->sortByName(); - settings_combo->updateSelection(); - mComment = getChild("comment_text"); return TRUE; } void LLFloaterSettingsDebug::draw() { - LLComboBox* settings_combo = getChild("settings_combo"); - LLControlVariable* controlp = (LLControlVariable*)settings_combo->getCurrentUserdata(); - updateControl(controlp); + LLScrollListItem* first_selected = mSettingList->getFirstSelected(); + if (first_selected) + { + LLControlVariable* controlp = (LLControlVariable*)first_selected->getUserdata(); + updateControl(controlp); + } LLFloater::draw(); } -//static -void LLFloaterSettingsDebug::onSettingSelect(LLUICtrl* ctrl) -{ - LLComboBox* combo_box = (LLComboBox*)ctrl; - LLControlVariable* controlp = (LLControlVariable*)combo_box->getCurrentUserdata(); - - updateControl(controlp); -} - void LLFloaterSettingsDebug::onCommitSettings() { - LLComboBox* settings_combo = getChild("settings_combo"); - LLControlVariable* controlp = (LLControlVariable*)settings_combo->getCurrentUserdata(); + LLScrollListItem* first_selected = mSettingList->getFirstSelected(); + if (!first_selected) + { + return; + } + LLControlVariable* controlp = (LLControlVariable*)first_selected->getUserdata(); if (!controlp) { @@ -176,19 +159,23 @@ void LLFloaterSettingsDebug::onCommitSettings() default: break; } + updateDefaultColumn(controlp); } // static void LLFloaterSettingsDebug::onClickDefault() { - LLComboBox* settings_combo = getChild("settings_combo"); - LLControlVariable* controlp = (LLControlVariable*)settings_combo->getCurrentUserdata(); - - if (controlp) - { - controlp->resetToDefault(true); - updateControl(controlp); - } + LLScrollListItem* first_selected = mSettingList->getFirstSelected(); + if (first_selected) + { + LLControlVariable* controlp = (LLControlVariable*)first_selected->getUserdata(); + if (controlp) + { + controlp->resetToDefault(true); + updateDefaultColumn(controlp); + updateControl(controlp); + } + } } // we've switched controls, or doing per-frame update, so update spinners, etc. @@ -207,21 +194,19 @@ void LLFloaterSettingsDebug::updateControl(LLControlVariable* controlp) return; } - spinner1->setVisible(FALSE); - spinner2->setVisible(FALSE); - spinner3->setVisible(FALSE); - spinner4->setVisible(FALSE); - color_swatch->setVisible(FALSE); - getChildView("val_text")->setVisible( FALSE); - mComment->setText(LLStringUtil::null); + hideUIControls(); - if (controlp) + if (controlp && !isSettingHidden(controlp)) { eControlType type = controlp->type(); //hide combo box only for non booleans, otherwise this will result in the combo box closing every frame getChildView("boolean_combo")->setVisible( type == TYPE_BOOLEAN); - + getChildView("default_btn")->setVisible(true); + getChildView("setting_name_txt")->setVisible(true); + getChild("setting_name_txt")->setText(controlp->getName()); + getChild("setting_name_txt")->setToolTip(controlp->getName()); + mComment->setVisible(true); mComment->setText(controlp->getComment()); spinner1->setMaxValue(F32_MAX); @@ -479,3 +464,166 @@ void LLFloaterSettingsDebug::updateControl(LLControlVariable* controlp) } } + +void LLFloaterSettingsDebug::updateList(bool skip_selection) +{ + std::string last_selected; + LLScrollListItem* item = mSettingList->getFirstSelected(); + if (item) + { + LLScrollListCell* cell = item->getColumn(1); + if (cell) + { + last_selected = cell->getValue().asString(); + } + } + + mSettingList->deleteAllItems(); + struct f : public LLControlGroup::ApplyFunctor + { + LLScrollListCtrl* setting_list; + LLFloaterSettingsDebug* floater; + std::string selected_setting; + bool skip_selection; + f(LLScrollListCtrl* list, LLFloaterSettingsDebug* floater, std::string setting, bool skip_selection) + : setting_list(list), floater(floater), selected_setting(setting), skip_selection(skip_selection) {} + virtual void apply(const std::string& name, LLControlVariable* control) + { + if (!control->isHiddenFromSettingsEditor() && floater->matchesSearchFilter(name) && !floater->isSettingHidden(control)) + { + LLSD row; + + row["columns"][0]["column"] = "changed_setting"; + row["columns"][0]["value"] = control->isDefault() ? "" : "*"; + + row["columns"][1]["column"] = "setting"; + row["columns"][1]["value"] = name; + + LLScrollListItem* item = setting_list->addElement(row, ADD_BOTTOM, (void*)control); + if (!floater->mSearchFilter.empty() && (selected_setting == name) && !skip_selection) + { + std::string lower_name(name); + LLStringUtil::toLower(lower_name); + if (LLStringUtil::startsWith(lower_name, floater->mSearchFilter)) + { + item->setSelected(true); + } + } + } + } + } func(mSettingList, this, last_selected, skip_selection); + + std::string key = getKey().asString(); + if (key == "all" || key == "base") + { + gSavedSettings.applyToAll(&func); + } + if (key == "all" || key == "account") + { + gSavedPerAccountSettings.applyToAll(&func); + } + + + if (!mSettingList->isEmpty()) + { + if (mSettingList->hasSelectedItem()) + { + mSettingList->scrollToShowSelected(); + } + else if (!mSettingList->hasSelectedItem() && !mSearchFilter.empty() && !skip_selection) + { + if (!mSettingList->selectItemByPrefix(mSearchFilter, false, 1)) + { + mSettingList->selectFirstItem(); + } + mSettingList->scrollToShowSelected(); + } + } + else + { + LLSD row; + + row["columns"][0]["column"] = "changed_setting"; + row["columns"][0]["value"] = ""; + row["columns"][1]["column"] = "setting"; + row["columns"][1]["value"] = "No matching settings."; + + mSettingList->addElement(row); + hideUIControls(); + } +} + +void LLFloaterSettingsDebug::onSettingSelect() +{ + LLScrollListItem* first_selected = mSettingList->getFirstSelected(); + if (first_selected) + { + LLControlVariable* controlp = (LLControlVariable*)first_selected->getUserdata(); + if (controlp) + { + updateControl(controlp); + } + } +} + +void LLFloaterSettingsDebug::setSearchFilter(const std::string& filter) +{ + if(mSearchFilter == filter) + return; + mSearchFilter = filter; + LLStringUtil::toLower(mSearchFilter); + updateList(); +} + +bool LLFloaterSettingsDebug::matchesSearchFilter(std::string setting_name) +{ + // If the search filter is empty, everything passes. + if (mSearchFilter.empty()) return true; + + LLStringUtil::toLower(setting_name); + std::string::size_type match_name = setting_name.find(mSearchFilter); + + return (std::string::npos != match_name); +} + +bool LLFloaterSettingsDebug::isSettingHidden(LLControlVariable* control) +{ + static LLCachedControl hide_default(gSavedSettings, "DebugSettingsHideDefault", false); + return hide_default && control->isDefault(); +} + +void LLFloaterSettingsDebug::updateDefaultColumn(LLControlVariable* control) +{ + if (isSettingHidden(control)) + { + hideUIControls(); + updateList(true); + return; + } + + LLScrollListItem* item = mSettingList->getFirstSelected(); + if (item) + { + LLScrollListCell* cell = item->getColumn(0); + if (cell) + { + std::string is_default = control->isDefault() ? "" : "*"; + cell->setValue(is_default); + } + } +} + +void LLFloaterSettingsDebug::hideUIControls() +{ + getChildView("val_spinner_1")->setVisible(false); + getChildView("val_spinner_2")->setVisible(false); + getChildView("val_spinner_3")->setVisible(false); + getChildView("val_spinner_4")->setVisible(false); + getChildView("val_color_swatch")->setVisible(false); + getChildView("val_text")->setVisible(false); + getChildView("default_btn")->setVisible(false); + getChildView("boolean_combo")->setVisible(false); + getChildView("setting_name_txt")->setVisible(false); + mComment->setVisible(false); +} + diff --git a/indra/newview/llfloatersettingsdebug.h b/indra/newview/llfloatersettingsdebug.h index f07e0557e3..888eaadcbd 100644 --- a/indra/newview/llfloatersettingsdebug.h +++ b/indra/newview/llfloatersettingsdebug.h @@ -2,9 +2,9 @@ * @file llfloatersettingsdebug.h * @brief floater for debugging internal viewer settings * - * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2022, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -30,6 +30,8 @@ #include "llcontrol.h" #include "llfloater.h" +class LLScrollListCtrl; + class LLFloaterSettingsDebug : public LLFloater { @@ -42,18 +44,31 @@ public: void updateControl(LLControlVariable* control); - void onSettingSelect(LLUICtrl* ctrl); void onCommitSettings(); void onClickDefault(); + bool matchesSearchFilter(std::string setting_name); + bool isSettingHidden(LLControlVariable* control); + private: // key - selects which settings to show, one of: // "all", "base", "account", "skin" LLFloaterSettingsDebug(const LLSD& key); virtual ~LLFloaterSettingsDebug(); + + void updateList(bool skip_selection = false); + void onSettingSelect(); + void setSearchFilter(const std::string& filter); + + void updateDefaultColumn(LLControlVariable* control); + void hideUIControls(); + + LLScrollListCtrl* mSettingList; protected: class LLTextEditor* mComment; + + std::string mSearchFilter; }; #endif //LLFLOATERDEBUGSETTINGS_H diff --git a/indra/newview/skins/default/xui/en/floater_settings_debug.xml b/indra/newview/skins/default/xui/en/floater_settings_debug.xml index 3ed2bd7206..e4fda5cd10 100644 --- a/indra/newview/skins/default/xui/en/floater_settings_debug.xml +++ b/indra/newview/skins/default/xui/en/floater_settings_debug.xml @@ -2,41 +2,79 @@ - - - - + reuse_instance="true" + can_resize="true" + min_width="550" + width="570"> + + + + + + + Debug setting name + + @@ -55,21 +93,25 @@ + width="220" > + + -- cgit v1.3 From d0e07c770b978d57210a5403bc42cc48e700ef63 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Sun, 30 Oct 2022 06:56:16 -0400 Subject: Fix checks for empty LLSD maps to use size and not emptyMap which is for creating an empty LLSDMap type. --- indra/llcommon/llerror.cpp | 2 +- indra/llui/llmultislider.cpp | 2 +- indra/llwindow/lldxhardware.cpp | 2 +- indra/newview/llenvironment.cpp | 2 +- indra/newview/llfloatermodelpreview.cpp | 2 +- indra/newview/llimprocessing.cpp | 2 +- indra/newview/llpanelexperiencelog.cpp | 2 +- indra/newview/llpanelobject.cpp | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) (limited to 'indra/llui') diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 919d2dabc4..56fb7c21ca 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -943,7 +943,7 @@ namespace LLError for (a = sets.beginArray(), end = sets.endArray(); a != end; ++a) { const LLSD& entry = *a; - if (entry.isMap() && !entry.emptyMap()) + if (entry.isMap() && entry.size() != 0) { ELevel level = decodeLevel(entry["level"]); diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp index f89064d59a..604d246f12 100644 --- a/indra/llui/llmultislider.cpp +++ b/indra/llui/llmultislider.cpp @@ -92,7 +92,7 @@ LLMultiSlider::LLMultiSlider(const LLMultiSlider::Params& p) mMouseDownSignal(NULL), mMouseUpSignal(NULL) { - mValue.emptyMap(); + mValue = LLSD::emptyMap(); mCurSlider = LLStringUtil::null; if (mOrientation == HORIZONTAL) diff --git a/indra/llwindow/lldxhardware.cpp b/indra/llwindow/lldxhardware.cpp index 81e938edbe..391a377280 100644 --- a/indra/llwindow/lldxhardware.cpp +++ b/indra/llwindow/lldxhardware.cpp @@ -1098,7 +1098,7 @@ LLSD LLDXHardware::getDisplayInfo() } LCleanup: - if (ret.emptyMap()) + if (!ret.isMap() || (ret.size() == 0)) { LL_INFOS() << "Failed to get data, cleaning up" << LL_ENDL; } diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index 1300cf3658..a01410e521 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -3086,7 +3086,7 @@ bool LLEnvironment::loadFromSettings() LL_INFOS("ENVIRONMENT") << "Unable to open previous session environment file " << user_filepath << LL_ENDL; } - if (!env_data.isMap() || env_data.emptyMap()) + if (!env_data.isMap() || (env_data.size() == 0)) { LL_DEBUGS("ENVIRONMENT") << "Empty map loaded from: " << user_filepath << LL_ENDL; return false; diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 66a245b779..6f8f73bca0 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -1740,7 +1740,7 @@ void LLFloaterModelPreview::toggleCalculateButton(bool visible) childSetTextArg("download_weight", "[ST]", tbd); childSetTextArg("server_weight", "[SIM]", tbd); childSetTextArg("physics_weight", "[PH]", tbd); - if (!mModelPhysicsFee.isMap() || mModelPhysicsFee.emptyMap()) + if (!mModelPhysicsFee.isMap() || (mModelPhysicsFee.size() == 0)) { childSetTextArg("upload_fee", "[FEE]", tbd); } diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp index 0524313a5c..57c0c7388e 100644 --- a/indra/newview/llimprocessing.cpp +++ b/indra/newview/llimprocessing.cpp @@ -1561,7 +1561,7 @@ void LLIMProcessing::requestOfflineMessagesCoro(std::string url) return; } - if (messages.emptyArray()) + if (messages.size() == 0) { // Nothing to process return; diff --git a/indra/newview/llpanelexperiencelog.cpp b/indra/newview/llpanelexperiencelog.cpp index 44b4728df7..e5c637938f 100644 --- a/indra/newview/llpanelexperiencelog.cpp +++ b/indra/newview/llpanelexperiencelog.cpp @@ -112,7 +112,7 @@ void LLPanelExperienceLog::refresh() int items = 0; bool moreItems = false; LLSD events_to_save = events; - if (!events.emptyMap()) + if (events.isMap() && events.size() != 0) { LLSD::map_const_iterator day = events.endMap(); do diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index 0bfc1297d3..c04b402610 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -2119,7 +2119,7 @@ bool LLPanelObject::menuEnableItem(const LLSD& userdata) } else if (command == "params_paste") { - return mClipboardParams.isMap() && !mClipboardParams.emptyMap(); + return mClipboardParams.isMap() && (mClipboardParams.size() != 0); } // copy options else if (command == "psr_copy") -- cgit v1.3 From 8669f3f4c207e913bc2f6e39438d92d76b3aa1c4 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Sun, 30 Oct 2022 06:59:54 -0400 Subject: Fix line editors deselecting when pressing capslock --- indra/llui/lllineeditor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 33037b5001..4c7dd034fc 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -1567,7 +1567,7 @@ BOOL LLLineEditor::handleKeyHere(KEY key, MASK mask ) KEY_SHIFT != key && KEY_CONTROL != key && KEY_ALT != key && - KEY_CAPSLOCK ) + KEY_CAPSLOCK != key) { deselect(); } -- cgit v1.3 From e231b6d8d3bf3d65d94054e6259e5d33d24e5425 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 22 Nov 2022 01:43:14 +0200 Subject: SL-18689 Crash at LLTabContainer::selectNextTab() FPE_NOOP at "idx = (idx + 1 ) % (S32)mTabList.size();" --- indra/llui/lltabcontainer.cpp | 5 +++++ indra/newview/llstartup.cpp | 2 -- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index 0aa7a2d217..8c841540a5 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -1442,6 +1442,11 @@ void LLTabContainer::selectLastTab() void LLTabContainer::selectNextTab() { + if (mTabList.size() == 0) + { + return; + } + BOOL tab_has_focus = FALSE; if (mCurrentTabIdx >= 0 && mTabList[mCurrentTabIdx]->mButton->hasFocus()) { diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 054e9530d4..f2d73a4043 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -272,12 +272,10 @@ void show_first_run_dialog(); bool first_run_dialog_callback(const LLSD& notification, const LLSD& response); void set_startup_status(const F32 frac, const std::string& string, const std::string& msg); bool login_alert_status(const LLSD& notification, const LLSD& response); -void login_packet_failed(void**, S32 result); void use_circuit_callback(void**, S32 result); void register_viewer_callbacks(LLMessageSystem* msg); void asset_callback_nothing(const LLUUID&, LLAssetType::EType, void*, S32); bool callback_choose_gender(const LLSD& notification, const LLSD& response); -void init_start_screen(S32 location_id); void release_start_screen(); void reset_login(); LLSD transform_cert_args(LLPointer cert); -- cgit v1.3