From a106d6cf78833a3e24f8d478807f6363e4af5652 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 29 Mar 2021 21:30:40 +0300 Subject: SL-13182 Turn on openmp paralellization on Windows --- indra/llui/llnotifications.cpp | 5 ----- indra/llui/llnotifications.h | 4 ---- 2 files changed, 9 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 06ec648178..34f25ad9fa 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -1784,11 +1784,6 @@ LLNotificationPtr LLNotifications::find(LLUUID uuid) } } -void LLNotifications::forEachNotification(NotificationProcess process) -{ - std::for_each(mItems.begin(), mItems.end(), process); -} - std::string LLNotifications::getGlobalString(const std::string& key) const { GlobalStringMap::const_iterator it = mGlobalStrings.find(key); diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index 2f4578da17..184a0ad83d 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -916,10 +916,6 @@ public: void update(const LLNotificationPtr pNotif); LLNotificationPtr find(LLUUID uuid); - - typedef boost::function NotificationProcess; - - void forEachNotification(NotificationProcess process); // This is all stuff for managing the templates // take your template out -- cgit v1.3 From c2711f2d763cfbf96d8db48b0809dd7a6e65a73e Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 31 Mar 2021 23:46:08 +0300 Subject: Revert "SL-13182 Turn on openmp paralellization on Windows" This reverts commit a106d6cf78833a3e24f8d478807f6363e4af5652. --- indra/cmake/00-Common.cmake | 4 ++-- indra/llui/llnotifications.cpp | 5 +++++ indra/llui/llnotifications.h | 4 ++++ 3 files changed, 11 insertions(+), 2 deletions(-) (limited to 'indra/llui') diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index 289d65e975..8aea50e02b 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -72,10 +72,10 @@ if (WINDOWS) endif() set(CMAKE_CXX_FLAGS_RELWITHDEBINFO - "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /openmp /Zo" + "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Zo" CACHE STRING "C++ compiler release-with-debug options" FORCE) set(CMAKE_CXX_FLAGS_RELEASE - "${CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /openmp /Zo" + "${CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /Zo" CACHE STRING "C++ compiler release options" FORCE) # zlib has assembly-language object files incompatible with SAFESEH set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LARGEADDRESSAWARE /SAFESEH:NO /NODEFAULTLIB:LIBCMT /IGNORE:4099") diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 34f25ad9fa..06ec648178 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -1784,6 +1784,11 @@ LLNotificationPtr LLNotifications::find(LLUUID uuid) } } +void LLNotifications::forEachNotification(NotificationProcess process) +{ + std::for_each(mItems.begin(), mItems.end(), process); +} + std::string LLNotifications::getGlobalString(const std::string& key) const { GlobalStringMap::const_iterator it = mGlobalStrings.find(key); diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index 184a0ad83d..2f4578da17 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -916,6 +916,10 @@ public: void update(const LLNotificationPtr pNotif); LLNotificationPtr find(LLUUID uuid); + + typedef boost::function NotificationProcess; + + void forEachNotification(NotificationProcess process); // This is all stuff for managing the templates // take your template out -- cgit v1.3 From 7ddbf118f5d1fde24c10b93432209fbe44d91345 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 24 Mar 2021 01:53:45 +0200 Subject: SL-13182 Split buildNewViews over frames --- indra/llui/llfolderviewitem.cpp | 14 ++- indra/llui/llfolderviewitem.h | 15 ++- indra/newview/llconversationview.cpp | 1 + indra/newview/llfolderviewmodelinventory.cpp | 2 +- indra/newview/llinventorybridge.cpp | 19 ++- indra/newview/llinventorypanel.cpp | 182 ++++++++++++++++++++++++--- indra/newview/llinventorypanel.h | 17 ++- indra/newview/llsidepanelinventory.cpp | 7 +- 8 files changed, 219 insertions(+), 38 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp index 1c6c7b1b35..f4a6053b57 100644 --- a/indra/llui/llfolderviewitem.cpp +++ b/indra/llui/llfolderviewitem.cpp @@ -132,7 +132,6 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p) mCutGeneration(0), mLabelStyle( LLFontGL::NORMAL ), mHasVisibleChildren(FALSE), - mIsFolderComplete(true), mLocalIndentation(p.folder_indentation), mIndentation(0), mItemHeight(p.item_height), @@ -1002,11 +1001,11 @@ LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ): mCurHeight(0.f), mTargetHeight(0.f), mAutoOpenCountdown(0.f), + mIsFolderComplete(false), // folder might have children that are not loaded yet. + mAreChildrenInited(false), // folder might have children that are not built yet. mLastArrangeGeneration( -1 ), mLastCalculatedWidth(0) { - // folder might have children that are not loaded yet. Mark it as incomplete until chance to check it. - mIsFolderComplete = false; } void LLFolderViewFolder::updateLabelRotation() @@ -1062,13 +1061,16 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height ) { // Sort before laying out contents // Note that we sort from the root (CHUI-849) - getRoot()->getFolderViewModel()->sort(this); + if (mAreChildrenInited) + { + getRoot()->getFolderViewModel()->sort(this); + } LL_RECORD_BLOCK_TIME(FTM_ARRANGE); // evaluate mHasVisibleChildren mHasVisibleChildren = false; - if (getViewModelItem()->descendantsPassedFilter()) + if (mAreChildrenInited && getViewModelItem()->descendantsPassedFilter()) { // We have to verify that there's at least one child that's not filtered out bool found = false; @@ -1094,7 +1096,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height ) mHasVisibleChildren = found; } - if (!mIsFolderComplete) + if (!mIsFolderComplete && mAreChildrenInited) { mIsFolderComplete = getFolderViewModel()->isFolderComplete(this); } diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h index da09d139e9..9df58d4478 100644 --- a/indra/llui/llfolderviewitem.h +++ b/indra/llui/llfolderviewitem.h @@ -116,7 +116,6 @@ protected: F32 mControlLabelRotation; LLFolderView* mRoot; bool mHasVisibleChildren, - mIsFolderComplete, // indicates that some children were not loaded/added yet mIsCurSelection, mDragAndDropTarget, mIsMouseOverTitle, @@ -219,7 +218,10 @@ public: BOOL hasVisibleChildren() { return mHasVisibleChildren; } // true if object can't have children - BOOL isFolderComplete() { return mIsFolderComplete; } + virtual bool isFolderComplete() { return true; } + // true if object can't have children + virtual bool areChildrenInited() { return true; } + virtual void setChildrenInited(bool inited) { } // Call through to the viewed object and return true if it can be // removed. Returns true if it's removed. @@ -334,6 +336,8 @@ protected: S32 mLastArrangeGeneration; S32 mLastCalculatedWidth; bool mNeedsSort; + bool mIsFolderComplete; // indicates that some children were not loaded/added yet + bool mAreChildrenInited; // indicates that no children were initialized public: typedef enum e_recurse_type @@ -385,6 +389,13 @@ public: // destroys this folder, and all children virtual void destroyView(); + // whether known children are fully loaded (arrange sets to true) + virtual bool isFolderComplete() { return mIsFolderComplete; } + + // whether known children are fully built + virtual bool areChildrenInited() { return mAreChildrenInited; } + virtual void setChildrenInited(bool inited) { mAreChildrenInited = inited; } + // extractItem() removes the specified item from the folder, but // doesn't delete it. virtual void extractItem( LLFolderViewItem* item ); diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp index 093e772abe..46a0a0b37a 100644 --- a/indra/newview/llconversationview.cpp +++ b/indra/newview/llconversationview.cpp @@ -88,6 +88,7 @@ LLConversationViewSession::LLConversationViewSession(const LLConversationViewSes mFlashStarted(false) { mFlashTimer = new LLFlashTimer(); + mAreChildrenInited = true; // inventory only } LLConversationViewSession::~LLConversationViewSession() diff --git a/indra/newview/llfolderviewmodelinventory.cpp b/indra/newview/llfolderviewmodelinventory.cpp index d40a7234e2..117e2534cb 100644 --- a/indra/newview/llfolderviewmodelinventory.cpp +++ b/indra/newview/llfolderviewmodelinventory.cpp @@ -66,7 +66,7 @@ void LLFolderViewModelInventory::sort( LLFolderViewFolder* folder ) { LL_RECORD_BLOCK_TIME(FTM_INVENTORY_SORT); - if (!needsSort(folder->getViewModelItem())) return; + if (!folder->areChildrenInited() || !needsSort(folder->getViewModelItem())) return; LLFolderViewModelItemInventory* modelp = static_cast(folder->getViewModelItem()); if (modelp->getUUID().isNull()) return; diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index d35d8456be..15c3f10436 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -3437,9 +3437,22 @@ void LLFolderBridge::copyOutfitToClipboard() void LLFolderBridge::openItem() { LL_DEBUGS() << "LLFolderBridge::openItem()" << LL_ENDL; - LLInventoryModel* model = getInventoryModel(); - if(!model) return; - if(mUUID.isNull()) return; + + LLInventoryPanel* panel = mInventoryPanel.get(); + if (!panel) + { + return; + } + LLInventoryModel* model = getInventoryModel(); + if (!model) + { + return; + } + if (mUUID.isNull()) + { + return; + } + panel->onFolderOpening(mUUID); bool fetching_inventory = model->fetchDescendentsOf(mUUID); // Only change folder type if we have the folder contents. if (!fetching_inventory) diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 74d9e895c2..09a94c1c09 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -282,17 +282,18 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params) mCompletionObserver = new LLInvPanelComplObserver(boost::bind(&LLInventoryPanel::onItemsCompletion, this)); mInventory->addObserver(mCompletionObserver); - if (mBuildViewsOnInit) + if (mBuildViewsOnInit && mViewsInitialized == VIEWS_UNINITIALIZED) { // Build view of inventory if we need default full hierarchy and inventory is ready, otherwise do in onIdle. // Initializing views takes a while so always do it onIdle if viewer already loaded. - if (mInventory->isInventoryUsable() - && mViewsInitialized == VIEWS_UNINITIALIZED + if (mInventory->isInventoryUsable() && LLStartUp::getStartupState() <= STATE_WEARABLES_WAIT) { - initializeViews(); + // Usually this happens on login, so we have less time constraits, but too long and we can cause a disconnect + const F64 max_time = 20.f; + initializeViews(max_time); } - else if (mViewsInitialized != VIEWS_INITIALIZING) + else { mViewsInitialized = VIEWS_INITIALIZING; gIdleCallbacks.addFunction(onIdle, (void*)this); @@ -497,6 +498,23 @@ void LLInventoryPanel::itemChanged(const LLUUID& item_id, U32 mask, const LLInve view_folder = dynamic_cast(view_item); } + // if folder is not fully initialized (likely due to delayed load on idle) + // and we are not rebuilding, try updating children + if (view_folder + && !view_folder->areChildrenInited() + && ( (mask & LLInventoryObserver::REBUILD) == 0)) + { + LLInventoryObject const* objectp = mInventory->getObject(item_id); + if (objectp) + { + // Time is low since we only need the item itself and children views. + // Any value bigger than zero will do to init children, everything else + // will be processed on idle. + const F64 max_time = 0.0001f; + view_item = buildNewViewsWithTimeLimit(item_id, objectp, view_item, max_time); + } + } + ////////////////////////////// // LABEL Operation // Empty out the display name for relabel. @@ -536,8 +554,13 @@ void LLInventoryPanel::itemChanged(const LLUUID& item_id, U32 mask, const LLInve LLInventoryObject const* objectp = mInventory->getObject(item_id); if (objectp) { + // Time is low since we only need the item itself and children views. + // Any value bigger than zero will do to init children, everything else + // will be processed on idle. + const F64 max_time = 0.0001f; + // providing NULL directly avoids unnessesary getItemByID calls - view_item = buildNewViews(item_id, objectp, NULL); + view_item = buildNewViewsWithTimeLimit(item_id, objectp, NULL, max_time); } else { @@ -589,8 +612,13 @@ void LLInventoryPanel::itemChanged(const LLUUID& item_id, U32 mask, const LLInve LLInventoryObject const* objectp = mInventory->getObject(item_id); if (objectp) { + // Time is low since we only need the item itself and children views. + // Any value bigger than zero will do to init children, everything else + // will be processed on idle. + const F64 max_time = 0.0001f; + // providing NULL directly avoids unnessesary getItemByID calls - buildNewViews(item_id, objectp, NULL); + buildNewViewsWithTimeLimit(item_id, objectp, NULL, max_time); } // Select any newly created object that has the auto rename at top of folder root set. @@ -742,12 +770,12 @@ void LLInventoryPanel::onIdle(void *userdata) return; LLInventoryPanel *self = (LLInventoryPanel*)userdata; - // Inventory just initialized, do complete build - if (self->mViewsInitialized != VIEWS_INITIALIZED) + if (self->mViewsInitialized <= VIEWS_INITIALIZING) { - self->initializeViews(); + const F64 max_time = 0.001f; // 1 ms, in this case we need only root folders + self->initializeViews(max_time); // Shedules LLInventoryPanel::idle() } - if (self->mViewsInitialized == VIEWS_INITIALIZED) + if (self->mViewsInitialized >= VIEWS_BUILDING) { gIdleCallbacks.deleteFunction(onIdle, (void*)self); } @@ -782,6 +810,49 @@ void LLInventoryPanel::idle(void* user_data) } + bool in_visible_chain = panel->isInVisibleChain(); + + if (!panel->mBuildViewsQueue.empty()) + { + const F64 max_time = in_visible_chain ? 0.006f : 0.001f; // 6 ms + F64 curent_time = LLTimer::getTotalSeconds(); + panel->mBuildViewsEndTime = curent_time + max_time; + + // things added last are closer to root thus of higher priority + std::deque priority_list; + priority_list.swap(panel->mBuildViewsQueue); + + while (curent_time < panel->mBuildViewsEndTime + && !priority_list.empty()) + { + LLUUID item_id = priority_list.back(); + priority_list.pop_back(); + + LLInventoryObject const* objectp = panel->mInventory->getObject(item_id); + if (objectp && panel->typedViewsFilter(item_id, objectp)) + { + LLFolderViewItem* folder_view_item = panel->getItemByID(item_id); + if (!folder_view_item || !folder_view_item->areChildrenInited()) + { + const LLUUID &parent_id = objectp->getParentUUID(); + LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)panel->getItemByID(parent_id); + panel->buildViewsTree(item_id, parent_id, objectp, folder_view_item, parent_folder); + } + } + curent_time = LLTimer::getTotalSeconds(); + } + while (!priority_list.empty()) + { + // items in priority_list are of higher priority + panel->mBuildViewsQueue.push_back(priority_list.front()); + priority_list.pop_front(); + } + if (panel->mBuildViewsQueue.empty()) + { + panel->mViewsInitialized = VIEWS_INITIALIZED; + } + } + // Take into account the fact that the root folder might be invalidated if (panel->mFolderRoot.get()) { @@ -812,10 +883,16 @@ void LLInventoryPanel::idle(void* user_data) } -void LLInventoryPanel::initializeViews() +void LLInventoryPanel::initializeViews(F64 max_time) { if (!gInventory.isInventoryUsable()) return; + mViewsInitialized = VIEWS_BUILDING; + + F64 curent_time = LLTimer::getTotalSeconds(); + mBuildViewsEndTime = curent_time + max_time; + + // init everything LLUUID root_id = getRootFolderID(); if (root_id.notNull()) { @@ -823,14 +900,18 @@ void LLInventoryPanel::initializeViews() } else { - // Default case: always add "My Inventory" first, "Library" second + // Default case: always add "My Inventory" root first, "Library" root second + // If we run out of time, this still should create root folders buildNewViews(gInventory.getRootFolderID()); // My Inventory buildNewViews(gInventory.getLibraryRootFolderID()); // Library } - gIdleCallbacks.addFunction(idle, this); + if (mBuildViewsQueue.empty()) + { + mViewsInitialized = VIEWS_INITIALIZED; + } - mViewsInitialized = VIEWS_INITIALIZED; + gIdleCallbacks.addFunction(idle, this); openStartFolderOrMyInventory(); @@ -930,6 +1011,12 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id, LLInventoryO return buildViewsTree(id, parent_id, objectp, folder_view_item, parent_folder); } +LLFolderViewItem* LLInventoryPanel::buildNewViewsWithTimeLimit(const LLUUID& id, LLInventoryObject const* objectp, LLFolderViewItem *folder_view_item, F64 max_time) +{ + mBuildViewsEndTime = LLTimer::getTotalSeconds() + max_time; + return buildNewViews(id, objectp, folder_view_item); +} + LLFolderViewItem* LLInventoryPanel::buildViewsTree(const LLUUID& id, const LLUUID& parent_id, LLInventoryObject const* objectp, @@ -1035,9 +1122,33 @@ LLFolderViewItem* LLInventoryPanel::buildViewsTree(const LLUUID& id, } } + bool create_children = folder_view_item && objectp->getType() == LLAssetType::AT_CATEGORY; + + if (create_children) + { + F64 curent_time = LLTimer::getTotalSeconds(); + // If function is out of time, we want to shedule it into mBuildViewsQueue + // If we have time, no matter how little, create views for all children + // + // This creates children in 'bulk' to make sure folder has either + // 'empty and incomplete' or 'complete' states with nothing in between. + // Folders are marked as mIsFolderComplete == false by default, + // later arrange() will update mIsFolderComplete by child count + if (mBuildViewsEndTime < curent_time) + { + create_children = false; + // run it again for the sake of creating children + mBuildViewsQueue.push_back(id); + } + else if (folder_view_item) + { + folder_view_item->setChildrenInited(true); + } + } + // If this is a folder, add the children of the folder and recursively add any // child folders. - if (folder_view_item && objectp->getType() == LLAssetType::AT_CATEGORY) + if (create_children) { LLViewerInventoryCategory::cat_array_t* categories; LLViewerInventoryItem::item_array_t* items; @@ -1053,7 +1164,7 @@ LLFolderViewItem* LLInventoryPanel::buildViewsTree(const LLUUID& id, ++cat_iter) { const LLViewerInventoryCategory* cat = (*cat_iter); - if (typedViewsFilter(cat->getUUID(), cat)) + if (typedViewsFilter(cat->getUUID(), cat)) { if (has_folders) { @@ -1077,17 +1188,16 @@ LLFolderViewItem* LLInventoryPanel::buildViewsTree(const LLUUID& id, item_iter != items->end(); ++item_iter) { + // At the moment we have to build folder's items in bulk and ignore mBuildViewsEndTime const LLViewerInventoryItem* item = (*item_iter); if (typedViewsFilter(item->getUUID(), item)) { - // This can be optimized: we don't need to call getItemByID() // each time, especially since content is growing, we can just // iter over copy of mItemMap in some way LLFolderViewItem* view_itemp = getItemByID(item->getUUID()); buildViewsTree(item->getUUID(), id, item, view_itemp, parentp); } - } } mInventory->unlockDirectDescendentArrays(id); @@ -1200,6 +1310,18 @@ void LLInventoryPanel::onFocusReceived() LLPanel::onFocusReceived(); } +void LLInventoryPanel::onFolderOpening(const LLUUID &id) +{ + LLFolderViewItem* folder = getItemByID(id); + if (folder && !folder->areChildrenInited()) + { + // Last item in list will be processed first. + // This might result in dupplicates in list, but it + // isn't critical, views won't be created twice + mBuildViewsQueue.push_back(id); + } +} + bool LLInventoryPanel::addBadge(LLBadge * badge) { bool badge_added = false; @@ -1221,7 +1343,7 @@ void LLInventoryPanel::openAllFolders() void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus) { // Don't select objects in COF (e.g. to prevent refocus when items are worn). - const LLInventoryObject *obj = gInventory.getObject(obj_id); + const LLInventoryObject *obj = mInventory->getObject(obj_id); if (obj && obj->getParentUUID() == LLAppearanceMgr::instance().getCOF()) { return; @@ -1257,6 +1379,12 @@ void LLInventoryPanel::onSelectionChange(const std::deque& it if (view_model) { LLUUID id = view_model->getUUID(); + if (!(*it)->areChildrenInited()) + { + const F64 max_time = 0.0001f; + mBuildViewsEndTime = LLTimer::getTotalSeconds() + max_time; + buildNewViews(id); + } LLViewerInventoryItem* inv_item = mInventory->getItem(id); if (inv_item && !inv_item->isFinished()) @@ -1714,6 +1842,20 @@ LLFolderViewFolder* LLInventoryPanel::getFolderByID(const LLUUID& id) void LLInventoryPanel::setSelectionByID( const LLUUID& obj_id, BOOL take_keyboard_focus ) { LLFolderViewItem* itemp = getItemByID(obj_id); + + if (itemp && !itemp->areChildrenInited()) + { + LLInventoryObject const* objectp = mInventory->getObject(obj_id); + if (objectp) + { + // Time is low since we only need the item itself and children views. + // Any value bigger than zero will do to init children, everything else + // will be processed on idle. + const F64 max_time = 0.0001f; + buildNewViewsWithTimeLimit(obj_id, objectp, itemp, max_time); + } + } + if(itemp && itemp->getViewModelItem()) { itemp->arrangeAndSet(TRUE, take_keyboard_focus); diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index ad6010f09c..06547ebf0e 100644 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -171,6 +171,7 @@ public: // LLUICtrl methods /*virtual*/ void onFocusLost(); /*virtual*/ void onFocusReceived(); + void onFolderOpening(const LLUUID &id); // LLBadgeHolder methods bool addBadge(LLBadge * badge); @@ -317,12 +318,9 @@ private: //-------------------------------------------------------------------- public: void addHideFolderType(LLFolderType::EType folder_type); - -public: - bool getViewsInitialized() const { return mViewsInitialized == VIEWS_INITIALIZED; } protected: // Builds the UI. Call this once the inventory is usable. - void initializeViews(); + void initializeViews(F64 max_time); // Specific inventory colors static bool sColorSetInitialized; @@ -330,13 +328,19 @@ protected: static LLUIColor sDefaultHighlightColor; static LLUIColor sLibraryColor; static LLUIColor sLinkColor; - + + // All buildNewViews() expect time limit mBuildViewsEndTime to be set LLFolderViewItem* buildNewViews(const LLUUID& id); LLFolderViewItem* buildNewViews(const LLUUID& id, LLInventoryObject const* objectp); LLFolderViewItem* buildNewViews(const LLUUID& id, LLInventoryObject const* objectp, LLFolderViewItem *target_view); + + LLFolderViewItem* buildNewViewsWithTimeLimit(const LLUUID& id, + LLInventoryObject const* objectp, + LLFolderViewItem *folder_view_item, + F64 max_time); // if certain types are not allowed, no reason to create views virtual bool typedViewsFilter(const LLUUID& id, LLInventoryObject const* objectp) { return true; } @@ -359,11 +363,14 @@ private: { VIEWS_UNINITIALIZED = 0, VIEWS_INITIALIZING, + VIEWS_BUILDING, // Root folder exists VIEWS_INITIALIZED, } EViewsInitializationState; bool mBuildViewsOnInit; EViewsInitializationState mViewsInitialized; // Whether views have been generated + F64 mBuildViewsEndTime; // Stop building views past this timestamp + std::deque mBuildViewsQueue; }; diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp index ea7e649792..a5dcdc41ed 100644 --- a/indra/newview/llsidepanelinventory.cpp +++ b/indra/newview/llsidepanelinventory.cpp @@ -653,7 +653,12 @@ bool LLSidepanelInventory::canWearSelected() LLInventoryItem *LLSidepanelInventory::getSelectedItem() { - LLFolderViewItem* current_item = mPanelMainInventory->getActivePanel()->getRootFolder()->getCurSelectedItem(); + LLFolderView* root = mPanelMainInventory->getActivePanel()->getRootFolder(); + if (!root) + { + return NULL; + } + LLFolderViewItem* current_item = root->getCurSelectedItem(); if (!current_item) { -- cgit v1.3 From 5e134b4732e5224b1a5da929a4b12ac63ec120b4 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 9 Apr 2021 17:19:43 +0300 Subject: SL-13182 Fix root folder's state --- indra/llui/llfolderview.cpp | 2 ++ indra/newview/llinventorypanel.cpp | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp index 0c1dcc301b..bcca4d78a0 100644 --- a/indra/llui/llfolderview.cpp +++ b/indra/llui/llfolderview.cpp @@ -257,6 +257,8 @@ LLFolderView::LLFolderView(const Params& p) mPopupMenuHandle = menu->getHandle(); mViewModelItem->openItem(); + + mAreChildrenInited = true; // root folder is a special case due to not being loaded normally, assume that it's inited. } // Destroys the object diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 1998fca89d..f181e30d93 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -256,7 +256,6 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params) // Determine the root folder in case specified, and // build the views starting with that folder. LLFolderView* folder_view = createFolderRoot(root_id); - folder_view->setChildrenInited(true); // assume that root folder's children are loaded, most of the time we do not load it the normal way mFolderRoot = folder_view->getHandle(); addItemID(root_id, mFolderRoot.get()); @@ -1103,7 +1102,6 @@ LLFolderViewItem* LLInventoryPanel::buildViewsTree(const LLUUID& id, if (create_root) { folder_view_item->setOpen(TRUE); - parent_folder->setChildrenInited(true); } } } -- cgit v1.3 From 9a1688322ab739f8838611d1b9e37d33adc07dfb Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Thu, 13 May 2021 17:51:24 +0300 Subject: SL-15195 The notification in chat history is multiplied after relogging --- indra/llui/llnotifications.cpp | 14 ++++++++++++++ indra/llui/llnotifications.h | 6 ++++++ indra/newview/llbrowsernotification.cpp | 2 +- indra/newview/llchiclet.h | 1 + indra/newview/llimhandler.cpp | 2 +- indra/newview/llnotificationalerthandler.cpp | 4 ++-- indra/newview/llnotificationgrouphandler.cpp | 2 +- indra/newview/llnotificationhandler.h | 22 +++++++++++----------- indra/newview/llnotificationhinthandler.cpp | 2 +- indra/newview/llnotificationofferhandler.cpp | 2 +- indra/newview/llnotificationscripthandler.cpp | 4 ++-- indra/newview/llnotificationtiphandler.cpp | 2 +- indra/newview/llpersistentnotificationstorage.cpp | 2 +- 13 files changed, 43 insertions(+), 22 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 06ec648178..c9e5c6653b 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -1699,6 +1699,20 @@ void LLNotifications::add(const LLNotificationPtr pNotif) updateItem(LLSD().with("sigtype", "add").with("id", pNotif->id()), pNotif); } +void LLNotifications::load(const LLNotificationPtr pNotif) +{ + if (pNotif == NULL) return; + + // first see if we already have it -- if so, that's a problem + LLNotificationSet::iterator it=mItems.find(pNotif); + if (it != mItems.end()) + { + LL_ERRS() << "Notification loaded a second time to the master notification channel." << LL_ENDL; + } + + updateItem(LLSD().with("sigtype", "load").with("id", pNotif->id()), pNotif); +} + void LLNotifications::cancel(LLNotificationPtr pNotif) { if (pNotif == NULL || pNotif->isCancelled()) return; diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index 2f4578da17..3ee48d1401 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -910,6 +910,7 @@ public: LLNotificationPtr add(const LLNotification::Params& p); void add(const LLNotificationPtr pNotif); + void load(const LLNotificationPtr pNotif); void cancel(LLNotificationPtr pNotif); void cancelByName(const std::string& name); void cancelByOwner(const LLUUID ownerId); @@ -1106,6 +1107,11 @@ private: mHistory.push_back(p); } + void onLoad(LLNotificationPtr p) + { + mHistory.push_back(p); + } + std::vector mHistory; }; diff --git a/indra/newview/llbrowsernotification.cpp b/indra/newview/llbrowsernotification.cpp index 0460bff1b4..7614624306 100644 --- a/indra/newview/llbrowsernotification.cpp +++ b/indra/newview/llbrowsernotification.cpp @@ -40,7 +40,7 @@ LLBrowserNotification::LLBrowserNotification() { } -bool LLBrowserNotification::processNotification(const LLNotificationPtr& notification) +bool LLBrowserNotification::processNotification(const LLNotificationPtr& notification, bool should_log) { LLUUID media_id = notification->getPayload()["media_id"].asUUID(); LLMediaCtrl* media_instance = LLMediaCtrl::getInstance(media_id); diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h index 9201c6bc00..aceedda07e 100644 --- a/indra/newview/llchiclet.h +++ b/indra/newview/llchiclet.h @@ -546,6 +546,7 @@ protected: static bool filterNotification(LLNotificationPtr notify); // connect counter updaters to the corresponding signals /*virtual*/ void onAdd(LLNotificationPtr p) { mChiclet->setCounter(++mChiclet->mUreadSystemNotifications); } + /*virtual*/ void onLoad(LLNotificationPtr p) { mChiclet->setCounter(++mChiclet->mUreadSystemNotifications); } /*virtual*/ void onDelete(LLNotificationPtr p) { mChiclet->setCounter(--mChiclet->mUreadSystemNotifications); } LLNotificationChiclet* const mChiclet; diff --git a/indra/newview/llimhandler.cpp b/indra/newview/llimhandler.cpp index c2b29f36e8..0fa3dc1110 100644 --- a/indra/newview/llimhandler.cpp +++ b/indra/newview/llimhandler.cpp @@ -60,7 +60,7 @@ void LLIMHandler::initChannel() } //-------------------------------------------------------------------------- -bool LLIMHandler::processNotification(const LLNotificationPtr& notification) +bool LLIMHandler::processNotification(const LLNotificationPtr& notification, bool should_log) { if(notification->isDND()) { diff --git a/indra/newview/llnotificationalerthandler.cpp b/indra/newview/llnotificationalerthandler.cpp index 58a9b01a45..90b9cdc133 100644 --- a/indra/newview/llnotificationalerthandler.cpp +++ b/indra/newview/llnotificationalerthandler.cpp @@ -69,7 +69,7 @@ void LLAlertHandler::initChannel() } //-------------------------------------------------------------------------- -bool LLAlertHandler::processNotification(const LLNotificationPtr& notification) +bool LLAlertHandler::processNotification(const LLNotificationPtr& notification, bool should_log) { if(mChannel.isDead()) { @@ -131,7 +131,7 @@ LLViewerAlertHandler::LLViewerAlertHandler(const std::string& name, const std::s { } -bool LLViewerAlertHandler::processNotification(const LLNotificationPtr& p) +bool LLViewerAlertHandler::processNotification(const LLNotificationPtr& p, bool should_log) { if (gHeadlessClient) { diff --git a/indra/newview/llnotificationgrouphandler.cpp b/indra/newview/llnotificationgrouphandler.cpp index 8fef102cf8..f87ebf219b 100644 --- a/indra/newview/llnotificationgrouphandler.cpp +++ b/indra/newview/llnotificationgrouphandler.cpp @@ -62,7 +62,7 @@ void LLGroupHandler::initChannel() } //-------------------------------------------------------------------------- -bool LLGroupHandler::processNotification(const LLNotificationPtr& notification) +bool LLGroupHandler::processNotification(const LLNotificationPtr& notification, bool should_log) { if(mChannel.isDead()) { diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h index ef4aced2c7..ddc957c941 100644 --- a/indra/newview/llnotificationhandler.h +++ b/indra/newview/llnotificationhandler.h @@ -96,10 +96,10 @@ public: // base interface functions virtual void onAdd(LLNotificationPtr p) { processNotification(p); } virtual void onChange(LLNotificationPtr p) { processNotification(p); } - virtual void onLoad(LLNotificationPtr p) { processNotification(p); } + virtual void onLoad(LLNotificationPtr p) { processNotification(p, false); } virtual void onDelete(LLNotificationPtr p) { if (mChannel.get()) mChannel.get()->removeToastByNotificationID(p->getID());} - virtual bool processNotification(const LLNotificationPtr& notify) = 0; + virtual bool processNotification(const LLNotificationPtr& notify, bool should_log = true) = 0; }; class LLSystemNotificationHandler : public LLNotificationHandler @@ -136,7 +136,7 @@ class LLIMHandler : public LLCommunicationNotificationHandler public: LLIMHandler(); virtual ~LLIMHandler(); - bool processNotification(const LLNotificationPtr& p); + bool processNotification(const LLNotificationPtr& p, bool should_log = true); protected: virtual void initChannel(); @@ -152,7 +152,7 @@ public: LLTipHandler(); virtual ~LLTipHandler(); - virtual bool processNotification(const LLNotificationPtr& p); + virtual bool processNotification(const LLNotificationPtr& p, bool should_log = true); protected: virtual void initChannel(); @@ -170,7 +170,7 @@ public: virtual void onDelete(LLNotificationPtr p); virtual void onChange(LLNotificationPtr p); - virtual bool processNotification(const LLNotificationPtr& p); + virtual bool processNotification(const LLNotificationPtr& p, bool should_log = true); virtual void addToastWithNotification(const LLNotificationPtr& p); protected: @@ -188,7 +188,7 @@ public: LLGroupHandler(); virtual ~LLGroupHandler(); - virtual bool processNotification(const LLNotificationPtr& p); + virtual bool processNotification(const LLNotificationPtr& p, bool should_log = true); protected: virtual void initChannel(); @@ -204,7 +204,7 @@ public: virtual ~LLAlertHandler(); virtual void onChange(LLNotificationPtr p); - virtual bool processNotification(const LLNotificationPtr& p); + virtual bool processNotification(const LLNotificationPtr& p, bool should_log = true); protected: virtual void initChannel(); @@ -220,7 +220,7 @@ public: virtual ~LLViewerAlertHandler() {}; virtual void onDelete(LLNotificationPtr p) {}; - virtual bool processNotification(const LLNotificationPtr& p); + virtual bool processNotification(const LLNotificationPtr& p, bool should_log = true); protected: virtual void initChannel() {}; @@ -238,7 +238,7 @@ public: virtual void onChange(LLNotificationPtr p); virtual void onDelete(LLNotificationPtr notification); - virtual bool processNotification(const LLNotificationPtr& p); + virtual bool processNotification(const LLNotificationPtr& p, bool should_log = true); protected: virtual void initChannel(); @@ -256,7 +256,7 @@ public: virtual void onAdd(LLNotificationPtr p); virtual void onLoad(LLNotificationPtr p); virtual void onDelete(LLNotificationPtr p); - virtual bool processNotification(const LLNotificationPtr& p); + virtual bool processNotification(const LLNotificationPtr& p, bool should_log = true); protected: virtual void initChannel() {}; @@ -271,7 +271,7 @@ public: LLBrowserNotification(); virtual ~LLBrowserNotification() {} - virtual bool processNotification(const LLNotificationPtr& p); + virtual bool processNotification(const LLNotificationPtr& p, bool should_log = true); protected: virtual void initChannel() {}; diff --git a/indra/newview/llnotificationhinthandler.cpp b/indra/newview/llnotificationhinthandler.cpp index f1226c53ff..44ebc5ed47 100644 --- a/indra/newview/llnotificationhinthandler.cpp +++ b/indra/newview/llnotificationhinthandler.cpp @@ -53,7 +53,7 @@ void LLHintHandler::onDelete(LLNotificationPtr p) LLHints::getInstance()->hide(p); } -bool LLHintHandler::processNotification(const LLNotificationPtr& p) +bool LLHintHandler::processNotification(const LLNotificationPtr& p, bool should_log) { return false; } diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp index a9678b1e93..201eaeb9f8 100644 --- a/indra/newview/llnotificationofferhandler.cpp +++ b/indra/newview/llnotificationofferhandler.cpp @@ -68,7 +68,7 @@ void LLOfferHandler::initChannel() } //-------------------------------------------------------------------------- -bool LLOfferHandler::processNotification(const LLNotificationPtr& notification) +bool LLOfferHandler::processNotification(const LLNotificationPtr& notification, bool should_log) { if(mChannel.isDead()) { diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp index ba831ab2ed..43c3ee3ce2 100644 --- a/indra/newview/llnotificationscripthandler.cpp +++ b/indra/newview/llnotificationscripthandler.cpp @@ -92,7 +92,7 @@ void LLScriptHandler::addToastWithNotification(const LLNotificationPtr& notifica } //-------------------------------------------------------------------------- -bool LLScriptHandler::processNotification(const LLNotificationPtr& notification) +bool LLScriptHandler::processNotification(const LLNotificationPtr& notification, bool should_log) { if(mChannel.isDead()) { @@ -105,7 +105,7 @@ bool LLScriptHandler::processNotification(const LLNotificationPtr& notification) initChannel(); } - if (notification->canLogToIM()) + if (should_log && notification->canLogToIM()) { LLHandlerUtil::logToIMP2P(notification); } diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp index a6ef130cd0..91f93067de 100644 --- a/indra/newview/llnotificationtiphandler.cpp +++ b/indra/newview/llnotificationtiphandler.cpp @@ -66,7 +66,7 @@ void LLTipHandler::initChannel() } //-------------------------------------------------------------------------- -bool LLTipHandler::processNotification(const LLNotificationPtr& notification) +bool LLTipHandler::processNotification(const LLNotificationPtr& notification, bool should_log) { if(mChannel.isDead()) { diff --git a/indra/newview/llpersistentnotificationstorage.cpp b/indra/newview/llpersistentnotificationstorage.cpp index f95ab9928d..18888f2723 100644 --- a/indra/newview/llpersistentnotificationstorage.cpp +++ b/indra/newview/llpersistentnotificationstorage.cpp @@ -150,7 +150,7 @@ void LLPersistentNotificationStorage::loadNotifications() LLNotificationResponderPtr responder(createResponder(notification_params["name"], notification_params["responder"])); notification->setResponseFunctor(responder); - instance.add(notification); + instance.load(notification); // hide script floaters so they don't confuse the user and don't overlap startup toast LLScriptFloaterManager::getInstance()->setFloaterVisible(notification->getID(), false); -- cgit v1.3 From 9df87dd36575597d4c522b99a1f706e4861a416e Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Thu, 27 May 2021 23:51:59 +0300 Subject: SL-13179 FIXED Sorting residents banned on the parcel by duration is incorrect --- indra/llui/llscrolllistcell.cpp | 23 ++++++++++++++++++++++- indra/llui/llscrolllistcell.h | 7 +++++++ indra/llui/llscrolllistctrl.cpp | 18 ++++++++++++++---- indra/llui/llscrolllistctrl.h | 4 ++++ indra/llui/llscrolllistitem.cpp | 3 ++- indra/llui/llscrolllistitem.h | 4 ++++ indra/newview/llfloaterland.cpp | 5 ++++- indra/newview/llnamelistctrl.cpp | 1 + 8 files changed, 58 insertions(+), 7 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llscrolllistcell.cpp b/indra/llui/llscrolllistcell.cpp index 13839da400..8dd552d2ad 100644 --- a/indra/llui/llscrolllistcell.cpp +++ b/indra/llui/llscrolllistcell.cpp @@ -79,6 +79,14 @@ const LLSD LLScrollListCell::getValue() const return LLStringUtil::null; } + +// virtual +const LLSD LLScrollListCell::getAltValue() const +{ + return LLStringUtil::null; +} + + // // LLScrollListIcon // @@ -173,6 +181,7 @@ U32 LLScrollListText::sCount = 0; LLScrollListText::LLScrollListText(const LLScrollListCell::Params& p) : LLScrollListCell(p), mText(p.label.isProvided() ? p.label() : p.value().asString()), + mAltText(p.alt_value().asString()), mFont(p.font), mColor(p.color), mUseColor(p.color.isProvided()), @@ -275,10 +284,22 @@ void LLScrollListText::setValue(const LLSD& text) setText(text.asString()); } +//virtual +void LLScrollListText::setAltValue(const LLSD& text) +{ + mAltText = text.asString(); +} + //virtual const LLSD LLScrollListText::getValue() const { - return LLSD(mText.getString()); + return LLSD(mText.getString()); +} + +//virtual +const LLSD LLScrollListText::getAltValue() const +{ + return LLSD(mAltText.getString()); } diff --git a/indra/llui/llscrolllistcell.h b/indra/llui/llscrolllistcell.h index 19576fb247..ede8d847d9 100644 --- a/indra/llui/llscrolllistcell.h +++ b/indra/llui/llscrolllistcell.h @@ -60,6 +60,7 @@ public: Optional userdata; Optional value; // state of checkbox, icon id/name, date + Optional alt_value; Optional label; // description or text Optional tool_tip; @@ -76,6 +77,7 @@ public: enabled("enabled", true), visible("visible", true), value("value"), + alt_value("alt_value", ""), label("label"), tool_tip("tool_tip", ""), font("font", LLFontGL::getFontSansSerifSmall()), @@ -98,7 +100,9 @@ public: virtual S32 getContentWidth() const { return 0; } virtual S32 getHeight() const { return 0; } virtual const LLSD getValue() const; + virtual const LLSD getAltValue() const; virtual void setValue(const LLSD& value) { } + virtual void setAltValue(const LLSD& value) { } virtual const std::string &getToolTip() const { return mToolTip; } virtual void setToolTip(const std::string &str) { mToolTip = str; } virtual BOOL getVisible() const { return TRUE; } @@ -138,7 +142,9 @@ public: /*virtual*/ S32 getContentWidth() const; /*virtual*/ S32 getHeight() const; /*virtual*/ void setValue(const LLSD& value); + /*virtual*/ void setAltValue(const LLSD& value); /*virtual*/ const LLSD getValue() const; + /*virtual*/ const LLSD getAltValue() const; /*virtual*/ BOOL getVisible() const; /*virtual*/ void highlightText(S32 offset, S32 num_chars); @@ -156,6 +162,7 @@ public: protected: LLUIString mText; + LLUIString mAltText; S32 mTextWidth; const LLFontGL* mFont; LLColor4 mColor; diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index be85f1cb6a..1059190712 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -66,9 +66,10 @@ static LLDefaultChildRegistry::Register r("scroll_list"); // local structures & classes. struct SortScrollListItem { - SortScrollListItem(const std::vector >& sort_orders,const LLScrollListCtrl::sort_signal_t* sort_signal) + SortScrollListItem(const std::vector >& sort_orders,const LLScrollListCtrl::sort_signal_t* sort_signal, bool alternate_sort) : mSortOrders(sort_orders) , mSortSignal(sort_signal) + , mAltSort(alternate_sort) {} bool operator()(const LLScrollListItem* i1, const LLScrollListItem* i2) @@ -93,7 +94,14 @@ struct SortScrollListItem } else { - sort_result = order * LLStringUtil::compareDict(cell1->getValue().asString(), cell2->getValue().asString()); + if (mAltSort && !cell1->getAltValue().asString().empty() && !cell2->getAltValue().asString().empty()) + { + sort_result = order * LLStringUtil::compareDict(cell1->getAltValue().asString(), cell2->getAltValue().asString()); + } + else + { + sort_result = order * LLStringUtil::compareDict(cell1->getValue().asString(), cell2->getValue().asString()); + } } if (sort_result != 0) { @@ -109,6 +117,7 @@ struct SortScrollListItem typedef std::vector > sort_order_t; const LLScrollListCtrl::sort_signal_t* mSortSignal; const sort_order_t& mSortOrders; + const bool mAltSort; }; //--------------------------------------------------------------------------- @@ -213,6 +222,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p) mSearchColumn(p.search_column), mColumnPadding(p.column_padding), mRowPadding(p.row_padding), + mAlternateSort(false), mContextMenuType(MENU_NONE), mIsFriendSignal(NULL) { @@ -2680,7 +2690,7 @@ void LLScrollListCtrl::updateSort() const std::stable_sort( mItemList.begin(), mItemList.end(), - SortScrollListItem(mSortColumns,mSortCallback)); + SortScrollListItem(mSortColumns,mSortCallback, mAlternateSort)); mSorted = true; } @@ -2696,7 +2706,7 @@ void LLScrollListCtrl::sortOnce(S32 column, BOOL ascending) std::stable_sort( mItemList.begin(), mItemList.end(), - SortScrollListItem(sort_column,mSortCallback)); + SortScrollListItem(sort_column,mSortCallback,mAlternateSort)); } void LLScrollListCtrl::dirtyColumns() diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index 0cc481b113..08134bbfc8 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -398,6 +398,8 @@ public: BOOL hasSortOrder() const; void clearSortOrder(); + void setAlternateSort() { mAlternateSort = true; } + S32 selectMultiple( uuid_vec_t ids ); // conceptually const, but mutates mItemList void updateSort() const; @@ -482,6 +484,8 @@ private: bool mColumnsDirty; bool mColumnWidthsDirty; + bool mAlternateSort; + mutable item_list mItemList; LLScrollListItem *mLastSelected; diff --git a/indra/llui/llscrolllistitem.cpp b/indra/llui/llscrolllistitem.cpp index 51c615dd00..e1360f80cd 100644 --- a/indra/llui/llscrolllistitem.cpp +++ b/indra/llui/llscrolllistitem.cpp @@ -44,7 +44,8 @@ LLScrollListItem::LLScrollListItem( const Params& p ) mSelectedIndex(-1), mEnabled(p.enabled), mUserdata(p.userdata), - mItemValue(p.value) + mItemValue(p.value), + mItemAltValue(p.alt_value) { } diff --git a/indra/llui/llscrolllistitem.h b/indra/llui/llscrolllistitem.h index d2c3dd7721..a3398305b1 100644 --- a/indra/llui/llscrolllistitem.h +++ b/indra/llui/llscrolllistitem.h @@ -55,6 +55,7 @@ public: Optional enabled; Optional userdata; Optional value; + Optional alt_value; Ignored name; // use for localization tools Ignored type; @@ -65,6 +66,7 @@ public: Params() : enabled("enabled", true), value("value"), + alt_value("alt_value"), name("name"), type("type"), length("length"), @@ -97,6 +99,7 @@ public: virtual LLUUID getUUID() const { return mItemValue.asUUID(); } LLSD getValue() const { return mItemValue; } + LLSD getAltValue() const { return mItemAltValue; } void setRect(LLRect rect) { mRectangle = rect; } LLRect getRect() const { return mRectangle; } @@ -131,6 +134,7 @@ private: BOOL mEnabled; void* mUserdata; LLSD mItemValue; + LLSD mItemAltValue; std::vector mColumns; LLRect mRectangle; }; diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index af0e56e448..04133f2710 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -2468,6 +2468,7 @@ BOOL LLPanelLandAccess::postBuild() { mListBanned->sortByColumnIndex(0, TRUE); // ascending mListBanned->setContextMenu(LLScrollListCtrl::MENU_AVATAR); + mListBanned->setAlternateSort(); } return TRUE; @@ -2570,11 +2571,12 @@ void LLPanelLandAccess::refresh() { const LLAccessEntry& entry = (*cit).second; std::string duration; + S32 seconds = -1; if (entry.mTime != 0) { LLStringUtil::format_map_t args; S32 now = time(NULL); - S32 seconds = entry.mTime - now; + seconds = entry.mTime - now; if (seconds < 0) seconds = 0; if (seconds >= 7200) @@ -2611,6 +2613,7 @@ void LLPanelLandAccess::refresh() columns[0]["column"] = "name"; // to be populated later columns[1]["column"] = "duration"; columns[1]["value"] = duration; + columns[1]["alt_value"] = entry.mTime != 0 ? std::to_string(seconds) : "Always"; mListBanned->addElement(item); } mListBanned->sortByName(TRUE); diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp index 3209d23e43..5215126789 100644 --- a/indra/newview/llnamelistctrl.cpp +++ b/indra/newview/llnamelistctrl.cpp @@ -398,6 +398,7 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow( if (cell) { cell->setValue(prefix + fullname); + cell->setAltValue(name_item.alt_value()); } dirtyColumns(); -- cgit v1.3 From 416ad1831f40052fccc01f012c4452d61e57f0f8 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 3 Jun 2021 23:46:55 +0300 Subject: SL-15340 The list of parcels is duplicated after reopening 1. Clean list before requesting 2. Don't trigger onOpen from menu if already open --- indra/llui/llfloaterreg.cpp | 52 ++++++++++++++++++++++ indra/llui/llfloaterreg.h | 1 + indra/llui/llui.cpp | 1 + indra/newview/llfloaterlandholdings.cpp | 3 ++ indra/newview/skins/default/xui/en/menu_viewer.xml | 2 +- 5 files changed, 58 insertions(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp index 85e07fc6a6..0b27ff3567 100644 --- a/indra/llui/llfloaterreg.cpp +++ b/indra/llui/llfloaterreg.cpp @@ -524,6 +524,58 @@ void LLFloaterReg::toggleInstanceOrBringToFront(const LLSD& sdname, const LLSD& } } +// static +// Same as toggleInstanceOrBringToFront but does not close floater. +// unlike showInstance() does not trigger onOpen() if already open +void LLFloaterReg::showInstanceOrBringToFront(const LLSD& sdname, const LLSD& key) +{ + std::string name = sdname.asString(); + LLFloater* instance = getInstance(name, key); + + + if (!instance) + { + LL_DEBUGS() << "Unable to get instance of floater '" << name << "'" << LL_ENDL; + return; + } + + // If hosted, we need to take that into account + LLFloater* host = instance->getHost(); + + if (host) + { + if (host->isMinimized() || !host->isShown() || !host->isFrontmost()) + { + host->setMinimized(FALSE); + instance->openFloater(key); + instance->setVisibleAndFrontmost(true, key); + } + else if (!instance->getVisible()) + { + instance->openFloater(key); + instance->setVisibleAndFrontmost(true, key); + instance->setFocus(TRUE); + } + } + else + { + if (instance->isMinimized()) + { + instance->setMinimized(FALSE); + instance->setVisibleAndFrontmost(true, key); + } + else if (!instance->isShown()) + { + instance->openFloater(key); + instance->setVisibleAndFrontmost(true, key); + } + else if (!instance->isFrontmost()) + { + instance->setVisibleAndFrontmost(true, key); + } + } +} + // static U32 LLFloaterReg::getVisibleFloaterInstanceCount() { diff --git a/indra/llui/llfloaterreg.h b/indra/llui/llfloaterreg.h index e3b17dcb4f..b337579552 100644 --- a/indra/llui/llfloaterreg.h +++ b/indra/llui/llfloaterreg.h @@ -128,6 +128,7 @@ public: // Callback wrappers static void toggleInstanceOrBringToFront(const LLSD& sdname, const LLSD& key = LLSD()); + static void showInstanceOrBringToFront(const LLSD& sdname, const LLSD& key = LLSD()); // Typed find / get / show template diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index 656b69d3ed..f9e81dd43c 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -174,6 +174,7 @@ mHelpImpl(NULL) reg.add("Floater.Toggle", boost::bind(&LLFloaterReg::toggleInstance, _2, LLSD())); reg.add("Floater.ToggleOrBringToFront", boost::bind(&LLFloaterReg::toggleInstanceOrBringToFront, _2, LLSD())); reg.add("Floater.Show", boost::bind(&LLFloaterReg::showInstance, _2, LLSD(), FALSE)); + reg.add("Floater.ShowOrBringToFront", boost::bind(&LLFloaterReg::showInstanceOrBringToFront, _2, LLSD())); reg.add("Floater.Hide", boost::bind(&LLFloaterReg::hideInstance, _2, LLSD())); // Button initialization callback for toggle buttons diff --git a/indra/newview/llfloaterlandholdings.cpp b/indra/newview/llfloaterlandholdings.cpp index f34760a6bf..a6cdf4b0c1 100644 --- a/indra/newview/llfloaterlandholdings.cpp +++ b/indra/newview/llfloaterlandholdings.cpp @@ -105,6 +105,9 @@ LLFloaterLandHoldings::~LLFloaterLandHoldings() void LLFloaterLandHoldings::onOpen(const LLSD& key) { + LLScrollListCtrl *list = getChild("parcel list"); + list->clearRows(); + // query_id null is known to be us const LLUUID& query_id = LLUUID::null; diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index ac69f5a748..a5f79d4e28 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -542,7 +542,7 @@ label="My land holdings..." name="My Land"> Date: Fri, 8 Oct 2021 02:12:28 +0300 Subject: SL-16157 Crash at LLFontGL::maxDrawableChars --- indra/llui/lltextbase.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 20bea7fe24..ea2d357d5d 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1558,11 +1558,14 @@ void LLTextBase::reflow() { // find first element whose end comes after start_index line_list_t::iterator iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), start_index, line_end_compare()); - line_start_index = iter->mDocIndexStart; - line_count = iter->mLineNum; - cur_top = iter->mRect.mTop; - getSegmentAndOffset(iter->mDocIndexStart, &seg_iter, &seg_offset); - mLineInfoList.erase(iter, mLineInfoList.end()); + if (iter != mLineInfoList.end()) + { + line_start_index = iter->mDocIndexStart; + line_count = iter->mLineNum; + cur_top = iter->mRect.mTop; + getSegmentAndOffset(iter->mDocIndexStart, &seg_iter, &seg_offset); + mLineInfoList.erase(iter, mLineInfoList.end()); + } } S32 line_height = 0; -- cgit v1.3 From b41f6cd2b522f3ff8effdd17f63c067a468cd4e0 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 21 Oct 2021 23:58:18 +0300 Subject: SL-15387 Resolve some columns crashes Looks like mColumnsIndexed had dead pointers which resulted in a crash and there is some kind of hard to trigger interaction with searchable UI --- indra/llui/llscrolllistctrl.cpp | 5 +++-- indra/newview/llfloaterpreference.cpp | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index de644185fd..a63457bdea 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -336,8 +336,7 @@ LLScrollListCtrl::~LLScrollListCtrl() std::for_each(mItemList.begin(), mItemList.end(), DeletePointer()); mItemList.clear(); - std::for_each(mColumns.begin(), mColumns.end(), DeletePairedPointer()); - mColumns.clear(); + clearColumns(); //clears columns and deletes headers delete mIsFriendSignal; } @@ -3011,6 +3010,8 @@ void LLScrollListCtrl::clearColumns() mSortColumns.clear(); mTotalStaticColumnWidth = 0; mTotalColumnPadding = 0; + + dirtyColumns(); // Clears mColumnsIndexed } void LLScrollListCtrl::setColumnLabel(const std::string& column, const std::string& label) diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 1c4fdc433b..0cbd06c38e 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -2958,6 +2958,9 @@ void LLPanelPreferenceControls::populateControlTable() LL_WARNS() << "Unimplemented mode" << LL_ENDL; } + // explicit update to make sure table is ready for llsearchableui + pControlsTable->updateColumns(); + // Searchable columns were removed and readded, mark searchables for an update // Note: at the moment tables/lists lack proper llsearchableui support LLFloaterPreference* instance = LLFloaterReg::findTypedInstance("preferences"); -- cgit v1.3