From 08cbeea3c72be69137b7ca7d4a95cc7d80fc176e Mon Sep 17 00:00:00 2001 From: Loren Shih Date: Tue, 17 Nov 2009 15:03:14 -0500 Subject: EXT-2583 : Some sidepanel inventory folders appear blank Starting sidepanel inventory folders as open by default. Also did some minor syntactic cleanup on the folder filter iterators. --HG-- branch : avatar-pipeline --- indra/newview/llfolderviewitem.cpp | 40 ++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 17 deletions(-) (limited to 'indra/newview/llfolderviewitem.cpp') diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp index bf74c5c936..1096f25f0c 100644 --- a/indra/newview/llfolderviewitem.cpp +++ b/indra/newview/llfolderviewitem.cpp @@ -1253,6 +1253,10 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter) // filter self only on first pass through LLFolderViewItem::filter( filter ); } + if (mDontShowInHierarchy) + { + setOpen(); + } } if (getRoot()->getDebugFilters()) @@ -1286,9 +1290,10 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter) // now query children for (folders_t::iterator iter = mFolders.begin(); - iter != mFolders.end();) + iter != mFolders.end(); + ++iter) { - folders_t::iterator fit = iter++; + LLFolderViewFolder* folder = (*iter); // have we run out of iterations this frame? if (filter.getFilterCount() < 0) { @@ -1298,15 +1303,15 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter) // mMostFilteredDescendantGeneration might have been reset // in which case we need to update it even for folders that // don't need to be filtered anymore - if ((*fit)->getCompletedFilterGeneration() >= filter_generation) + if (folder->getCompletedFilterGeneration() >= filter_generation) { // track latest generation to pass any child items - if ((*fit)->getFiltered() || (*fit)->hasFilteredDescendants(filter.getMinRequiredGeneration())) + if (folder->getFiltered() || folder->hasFilteredDescendants(filter.getMinRequiredGeneration())) { mMostFilteredDescendantGeneration = filter_generation; if (getRoot()->needsAutoSelect() && autoopen_folders) { - (*fit)->setOpenArrangeRecursively(TRUE); + folder->setOpenArrangeRecursively(TRUE); } } // just skip it, it has already been filtered @@ -1314,48 +1319,49 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter) } // update this folders filter status (and children) - (*fit)->filter( filter ); + folder->filter( filter ); // track latest generation to pass any child items - if ((*fit)->getFiltered() || (*fit)->hasFilteredDescendants(filter_generation)) + if (folder->getFiltered() || folder->hasFilteredDescendants(filter_generation)) { mMostFilteredDescendantGeneration = filter_generation; if (getRoot()->needsAutoSelect() && autoopen_folders) { - (*fit)->setOpenArrangeRecursively(TRUE); + folder->setOpenArrangeRecursively(TRUE); } } } for (items_t::iterator iter = mItems.begin(); - iter != mItems.end();) + iter != mItems.end(); + ++iter) { - items_t::iterator iit = iter++; + LLFolderViewItem* item = (*iter); if (filter.getFilterCount() < 0) { break; } - if ((*iit)->getLastFilterGeneration() >= filter_generation) + if (item->getLastFilterGeneration() >= filter_generation) { - if ((*iit)->getFiltered()) + if (item->getFiltered()) { mMostFilteredDescendantGeneration = filter_generation; } continue; } - if ((*iit)->getLastFilterGeneration() >= must_pass_generation && - !(*iit)->getFiltered(must_pass_generation)) + if (item->getLastFilterGeneration() >= must_pass_generation && + !item->getFiltered(must_pass_generation)) { // failed to pass an earlier filter that was a subset of the current one // go ahead and flag this item as done - (*iit)->setFiltered(FALSE, filter_generation); + item->setFiltered(FALSE, filter_generation); continue; } - (*iit)->filter( filter ); + item->filter( filter ); - if ((*iit)->getFiltered(filter.getMinRequiredGeneration())) + if (item->getFiltered(filter.getMinRequiredGeneration())) { mMostFilteredDescendantGeneration = filter_generation; } -- cgit v1.3 From ad86caf4790d45b0d7c6776c9f840e3023c52033 Mon Sep 17 00:00:00 2001 From: Loren Shih Date: Thu, 19 Nov 2009 17:56:30 -0500 Subject: EXT-2668 : Screwy logic for figuring out if a folder is removable EXT-2661 : "Remove From Outfit" on COF doesn't take off my outfit EXT-2662 : Can't delete a worn item link Cleaned up the whole "isItemRemovable" logic, and having folders figure this out recursively via children. Changed the isItemRemovable logic so that links aren't treated as worn for the purposes of deletion. --HG-- branch : avatar-pipeline --- indra/newview/llfolderviewitem.cpp | 16 +++++++ indra/newview/llfolderviewitem.h | 3 ++ indra/newview/llinventorybridge.cpp | 94 ++++++++++++++++++------------------- indra/newview/llinventorybridge.h | 2 - 4 files changed, 64 insertions(+), 51 deletions(-) (limited to 'indra/newview/llfolderviewitem.cpp') 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..578cf7bebc 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 @@ -1303,6 +1320,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 +1368,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(mInventoryPanel.get()); + LLFolderViewFolder* folderp = dynamic_cast(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; } @@ -3772,14 +3782,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 +4301,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 -- cgit v1.3 From 2b54c8a084a3f387d6f15b9d4f61d8cb68b434e0 Mon Sep 17 00:00:00 2001 From: Loren Shih Date: Mon, 23 Nov 2009 17:46:30 -0500 Subject: EXT-2763 : Right-click on inventory doesn't bring up context menu Also did some minor cleanup on header files. --HG-- branch : avatar-pipeline --- indra/newview/llfolderview.cpp | 6 ++++-- indra/newview/llfolderview.h | 38 ++++++++++++++++---------------------- indra/newview/llfolderviewitem.cpp | 2 +- indra/newview/llinventorypanel.cpp | 28 +++++++++++----------------- indra/newview/llinventorypanel.h | 35 +++++++++++++++-------------------- 5 files changed, 47 insertions(+), 62 deletions(-) (limited to 'indra/newview/llfolderviewitem.cpp') diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index c9c4c76da4..3138b5b26f 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -44,6 +44,7 @@ #include "llkeyboard.h" #include "lllineeditor.h" #include "llmenugl.h" +#include "llpanel.h" #include "llpreview.h" #include "llscrollcontainer.h" // hack to allow scrolling #include "lltooldraganddrop.h" @@ -2014,12 +2015,13 @@ static LLFastTimer::DeclareTimer FTM_INVENTORY("Inventory"); // Main idle routine void LLFolderView::doIdle() { - // Don't do anything until the inventory is loaded up. + // Don't do anything until the inventory is usable and loaded up. + // Seraph: Change this to calling mParentPanel->isViewsInitialized if (!gInventory.isInventoryUsable()) { return; } - + LLFastTimer t2(FTM_INVENTORY); BOOL debug_filters = gSavedSettings.getBOOL("DebugInventoryFilters"); diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h index 0bd65b5f90..a0e252ae88 100644 --- a/indra/newview/llfolderview.h +++ b/indra/newview/llfolderview.h @@ -41,25 +41,27 @@ #ifndef LL_LLFOLDERVIEW_H #define LL_LLFOLDERVIEW_H -// JAMESDEBUG - trim this list -#include -#include -#include -#include -#include +#include "llfolderviewitem.h" // because LLFolderView is-a LLFolderViewFolder #include "lluictrl.h" #include "v4color.h" #include "lldarray.h" -//#include "llviewermenu.h" #include "stdenums.h" -#include "llfontgl.h" -#include "lleditmenuhandler.h" -#include "llviewertexture.h" #include "lldepthstack.h" +#include "lleditmenuhandler.h" +#include "llfontgl.h" #include "lltooldraganddrop.h" -// JAMESDEBUG - move this up -#include "llfolderviewitem.h" // because LLFolderView is-a LLFolderViewFolder +#include "llviewertexture.h" + +class LLFolderViewEventListener; +class LLFolderViewFolder; +class LLFolderViewItem; +class LLInventoryModel; +class LLPanel; +class LLLineEditor; +class LLMenuGL; +class LLScrollContainer; +class LLUICtrl; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLFolderViewFunctor @@ -70,8 +72,7 @@ // that later when it's determined to be too slow. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -class LLFolderViewItem; -class LLFolderViewFolder; + class LLFolderViewFunctor { @@ -89,13 +90,6 @@ public: // manages the screen region of the folder view. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -class LLFolderViewEventListener; -class LLInventoryModel; -class LLLineEditor; -class LLMenuGL; -class LLScrollContainer; -class LLUICtrl; - class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler { public: @@ -330,7 +324,7 @@ protected: LLUUID mSelectThisID; // if non null, select this item - LLPanel* mParentPanel; + LLPanel* mParentPanel; /** * Is used to determine if we need to cut text In LLFolderViewItem to avoid horizontal scroll. diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp index 41e3279795..420dba07fe 100644 --- a/indra/newview/llfolderviewitem.cpp +++ b/indra/newview/llfolderviewitem.cpp @@ -38,12 +38,12 @@ #include "llfoldervieweventlistener.h" #include "llinventorybridge.h" // for LLItemBridge in LLInventorySort::operator() #include "llinventoryfilter.h" +#include "llpanel.h" #include "llviewercontrol.h" // gSavedSettings #include "llviewerwindow.h" // Argh, only for setCursor() // linden library includes #include "llfocusmgr.h" // gFocusMgr -#include "llpanel.h" // panel->hasFocus() #include "lltrans.h" ///---------------------------------------------------------------------------- diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index e4dd70cdd1..47201b2ccc 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -78,7 +78,7 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) : mSortOrderSetting(p.sort_order_setting), mInventory(p.inventory), mAllowMultiSelect(p.allow_multi_select), - mHasInventoryConnection(false), + mViewsInitialized(false), mStartFolderString(p.start_folder), mBuildDefaultHierarchy(true), mInvFVBridgeBuilder(NULL) @@ -151,11 +151,9 @@ BOOL LLInventoryPanel::postBuild() mInventory->addObserver(mInventoryObserver); // build view of inventory if we need default full hierarchy and inventory ready, otherwise wait for modelChanged() callback - if (mBuildDefaultHierarchy && mInventory->isInventoryUsable() && !mHasInventoryConnection) + if (mBuildDefaultHierarchy && mInventory->isInventoryUsable() && !mViewsInitialized) { - generateViews(); - mHasInventoryConnection = true; - defaultOpenInventory(); + initializeViews(); } if (mSortOrderSetting != INHERIT_SORT_ORDER) @@ -258,11 +256,9 @@ void LLInventoryPanel::modelChanged(U32 mask) bool handled = false; // inventory just initialized, do complete build - if ((mask & LLInventoryObserver::ADD) && mInventory->isInventoryUsable() && gInventory.getChangedIDs().empty() && !mHasInventoryConnection) + if ((mask & LLInventoryObserver::ADD) && mInventory->isInventoryUsable() && gInventory.getChangedIDs().empty() && !mViewsInitialized) { - generateViews(); - mHasInventoryConnection = true; - defaultOpenInventory(); + initializeViews(); return; } @@ -372,11 +368,10 @@ void LLInventoryPanel::modelChanged(U32 mask) } -void LLInventoryPanel::generateViews() +void LLInventoryPanel::initializeViews() { - - // Blow away the entire previous UI tree. - mFolders->getRoot()->destroyView(); + if (!gInventory.isInventoryUsable()) + return; // Determine the root folder in case specified, and // build the views starting with that folder. @@ -392,6 +387,9 @@ void LLInventoryPanel::generateViews() } llinfos << this << " Generating views for start folder " << mStartFolderString << llendl; rebuildViewsFor(mStartFolderID); + + mViewsInitialized = true; + defaultOpenInventory(); } void LLInventoryPanel::rebuildViewsFor(const LLUUID& id) @@ -426,10 +424,6 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id) return; } - if (objectp->getName() == "My Inventory") - { - llinfos << this << " Adding MyInventory for start folder " << mStartFolderString << llendl; - } if (objectp->getType() <= LLAssetType::AT_NONE || objectp->getType() >= LLAssetType::AT_COUNT) { diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index 41f393c660..5b1104936d 100644 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -161,9 +161,6 @@ public: void unSelectAll() { mFolders->setSelection(NULL, FALSE, FALSE); } private: - // Destroys the old views, and regenerates them based on the - // start folder ID. - void generateViews(); // Given the id and the parent, build all of the folder views. void rebuildViewsFor(const LLUUID& id); @@ -176,25 +173,8 @@ protected: BOOL mAllowMultiSelect; std::string mSortOrderSetting; -//private: // Can not make these private - needed by llinventorysubtreepanel LLFolderView* mFolders; - std::string mStartFolderString; - - /** - * Contains UUID of Inventory item from which hierarchy should be built. - * Can be set with the "start_folder" xml property. - * Default is LLUUID::null that means total Inventory hierarchy. - */ - LLUUID mStartFolderID; LLScrollContainer* mScroller; - bool mHasInventoryConnection; - - /** - * Flag specified if default inventory hierarchy should be created in postBuild() - */ - bool mBuildDefaultHierarchy; - - LLUUID mRootInventoryItemUUID; /** * Pointer to LLInventoryFVBridgeBuilder. @@ -205,6 +185,21 @@ protected: */ const LLInventoryFVBridgeBuilder* mInvFVBridgeBuilder; + //-------------------------------------------------------------------- + // Initialization routines for building up the UI ("views") + //-------------------------------------------------------------------- +public: + BOOL getIsViewsInitialized() const { return mViewsInitialized; } +private: + // Builds the UI. Call this once the inventory is usable. + void initializeViews(); + BOOL mBuildDefaultHierarchy; // default inventory hierarchy should be created in postBuild() + BOOL mViewsInitialized; // Views have been generated + + // UUID of category from which hierarchy should be built. Set with the + // "start_folder" xml property. Default is LLUUID::null that means total Inventory hierarchy. + std::string mStartFolderString; + LLUUID mStartFolderID; }; #endif // LL_LLINVENTORYPANEL_H -- cgit v1.3