summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llappviewer.cpp2
-rw-r--r--indra/newview/llfolderviewitem.cpp16
-rw-r--r--indra/newview/llfolderviewitem.h3
-rw-r--r--indra/newview/llinventorybridge.cpp99
-rw-r--r--indra/newview/llinventorybridge.h2
-rw-r--r--indra/newview/llinventorymodel.cpp27
-rw-r--r--indra/newview/llinventorymodel.h9
7 files changed, 91 insertions, 67 deletions
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index a5ca06ce30..af17286c9c 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -3534,7 +3534,7 @@ void LLAppViewer::idle()
gEventNotifier.update();
gIdleCallbacks.callFunctions();
- gInventory.notifyObservers();
+ gInventory.idleNotifyObservers();
}
if (gDisconnected)
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index 1096f25f0c..41e3279795 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -2030,6 +2030,22 @@ void LLFolderViewFolder::openItem( void )
toggleOpen();
}
+void LLFolderViewFolder::applyFunctorToChildren(LLFolderViewFunctor& functor)
+{
+ for (folders_t::iterator iter = mFolders.begin();
+ iter != mFolders.end();)
+ {
+ folders_t::iterator fit = iter++;
+ functor.doItem((*fit));
+ }
+ for (items_t::iterator iter = mItems.begin();
+ iter != mItems.end();)
+ {
+ items_t::iterator iit = iter++;
+ functor.doItem((*iit));
+ }
+}
+
void LLFolderViewFolder::applyFunctorRecursively(LLFolderViewFunctor& functor)
{
functor.doFolder(this);
diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h
index 30387812a6..f6264ec968 100644
--- a/indra/newview/llfolderviewitem.h
+++ b/indra/newview/llfolderviewitem.h
@@ -501,6 +501,9 @@ public:
void applyFunctorRecursively(LLFolderViewFunctor& functor);
virtual void applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor);
+ // Just apply this functor to the folder's immediate children.
+ void applyFunctorToChildren(LLFolderViewFunctor& functor);
+
virtual void openItem( void );
virtual BOOL addItem(LLFolderViewItem* item);
virtual BOOL addFolder( LLFolderViewFolder* folder);
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index bb8b45ef11..c8540bdbd2 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -171,16 +171,33 @@ time_t LLInvFVBridge::getCreationDate() const
return 0;
}
-// Can be destoryed (or moved to trash)
+// Can be destroyed (or moved to trash)
BOOL LLInvFVBridge::isItemRemovable()
{
- LLInventoryModel* model = getInventoryModel();
- if(!model) return FALSE;
- if(model->isObjectDescendentOf(mUUID, gInventory.getRootFolderID()))
+ const LLInventoryModel* model = getInventoryModel();
+ if(!model)
+ {
+ return FALSE;
+ }
+ if(!model->isObjectDescendentOf(mUUID, gInventory.getRootFolderID()))
+ {
+ return FALSE;
+ }
+ const LLInventoryObject *obj = model->getItem(mUUID);
+ if (obj && obj->getIsLinkType())
{
return TRUE;
}
- return FALSE;
+ if (gAgentWearables.isWearingItem(mUUID))
+ {
+ return FALSE;
+ }
+ const LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
+ if (avatar && avatar->isWearingAttachment(mUUID))
+ {
+ return FALSE;
+ }
+ return TRUE;
}
// Can be moved to another folder
@@ -475,6 +492,7 @@ void hide_context_entries(LLMenuGL& menu,
}
else
{
+ (*itor)->setVisible(TRUE);
for (itor2 = disabled_entries.begin(); itor2 != disabled_entries.end(); ++itor2)
{
if (*itor2 == name)
@@ -1303,6 +1321,23 @@ void LLFolderBridge::selectItem()
}
+// Iterate through a folder's children to determine if
+// all the children are removable.
+class LLIsItemRemovable : public LLFolderViewFunctor
+{
+public:
+ LLIsItemRemovable() : mPassed(TRUE) {}
+ virtual void doFolder(LLFolderViewFolder* folder)
+ {
+ mPassed &= folder->getListener()->isItemRemovable();
+ }
+ virtual void doItem(LLFolderViewItem* item)
+ {
+ mPassed &= item->getListener()->isItemRemovable();
+ }
+ BOOL mPassed;
+};
+
// Can be destroyed (or moved to trash)
BOOL LLFolderBridge::isItemRemovable()
{
@@ -1334,41 +1369,17 @@ BOOL LLFolderBridge::isItemRemovable()
return FALSE;
}
- LLInventoryModel::cat_array_t descendent_categories;
- LLInventoryModel::item_array_t descendent_items;
- gInventory.collectDescendents( mUUID, descendent_categories, descendent_items, FALSE );
-
- S32 i;
- for( i = 0; i < descendent_categories.count(); i++ )
+ LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get());
+ LLFolderViewFolder* folderp = dynamic_cast<LLFolderViewFolder*>(panel ? panel->getRootFolder()->getItemByID(mUUID) : NULL);
+ if (folderp)
{
- LLInventoryCategory* category = descendent_categories[i];
- if(LLFolderType::lookupIsProtectedType(category->getPreferredType()))
+ LLIsItemRemovable folder_test;
+ folderp->applyFunctorToChildren(folder_test);
+ if (!folder_test.mPassed)
{
return FALSE;
}
}
-
- for( i = 0; i < descendent_items.count(); i++ )
- {
- LLInventoryItem* item = descendent_items[i];
- if( (item->getType() == LLAssetType::AT_CLOTHING) ||
- (item->getType() == LLAssetType::AT_BODYPART) )
- {
- if(gAgentWearables.isWearingItem(item->getUUID()))
- {
- return FALSE;
- }
- }
- else
- if( item->getType() == LLAssetType::AT_OBJECT )
- {
- if(avatar->isWearingAttachment(item->getUUID()))
- {
- return FALSE;
- }
- }
- }
-
return TRUE;
}
@@ -2349,6 +2360,10 @@ void LLFolderBridge::folderOptionsMenu()
mItems.push_back(std::string("Remove From Outfit"));
}
hide_context_entries(*mMenu, mItems, disabled_items);
+
+ // Reposition the menu, in case we're adding items to an existing menu.
+ mMenu->needsArrange();
+ mMenu->arrangeAndClear();
}
BOOL LLFolderBridge::checkFolderForContentsOfType(LLInventoryModel* model, LLInventoryCollectFunctor& is_type)
@@ -3772,14 +3787,6 @@ LLItemBridge(inventory, uuid), mInvType(type)
mIsMultiObject = ( flags & LLInventoryItem::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS ) ? TRUE: FALSE;
}
-BOOL LLObjectBridge::isItemRemovable()
-{
- LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
- if(!avatar) return FALSE;
- if(avatar->isWearingAttachment(mUUID)) return FALSE;
- return LLInvFVBridge::isItemRemovable();
-}
-
LLUIImagePtr LLObjectBridge::getIcon() const
{
return get_item_icon(LLAssetType::AT_OBJECT, mInvType, mAttachPt, mIsMultiObject );
@@ -4299,12 +4306,6 @@ BOOL LLWearableBridge::renameItem(const std::string& new_name)
return LLItemBridge::renameItem(new_name);
}
-BOOL LLWearableBridge::isItemRemovable()
-{
- if (gAgentWearables.isWearingItem(mUUID)) return FALSE;
- return LLInvFVBridge::isItemRemovable();
-}
-
std::string LLWearableBridge::getLabelSuffix() const
{
if( gAgentWearables.isWearingItem( mUUID ) )
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 49e64ebdde..7534548894 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -508,7 +508,6 @@ public:
virtual LLFontGL::StyleFlags getLabelStyle() const;
virtual std::string getLabelSuffix() const;
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
- virtual BOOL isItemRemovable();
virtual BOOL renameItem(const std::string& new_name);
LLInventoryObject* getObject() const;
@@ -546,7 +545,6 @@ public:
virtual void openItem();
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
virtual std::string getLabelSuffix() const;
- virtual BOOL isItemRemovable();
virtual BOOL renameItem(const std::string& new_name);
static void onWearOnAvatar( void* userdata ); // Access to wearOnAvatar() from menu
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index fbaab385fe..9e37c5be38 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -1118,9 +1118,16 @@ BOOL LLInventoryModel::containsObserver(LLInventoryObserver* observer) const
return mObservers.find(observer) != mObservers.end();
}
-// Call this method when it's time to update everyone on a new state,
-// by default, the inventory model will not update observers
-// automatically.
+void LLInventoryModel::idleNotifyObservers()
+{
+ if (mModifyMask == LLInventoryObserver::NONE && (mChangedItemIDs.size() == 0))
+ {
+ return;
+ }
+ notifyObservers("");
+}
+
+// Call this method when it's time to update everyone on a new state.
// The optional argument 'service_name' is used by Agent Inventory Service [DEV-20328]
void LLInventoryModel::notifyObservers(const std::string service_name)
{
@@ -1133,13 +1140,6 @@ void LLInventoryModel::notifyObservers(const std::string service_name)
return;
}
- if ((mModifyMask == LLInventoryObserver::NONE) && (service_name == ""))
- {
- mModifyMask = LLInventoryObserver::NONE;
- mChangedItemIDs.clear();
- return;
- }
-
mIsNotifyObservers = TRUE;
for (observer_list_t::iterator iter = mObservers.begin();
iter != mObservers.end(); )
@@ -3308,8 +3308,7 @@ void LLInventoryModel::processInventoryDescendents(LLMessageSystem* msg,void**)
msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
if(agent_id != gAgent.getID())
{
- llwarns << "Got a UpdateInventoryItem for the wrong agent."
- << llendl;
+ llwarns << "Got a UpdateInventoryItem for the wrong agent." << llendl;
return;
}
LLUUID parent_id;
@@ -3320,6 +3319,7 @@ void LLInventoryModel::processInventoryDescendents(LLMessageSystem* msg,void**)
msg->getS32("AgentData", "Version", version);
S32 descendents;
msg->getS32("AgentData", "Descendents", descendents);
+
S32 i;
S32 count = msg->getNumberOfBlocksFast(_PREHASH_FolderData);
LLPointer<LLViewerInventoryCategory> tcategory = new LLViewerInventoryCategory(owner_id);
@@ -3349,6 +3349,9 @@ void LLInventoryModel::processInventoryDescendents(LLMessageSystem* msg,void**)
{
cat->setVersion(version);
cat->setDescendentCount(descendents);
+ // Get this UUID on the changed list so that whatever's listening for it
+ // will get triggered.
+ gInventory.addChangedMask(LLInventoryObserver::INTERNAL, cat->getUUID());
}
gInventory.notifyObservers();
}
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index da12dbdf7f..50f54cb842 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -252,9 +252,12 @@ public:
// multiple trash can bug.
const LLUUID findCategoryUUIDForType(LLFolderType::EType preferred_type, bool create_folder = true, bool find_in_library = false);
- // Call this method when it's time to update everyone on a new
- // state, by default, the inventory model will not update
- // observers automatically.
+ // This gets called by the idle loop. It only updates if new
+ // state is detected. Call notifyObservers() manually to update
+ // regardless of whether state change has been indicated.
+ void idleNotifyObservers();
+
+ // Call this method to explicitly update everyone on a new state.
// The optional argument 'service_name' is used by Agent Inventory Service [DEV-20328]
void notifyObservers(const std::string service_name="");