diff options
Diffstat (limited to 'indra')
-rw-r--r-- | indra/newview/llinventorybridge.cpp | 23 | ||||
-rw-r--r-- | indra/newview/llinventoryfunctions.cpp | 14 | ||||
-rw-r--r-- | indra/newview/llinventoryfunctions.h | 15 | ||||
-rw-r--r-- | indra/newview/llinventorypanel.cpp | 193 | ||||
-rw-r--r-- | indra/newview/llinventorypanel.h | 5 | ||||
-rw-r--r-- | indra/newview/llviewerinventory.cpp | 3 |
6 files changed, 233 insertions, 20 deletions
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index d7c7c7b552..20b2e1334e 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -838,6 +838,8 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, { const LLInventoryObject *obj = getInventoryObject(); bool single_folder_root = (mRoot == NULL); + bool is_cof = isCOFFolder(); + bool is_inbox = isInboxFolder(); if (obj) { @@ -853,7 +855,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, } bool is_agent_inventory = isAgentInventory(); - if (is_agent_inventory && !single_folder_root) + if (is_agent_inventory && !single_folder_root && !is_cof && !is_inbox) { items.push_back(std::string("New folder from selected")); items.push_back(std::string("Subfolder Separator")); @@ -889,6 +891,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, if (!isItemMovable() || !isItemRemovable()) { disabled_items.push_back(std::string("Cut")); + disabled_items.push_back(std::string("New folder from selected")); } } else @@ -898,7 +901,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, items.push_back(std::string("Find Links")); } - if (!isInboxFolder() && !single_folder_root) + if (!is_inbox && !single_folder_root) { items.push_back(std::string("Rename")); if (!isItemRenameable() || ((flags & FIRST_SELECTED_ITEM) == 0)) @@ -938,6 +941,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, if (!isItemMovable() || !isItemRemovable()) { disabled_items.push_back(std::string("Cut")); + disabled_items.push_back(std::string("New folder from selected")); } if (canListOnMarketplace() && !isMarketplaceListingsFolder() && !isInboxFolder()) @@ -960,7 +964,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, } // Don't allow items to be pasted directly into the COF or the inbox - if (!isCOFFolder() && !isInboxFolder()) + if (!is_cof && !is_inbox) { items.push_back(std::string("Paste")); } @@ -4445,6 +4449,15 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items items.push_back(std::string("Rename")); items.push_back(std::string("thumbnail")); + if (cat->getIsFavorite()) + { + items.push_back(std::string("Remove from Favorites")); + } + else + { + items.push_back(std::string("Add to Favorites")); + } + addDeleteContextMenuOptions(items, disabled_items); // EXT-4030: disallow deletion of currently worn outfit const LLViewerInventoryItem *base_outfit_link = LLAppearanceMgr::instance().getBaseOutfitLink(); @@ -8029,6 +8042,7 @@ void LLRecentItemsFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) buildContextMenuOptions(flags, items, disabled_items); items.erase(std::remove(items.begin(), items.end(), std::string("New Folder")), items.end()); + items.erase(std::remove(items.begin(), items.end(), std::string("New folder from selected")), items.end()); hide_context_entries(menu, items, disabled_items); } @@ -8072,6 +8086,9 @@ void LLFavoritesFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) menuentry_vec_t disabled_items, items; buildContextMenuOptions(flags, items, disabled_items); + items.erase(std::remove(items.begin(), items.end(), std::string("New Folder")), items.end()); + items.erase(std::remove(items.begin(), items.end(), std::string("New folder from selected")), items.end()); + hide_context_entries(menu, items, disabled_items); } diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 135dfa3519..81be2c1f24 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -2663,6 +2663,20 @@ bool LLIsTypeWithPermissions::operator()(LLInventoryCategory* cat, LLInventoryIt return FALSE; } +bool LLFavoritesCollector::operator()(LLInventoryCategory* cat, + LLInventoryItem* item) +{ + if (item && item->getIsFavorite()) + { + return true; + } + if (cat && cat->getIsFavorite()) + { + return true; + } + return false; +} + bool LLBuddyCollector::operator()(LLInventoryCategory* cat, LLInventoryItem* item) { diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index 14038967c6..44f85bfb3e 100644 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -325,6 +325,21 @@ protected: }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class LLFavoritesCollector +// +// Simple class that collects calling cards that are not null, and not +// the agent. Duplicates are possible. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +class LLFavoritesCollector : public LLInventoryCollectFunctor +{ +public: + LLFavoritesCollector() {} + virtual ~LLFavoritesCollector() {} + virtual bool operator()(LLInventoryCategory* cat, + LLInventoryItem* item); +}; + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLBuddyCollector // // Simple class that collects calling cards that are not null, and not diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 3892bfee03..4682f2085b 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -865,7 +865,23 @@ void LLInventoryPanel::idle(void* user_data) bool in_visible_chain = panel->isInVisibleChain(); - if (!panel->mBuildViewsQueue.empty()) + if (!panel->mBuildRootQueue.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; + + while (curent_time < panel->mBuildViewsEndTime + && !panel->mBuildRootQueue.empty()) + { + LLUUID item_id = panel->mBuildRootQueue.back(); + panel->mBuildRootQueue.pop_back(); + panel->findAndInitRootContent(item_id); + + curent_time = LLTimer::getTotalSeconds(); + } + } + else if (!panel->mBuildViewsQueue.empty()) { const F64 max_time = in_visible_chain ? 0.006f : 0.001f; // 6 ms F64 curent_time = LLTimer::getTotalSeconds(); @@ -949,7 +965,7 @@ void LLInventoryPanel::initializeViews(F64 max_time) // init everything initRootContent(); - if (mBuildViewsQueue.empty()) + if (mBuildViewsQueue.empty() && mBuildRootQueue.empty()) { mViewsInitialized = VIEWS_INITIALIZED; } @@ -2252,12 +2268,19 @@ public: getFilter().setFilterNoMarketplaceFolder(); } + void removeItemID(const LLUUID& id) override; + protected: LLInventoryFavoritesItemsPanel(const Params&); friend class LLUICtrlFactory; - void initRootContent(const LLUUID& id); + void findAndInitRootContent(const LLUUID& folder_id) override; void initRootContent() override; + + bool removeFavorite(const LLUUID& id, const LLInventoryObject* model_item); + void itemChanged(const LLUUID& item_id, U32 mask, const LLInventoryObject* model_item) override; + + std::set<LLUUID> mRootContentIDs; }; LLInventoryFavoritesItemsPanel::LLInventoryFavoritesItemsPanel(const Params& params) @@ -2267,8 +2290,27 @@ LLInventoryFavoritesItemsPanel::LLInventoryFavoritesItemsPanel(const Params& par mInvFVBridgeBuilder = &FAVORITES_BUILDER; } -void LLInventoryFavoritesItemsPanel::initRootContent(const LLUUID& id) +void LLInventoryFavoritesItemsPanel::removeItemID(const LLUUID& id) +{ + std::set<LLUUID>::iterator found = mRootContentIDs.find(id); + if (found != mRootContentIDs.end()) + { + mRootContentIDs.erase(found); + // check content for favorites + mBuildRootQueue.emplace_back(id); + } + + LLInventoryPanel::removeItemID(id); +} + +void LLInventoryFavoritesItemsPanel::findAndInitRootContent(const LLUUID& id) { + F64 curent_time = LLTimer::getTotalSeconds(); + if (mBuildViewsEndTime < curent_time) + { + mBuildRootQueue.emplace_back(id); + return; + } LLViewerInventoryCategory::cat_array_t* categories; LLViewerInventoryItem::item_array_t* items; mInventory->lockDirectDescendentArrays(id, categories, items); @@ -2285,14 +2327,18 @@ void LLInventoryFavoritesItemsPanel::initRootContent(const LLUUID& id) } else if (cat->getIsFavorite()) { - const LLUUID& parent_id = cat->getParentUUID(); - LLFolderViewItem* folder_view_item = getItemByID(cat->getUUID()); // Should be NULL + LLFolderViewItem* folder_view_item = getItemByID(cat->getUUID()); + if (!folder_view_item) + { + const LLUUID& parent_id = cat->getParentUUID(); + mRootContentIDs.emplace(cat->getUUID()); - buildViewsTree(cat->getUUID(), parent_id, cat, folder_view_item, mFolderRoot.get(), BUILD_TIMELIMIT); + buildViewsTree(cat->getUUID(), parent_id, cat, folder_view_item, mFolderRoot.get(), BUILD_TIMELIMIT); + } } - else // Todo: timelimits + else { - initRootContent(cat->getUUID()); + findAndInitRootContent(cat->getUUID()); } } } @@ -2303,12 +2349,17 @@ void LLInventoryFavoritesItemsPanel::initRootContent(const LLUUID& id) for (S32 i = 0; i < count; ++i) { LLViewerInventoryItem* item = items->at(i); - if (item->getIsFavorite() && typedViewsFilter(id, item)) + const LLUUID item_id = item->getUUID(); + if (item->getIsFavorite() && typedViewsFilter(item_id, item)) { - const LLUUID& parent_id = item->getParentUUID(); - LLFolderViewItem* folder_view_item = getItemByID(id); // Should be NULL + LLFolderViewItem* folder_view_item = getItemByID(id); + if (!folder_view_item) + { + const LLUUID& parent_id = item->getParentUUID(); + mRootContentIDs.emplace(item_id); - buildViewsTree(item->getUUID(), parent_id, item, folder_view_item, mFolderRoot.get(), BUILD_TIMELIMIT); + buildViewsTree(item_id, parent_id, item, folder_view_item, mFolderRoot.get(), BUILD_TIMELIMIT); + } } } } @@ -2316,9 +2367,123 @@ void LLInventoryFavoritesItemsPanel::initRootContent(const LLUUID& id) void LLInventoryFavoritesItemsPanel::initRootContent() { - initRootContent(gInventory.getRootFolderID()); // My Inventory + findAndInitRootContent(gInventory.getRootFolderID()); // My Inventory +} + +bool LLInventoryFavoritesItemsPanel::removeFavorite(const LLUUID& id, const LLInventoryObject* model_item) +{ + std::set<LLUUID>::iterator found = mRootContentIDs.find(id); + if (found == mRootContentIDs.end()) + { + return false; + } + + mRootContentIDs.erase(found); + + // This item is in root's content, remove item's UI. + LLFolderViewItem* view_item = getItemByID(id); + if (view_item) + { + LLFolderViewFolder* parent = view_item->getParentFolder(); + LLFolderViewModelItemInventory* viewmodel_item = static_cast<LLFolderViewModelItemInventory*>(view_item->getViewModelItem()); + if (viewmodel_item) + { + removeItemID(viewmodel_item->getUUID()); + } + view_item->destroyView(); + if (parent) + { + parent->getViewModelItem()->dirtyDescendantsFilter(); + LLFolderViewModelItemInventory* viewmodel_folder = static_cast<LLFolderViewModelItemInventory*>(parent->getViewModelItem()); + if (viewmodel_folder) + { + updateFolderLabel(viewmodel_folder->getUUID()); + } + if (view_item->isFavorite()) + { + parent->updateHasFavorites(false); // favorite was removed + } + } + } + + return true; } +void LLInventoryFavoritesItemsPanel::itemChanged(const LLUUID& id, U32 mask, const LLInventoryObject* model_item) +{ + if (!model_item && !getItemByID(id)) + { + // remove operation, but item is not in panel already + return; + } + + bool handled = false; + + if (mask & (LLInventoryObserver::UPDATE_FAVORITE | + LLInventoryObserver::STRUCTURE | + LLInventoryObserver::ADD | + LLInventoryObserver::REMOVE)) + { + if (model_item && model_item->getIsFavorite()) + { + LLFolderViewItem* view_item = getItemByID(id); + if (!view_item) + { + const LLViewerInventoryCategory* cat = dynamic_cast<const LLViewerInventoryCategory*>(model_item); + if (cat) + { + // New favorite folder + if (cat->getPreferredType() != LLFolderType::FT_TRASH) + { + // If any descendants were in the list, remove them + LLFavoritesCollector is_favorite; + LLInventoryModel::cat_array_t cat_array; + LLInventoryModel::item_array_t item_array; + gInventory.collectDescendentsIf(id, cat_array, item_array, FALSE, is_favorite); + for (LLInventoryModel::cat_array_t::const_iterator it = cat_array.begin(); it != cat_array.end(); ++it) + { + removeFavorite((*it)->getUUID(), *it); + } + for (LLInventoryModel::item_array_t::const_iterator it = item_array.begin(); it != item_array.end(); ++it) + { + removeFavorite((*it)->getUUID(), *it); + } + + LLFolderViewItem* folder_view_item = getItemByID(cat->getUUID()); + if (!folder_view_item) + { + const LLUUID& parent_id = cat->getParentUUID(); + mRootContentIDs.emplace(cat->getUUID()); + + buildViewsTree(cat->getUUID(), parent_id, cat, folder_view_item, mFolderRoot.get(), BUILD_ONE_FOLDER); + } + } + } + else + { + // New favorite item + if (model_item->getIsFavorite() && typedViewsFilter(id, model_item)) + { + const LLUUID& parent_id = model_item->getParentUUID(); + mRootContentIDs.emplace(id); + + buildViewsTree(id, parent_id, model_item, NULL, mFolderRoot.get(), BUILD_ONE_FOLDER); + } + } + handled = true; + } + } + else + { + handled = removeFavorite(id, model_item); + } + } + + if (!handled) + { + LLInventoryPanel::itemChanged(id, mask, model_item); + } +} /************************************************************************/ /* LLInventorySingleFolderPanel */ /************************************************************************/ diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index b6d21ea9a8..a03ec15777 100644 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -251,7 +251,7 @@ public: bool reset_filter = false); static void setSFViewAndOpenFolder(const LLInventoryPanel* panel, const LLUUID& folder_id); void addItemID(const LLUUID& id, LLFolderViewItem* itemp); - void removeItemID(const LLUUID& id); + virtual void removeItemID(const LLUUID& id); LLFolderViewItem* getItemByID(const LLUUID& id); LLFolderViewFolder* getFolderByID(const LLUUID& id); void setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus); @@ -335,6 +335,7 @@ protected: // Builds the UI. Call this once the inventory is usable. void initializeViews(F64 max_time); virtual void initRootContent(); + virtual void findAndInitRootContent(const LLUUID& root_id) {}; // Specific inventory colors static bool sColorSetInitialized; @@ -395,7 +396,7 @@ protected: EViewsInitializationState mViewsInitialized; // Whether views have been generated F64 mBuildViewsEndTime; // Stop building views past this timestamp std::deque<LLUUID> mBuildViewsQueue; - std::deque<LLUUID> mBuildRootContent; + std::deque<LLUUID> mBuildRootQueue; }; diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index b9a7c9448f..3a4ac96826 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -1436,7 +1436,8 @@ void update_inventory_category( if(obj) { if (LLFolderType::lookupIsProtectedType(obj->getPreferredType()) - && (updates.size() != 1 || !updates.has("thumbnail"))) + && (updates.size() != 1 + || !(updates.has("thumbnail") || updates.has("favorite")))) { LLNotificationsUtil::add("CannotModifyProtectedCategories"); return; |