summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/llinventorybridge.cpp23
-rw-r--r--indra/newview/llinventoryfunctions.cpp14
-rw-r--r--indra/newview/llinventoryfunctions.h15
-rw-r--r--indra/newview/llinventorypanel.cpp193
-rw-r--r--indra/newview/llinventorypanel.h5
-rw-r--r--indra/newview/llviewerinventory.cpp3
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;