diff options
author | Richard Linden <none@none> | 2012-07-02 17:57:29 -0700 |
---|---|---|
committer | Richard Linden <none@none> | 2012-07-02 17:57:29 -0700 |
commit | 1bd52dfbdc3607bbd9ea86c715ce63b17d5a557f (patch) | |
tree | 6fffd9003c6c9f9a6421603f3552082ec7f12e4a | |
parent | 062cae9a4880f7672df7f6189e01b2bff15f42f1 (diff) |
CHUI-101 WIP Make LLFolderView general purpose
refactored source files, moving logic into llfolderviewmodel*.cpp
filter logic tweaks
purging and moving inventory now properly cleans up view model
-rw-r--r-- | indra/newview/CMakeLists.txt | 3 | ||||
-rw-r--r-- | indra/newview/llfolderview.cpp | 27 | ||||
-rw-r--r-- | indra/newview/llfolderviewitem.cpp | 19 | ||||
-rw-r--r-- | indra/newview/llfolderviewitem.h | 10 | ||||
-rw-r--r-- | indra/newview/llfolderviewmodel.cpp | 54 | ||||
-rw-r--r-- | indra/newview/llfolderviewmodel.h | 25 | ||||
-rw-r--r-- | indra/newview/llfolderviewmodelinventory.cpp | 225 | ||||
-rw-r--r-- | indra/newview/llfolderviewmodelinventory.h | 107 | ||||
-rw-r--r-- | indra/newview/llinventoryfilter.cpp | 24 | ||||
-rw-r--r-- | indra/newview/llinventorypanel.cpp | 201 | ||||
-rw-r--r-- | indra/newview/llinventorypanel.h | 78 | ||||
-rw-r--r-- | indra/newview/lltexturectrl.cpp | 4 |
12 files changed, 429 insertions, 348 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 4f447fd35b..dee37bd5e8 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -253,6 +253,8 @@ set(viewer_SOURCE_FILES llfloaterworldmap.cpp llfolderview.cpp llfolderviewitem.cpp + llfolderviewmodel.cpp + llfolderviewmodelinventory.cpp llfollowcam.cpp llfriendcard.cpp llgesturelistener.cpp @@ -809,6 +811,7 @@ set(viewer_HEADER_FILES llfloaterworldmap.h llfolderview.h llfolderviewmodel.h + llfolderviewmodelinventory.h llfolderviewitem.h llfollowcam.h llfriendcard.h diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index 5844c58e09..90c78d98b0 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -259,7 +259,7 @@ LLFolderView::LLFolderView(const Params& p) menu->setBackgroundColor(LLUIColorTable::instance().getColor("MenuPopupBgColor")); mPopupMenuHandle = menu->getHandle(); - mListener->openItem(); + mViewModelItem->openItem(); } // Destroys the object @@ -363,11 +363,7 @@ void LLFolderView::filter( LLFolderViewFilter& filter ) LLFastTimer t2(FTM_FILTER); filter.setFilterCount(llclamp(gSavedSettings.getS32("FilterItemsPerFrame"), 1, 5000)); - if (getLastFilterGeneration() < filter.getCurrentGeneration()) - { - mMinWidth = 0; - getViewModelItem()->filter(filter); - } + getViewModelItem()->filter(filter); } void LLFolderView::reshape(S32 width, S32 height, BOOL called_from_parent) @@ -706,20 +702,11 @@ void LLFolderView::draw() if (hasVisibleChildren()) { - mStatusText.clear(); mStatusTextBox->setVisible( FALSE ); } else if (mShowEmptyMessage) { - if (!mViewModel->contentsReady() || getLastFilterGeneration() < getFolderViewModel()->getFilter()->getFirstSuccessGeneration()) - { - mStatusText = LLTrans::getString("Searching"); - } - else - { - mStatusText = getFolderViewModel()->getFilter()->getEmptyLookupMessage(); - } - mStatusTextBox->setValue(mStatusText); + mStatusTextBox->setValue(getFolderViewModel()->getStatusText()); mStatusTextBox->setVisible( TRUE ); // firstly reshape message textbox with current size. This is necessary to @@ -1971,7 +1958,7 @@ void LLFolderView::doIdle() scrollToShowSelection(); } - BOOL filter_finished = getLastFilterGeneration() >= getFolderViewModel()->getFilter()->getCurrentGeneration() + BOOL filter_finished = getViewModelItem()->passedFilter() && mViewModel->contentsReady(); if (filter_finished || gFocusMgr.childHasKeyboardFocus(inventory_panel) @@ -2264,9 +2251,3 @@ S32 LLFolderView::getItemHeight() } return 0; } - -//TODO RN: move to llfolderviewmodel.cpp file -bool LLFolderViewModelCommon::needsSort(LLFolderViewModelItem* item) -{ - return item->getSortVersion() < mTargetSortVersion; -} diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp index 685a4cbf49..ac389c9189 100644 --- a/indra/newview/llfolderviewitem.cpp +++ b/indra/newview/llfolderviewitem.cpp @@ -120,12 +120,12 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p) mDragAndDropTarget(FALSE), mLabel(p.name), mRoot(p.root), - mListener(p.listener), + mViewModelItem(p.listener), mIsMouseOverTitle(false) { - if (mListener) + if (mViewModelItem) { - mListener->setFolderViewItem(this); + mViewModelItem->setFolderViewItem(this); } } @@ -138,8 +138,8 @@ BOOL LLFolderViewItem::postBuild() // Destroys the object LLFolderViewItem::~LLFolderViewItem( void ) { - delete mListener; - mListener = NULL; + delete mViewModelItem; + mViewModelItem = NULL; } LLFolderView* LLFolderViewItem::getRoot() @@ -837,12 +837,6 @@ LLFolderViewModelInterface* LLFolderViewItem::getFolderViewModel( void ) return getRoot()->getFolderViewModel(); } -S32 LLFolderViewItem::getLastFilterGeneration() const -{ - return getViewModelItem()->getLastFilterGeneration(); -} - - ///---------------------------------------------------------------------------- /// Class LLFolderViewFolder @@ -1446,6 +1440,7 @@ void LLFolderViewFolder::extractItem( LLFolderViewItem* item ) mItems.erase(it); } //item has been removed, need to update filter + getViewModelItem()->removeChild(item->getViewModelItem()); getViewModelItem()->dirtyFilter(); //because an item is going away regardless of filter status, force rearrange requestArrange(); @@ -1638,7 +1633,7 @@ BOOL LLFolderViewFolder::handleDragAndDropFromChild(MASK mask, EAcceptance* accept, std::string& tooltip_msg) { - BOOL accepted = mListener->dragOrDrop(mask,drop,c_type,cargo_data, tooltip_msg); + BOOL accepted = mViewModelItem->dragOrDrop(mask,drop,c_type,cargo_data, tooltip_msg); if (accepted) { mDragAndDropTarget = TRUE; diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h index a3c92a55e8..581ec7239e 100644 --- a/indra/newview/llfolderviewitem.h +++ b/indra/newview/llfolderviewitem.h @@ -92,13 +92,12 @@ protected: S32 mLabelWidth; bool mLabelWidthDirty; LLFolderViewFolder* mParentFolder; - LLFolderViewModelItem* mListener; + LLFolderViewModelItem* mViewModelItem; BOOL mIsCurSelection; BOOL mSelectPending; LLFontGL::StyleFlags mLabelStyle; std::string mLabelSuffix; LLUIImagePtr mIcon; - std::string mStatusText; LLUIImagePtr mIconOpen; LLUIImagePtr mIconOverlay; BOOL mHasVisibleChildren; @@ -136,9 +135,6 @@ public: virtual S32 arrange( S32* width, S32* height ); virtual S32 getItemHeight(); - // updates filter serial number and optionally propagated value up to root - S32 getLastFilterGeneration() const; - // If 'selection' is 'this' then note that otherwise ignore. // Returns TRUE if this item ends up being selected. virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus); @@ -202,8 +198,8 @@ public: LLFolderViewItem* getNextOpenNode( BOOL include_children = TRUE ); LLFolderViewItem* getPreviousOpenNode( BOOL include_children = TRUE ); - const LLFolderViewModelItem* getViewModelItem( void ) const { return mListener; } - LLFolderViewModelItem* getViewModelItem( void ) { return mListener; } + const LLFolderViewModelItem* getViewModelItem( void ) const { return mViewModelItem; } + LLFolderViewModelItem* getViewModelItem( void ) { return mViewModelItem; } const LLFolderViewModelInterface* getFolderViewModel( void ) const; LLFolderViewModelInterface* getFolderViewModel( void ); diff --git a/indra/newview/llfolderviewmodel.cpp b/indra/newview/llfolderviewmodel.cpp new file mode 100644 index 0000000000..92db84156e --- /dev/null +++ b/indra/newview/llfolderviewmodel.cpp @@ -0,0 +1,54 @@ +/** + * @file llfolderviewmodel.cpp + * @brief Implementation of the view model collection of classes. + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfolderviewmodel.h" +#include "lltrans.h" +#include "llviewercontrol.h" + +bool LLFolderViewModelCommon::needsSort(LLFolderViewModelItem* item) +{ + return item->getSortVersion() < mTargetSortVersion; +} + +std::string LLFolderViewModelCommon::getStatusText() +{ + if (!contentsReady() || mFolderView->getViewModelItem()->getLastFilterGeneration() < getFilter()->getCurrentGeneration()) + { + return LLTrans::getString("Searching"); + } + else + { + return getFilter()->getEmptyLookupMessage(); + } +} + +void LLFolderViewModelCommon::filter() +{ + getFilter()->setFilterCount(llclamp(gSavedSettings.getS32("FilterItemsPerFrame"), 1, 5000)); + mFolderView->getViewModelItem()->filter(*getFilter()); +} diff --git a/indra/newview/llfolderviewmodel.h b/indra/newview/llfolderviewmodel.h index 5304613219..8a16ec3eff 100644 --- a/indra/newview/llfolderviewmodel.h +++ b/indra/newview/llfolderviewmodel.h @@ -28,6 +28,7 @@ #include "lldarray.h" // *TODO: convert to std::vector #include "llfoldertype.h" #include "llfontgl.h" // just for StyleFlags enum +#include "llfolderview.h" #include "llfolderviewitem.h" #include "llinventorytype.h" #include "llpermissionsflags.h" @@ -122,11 +123,13 @@ public: virtual void requestSortAll() = 0; virtual void sort(class LLFolderViewFolder*) = 0; + virtual void filter() = 0; virtual bool contentsReady() = 0; virtual void setFolderView(LLFolderView* folder_view) = 0; virtual LLFolderViewFilter* getFilter() = 0; virtual const LLFolderViewFilter* getFilter() const = 0; + virtual std::string getStatusText() = 0; }; class LLFolderViewModelCommon : public LLFolderViewModelInterface @@ -142,6 +145,8 @@ public: // sort everything mTargetSortVersion++; } + virtual std::string getStatusText(); + virtual void filter(); void setFolderView(LLFolderView* folder_view) { mFolderView = folder_view;} @@ -177,6 +182,7 @@ public: // add getStatusText and isFiltering() virtual bool contentsReady() { return true; } + struct ViewModelCompare { ViewModelCompare(const SortType& sorter) @@ -272,6 +278,7 @@ public: virtual bool hasChildren() const = 0; virtual void addChild(LLFolderViewModelItem* child) = 0; + virtual void removeChild(LLFolderViewModelItem* child) = 0; // This method will be called to determine if a drop can be // performed, and will set drop to TRUE if a drop is @@ -305,7 +312,9 @@ public: mLastFilterGeneration(-1), mMostFilteredDescendantGeneration(-1), mParent(NULL) - {} + { + std::for_each(mChildren.begin(), mChildren.end(), DeletePointer()); + } void requestSort() { mSortVersion = -1; } S32 getSortVersion() { return mSortVersion; } @@ -315,13 +324,23 @@ public: void dirtyFilter() { mLastFilterGeneration = -1; + // bubble up dirty flag all the way to root if (mParent) { mParent->dirtyFilter(); - } + } + } + virtual void addChild(LLFolderViewModelItem* child) + { + mChildren.push_back(child); + child->setParent(this); + } + virtual void removeChild(LLFolderViewModelItem* child) + { + mChildren.remove(child); + child->setParent(NULL); } - virtual void addChild(LLFolderViewModelItem* child) { mChildren.push_back(child); child->setParent(this); } protected: virtual void setParent(LLFolderViewModelItem* parent) { mParent = parent; } diff --git a/indra/newview/llfolderviewmodelinventory.cpp b/indra/newview/llfolderviewmodelinventory.cpp new file mode 100644 index 0000000000..7ee1a10b15 --- /dev/null +++ b/indra/newview/llfolderviewmodelinventory.cpp @@ -0,0 +1,225 @@ +/* + * @file llfolderviewmodelinventory.cpp + * @brief Implementation of the inventory-specific view model + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llfolderviewmodelinventory.h" +#include "llinventorymodelbackgroundfetch.h" +#include "llinventorypanel.h" + +// +// class LLFolderViewModelInventory +// +static LLFastTimer::DeclareTimer FTM_INVENTORY_SORT("Sort"); + +void LLFolderViewModelInventory::sort( LLFolderViewFolder* folder ) +{ + LLFastTimer _(FTM_INVENTORY_SORT); + + if (!needsSort(folder->getViewModelItem())) return; + + LLFolderViewModelItemInventory* modelp = static_cast<LLFolderViewModelItemInventory*>(folder->getViewModelItem()); + if (modelp->getUUID().isNull()) return; + + for (std::list<LLFolderViewFolder*>::iterator it = folder->getFoldersBegin(), end_it = folder->getFoldersEnd(); + it != end_it; + ++it) + { + LLFolderViewFolder* child_folderp = *it; + sort(child_folderp); + + if (child_folderp->getFoldersCount() > 0) + { + time_t most_recent_folder_time = + static_cast<LLFolderViewModelItemInventory*>((*child_folderp->getFoldersBegin())->getViewModelItem())->getCreationDate(); + LLFolderViewModelItemInventory* modelp = static_cast<LLFolderViewModelItemInventory*>(child_folderp->getViewModelItem()); + if (most_recent_folder_time > modelp->getCreationDate()) + { + modelp->setCreationDate(most_recent_folder_time); + } + } + if (child_folderp->getItemsCount() > 0) + { + time_t most_recent_item_time = + static_cast<LLFolderViewModelItemInventory*>((*child_folderp->getItemsBegin())->getViewModelItem())->getCreationDate(); + + LLFolderViewModelItemInventory* modelp = static_cast<LLFolderViewModelItemInventory*>(child_folderp->getViewModelItem()); + if (most_recent_item_time > modelp->getCreationDate()) + { + modelp->setCreationDate(most_recent_item_time); + } + } + } + base_t::sort(folder); +} + +bool LLFolderViewModelInventory::contentsReady() +{ + return !LLInventoryModelBackgroundFetch::instance().folderFetchActive(); +} + +void LLFolderViewModelItemInventory::requestSort() +{ + LLFolderViewModelItemCommon::requestSort(); + if (mRootViewModel->getSorter().isByDate()) + { + // sort by date potentially affects parent folders which use a date + // derived from newest item in them + if (mParent) + { + mParent->requestSort(); + } + } +} + +bool LLFolderViewModelItemInventory::potentiallyVisible() +{ + return passedFilter() // we've passed the filter + || getLastFilterGeneration() < mRootViewModel->getFilter()->getFirstSuccessGeneration() // or we don't know yet + || descendantsPassedFilter(); +} + +bool LLFolderViewModelItemInventory::passedFilter(S32 filter_generation) +{ + if (filter_generation < 0 && mRootViewModel) + filter_generation = mRootViewModel->getFilter()->getFirstSuccessGeneration(); + + return mPassedFolderFilter + && mLastFilterGeneration >= filter_generation + && (mPassedFilter || descendantsPassedFilter(filter_generation)); +} + +bool LLFolderViewModelItemInventory::descendantsPassedFilter(S32 filter_generation) +{ + if (filter_generation < 0) filter_generation = mRootViewModel->getFilter()->getFirstSuccessGeneration(); + return mMostFilteredDescendantGeneration >= filter_generation; +} + +void LLFolderViewModelItemInventory::setPassedFilter(bool passed, bool passed_folder, S32 filter_generation) +{ + mPassedFilter = passed; + mPassedFolderFilter = passed_folder; + mLastFilterGeneration = filter_generation; +} + +bool LLFolderViewModelItemInventory::filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter ) +{ + bool passed_filter_before = item->passedFilter(); + S32 filter_generation = filter.getCurrentGeneration(); + S32 must_pass_generation = filter.getFirstRequiredGeneration(); + + if (item->getLastFilterGeneration() < filter_generation) + { + if (item->getLastFilterGeneration() >= must_pass_generation + && !item->passedFilter(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 + item->filter(filter); + if (item->passedFilter()) + { + llerrs << "Invalid shortcut in inventory filtering!" << llendl; + } + item->setPassedFilter(false, false, filter_generation); + } + else + { + item->filter( filter ); + } + } + + // track latest generation to pass any child items, for each folder up to root + if (item->passedFilter()) + { + LLFolderViewModelItemInventory* view_model = this; + + while(view_model && view_model->mMostFilteredDescendantGeneration < filter_generation) + { + view_model->mMostFilteredDescendantGeneration = filter_generation; + view_model = static_cast<LLFolderViewModelItemInventory*>(view_model->mParent); + } + + return !passed_filter_before; + } + else // !item->passedfilter() + { + return passed_filter_before; + } +} + +bool LLFolderViewModelItemInventory::filter( LLFolderViewFilter& filter) +{ + bool changed = false; + + if(!mChildren.empty() + && (getLastFilterGeneration() < filter.getFirstRequiredGeneration() // haven't checked descendants against minimum required generation to pass + || descendantsPassedFilter(filter.getFirstRequiredGeneration()))) // or at least one descendant has passed the minimum requirement + { + // now query children + for (child_list_t::iterator iter = mChildren.begin(); + iter != mChildren.end() && filter.getFilterCount() > 0; + ++iter) + { + changed |= filterChildItem((*iter), filter); + } + } + + if (changed) + { + //TODO RN: ensure this still happens, but without dependency on folderview + LLFolderViewFolder* folder = static_cast<LLFolderViewFolder*>(mFolderViewItem); + folder->requestArrange(); + } + + // if we didn't use all filter iterations + // that means we filtered all of our descendants + // so filter ourselves now + if (filter.getFilterCount() > 0) + { + filter.decrementFilterCount(); + + const BOOL passed_filter = filter.check(this); + const BOOL passed_filter_folder = (getInventoryType() == LLInventoryType::IT_CATEGORY) + ? filter.checkFolder(this) + : true; + + setPassedFilter(passed_filter, passed_filter_folder, filter.getCurrentGeneration()); + //TODO RN: create interface for string highlighting + //mStringMatchOffset = filter.getStringMatchOffset(this); + } + return changed; +} + +LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel() +{ + return &mInventoryViewModel; +} + + +const LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel() const +{ + return &mInventoryViewModel; +} + diff --git a/indra/newview/llfolderviewmodelinventory.h b/indra/newview/llfolderviewmodelinventory.h new file mode 100644 index 0000000000..a8fe3f57ea --- /dev/null +++ b/indra/newview/llfolderviewmodelinventory.h @@ -0,0 +1,107 @@ +/** + * @file llfolderviewmodelinventory.h + * @brief view model implementation specific to inventory + * class definition + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLFOLDERVIEWMODELINVENTORY_H +#define LL_LLFOLDERVIEWMODELINVENTORY_H + +#include "llinventoryfilter.h" + +class LLFolderViewModelItemInventory + : public LLFolderViewModelItemCommon +{ +public: + LLFolderViewModelItemInventory() + : mRootViewModel(NULL) + {} + void setRootViewModel(class LLFolderViewModelInventory* root_view_model) + { + mRootViewModel = root_view_model; + } + virtual const LLUUID& getUUID() const = 0; + virtual time_t getCreationDate() const = 0; // UTC seconds + virtual void setCreationDate(time_t creation_date_utc) = 0; + virtual PermissionMask getPermissionMask() const = 0; + virtual LLFolderType::EType getPreferredType() const = 0; + virtual void showProperties(void) = 0; + virtual BOOL isItemInTrash( void) const { return FALSE; } // TODO: make into pure virtual. + virtual BOOL isUpToDate() const = 0; + virtual bool hasChildren() const = 0; + virtual LLInventoryType::EType getInventoryType() const = 0; + virtual void performAction(LLInventoryModel* model, std::string action) = 0; + virtual LLWearableType::EType getWearableType() const = 0; + virtual EInventorySortGroup getSortGroup() const = 0; + virtual LLInventoryObject* getInventoryObject() const = 0; + virtual void requestSort(); + virtual bool potentiallyVisible(); + virtual bool passedFilter(S32 filter_generation = -1); + virtual bool descendantsPassedFilter(S32 filter_generation = -1); + virtual void setPassedFilter(bool filtered, bool filtered_folder, S32 filter_generation); + virtual bool filter( LLFolderViewFilter& filter); + virtual bool filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter); +protected: + class LLFolderViewModelInventory* mRootViewModel; +}; + +class LLInventorySort +{ +public: + LLInventorySort(U32 order = 0) + : mSortOrder(order), + mByDate(false), + mSystemToTop(false), + mFoldersByName(false) + { + mByDate = (order & LLInventoryFilter::SO_DATE); + mSystemToTop = (order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP); + mFoldersByName = (order & LLInventoryFilter::SO_FOLDERS_BY_NAME); + } + + bool isByDate() const { return mByDate; } + U32 getSortOrder() const { return mSortOrder; } + + bool operator()(const LLFolderViewModelItemInventory* const& a, const LLFolderViewModelItemInventory* const& b) const; +private: + U32 mSortOrder; + bool mByDate; + bool mSystemToTop; + bool mFoldersByName; +}; + +class LLFolderViewModelInventory + : public LLFolderViewModel<LLInventorySort, LLFolderViewModelItemInventory, LLFolderViewModelItemInventory, LLInventoryFilter> +{ +public: + typedef LLFolderViewModel<LLInventorySort, LLFolderViewModelItemInventory, LLFolderViewModelItemInventory, LLInventoryFilter> base_t; + + virtual ~LLFolderViewModelInventory() {} + + void sort(LLFolderViewFolder* folder); + + bool contentsReady(); + +}; +#endif // LL_LLFOLDERVIEWMODELINVENTORY_H diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index 6a33130322..3f38d80a39 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -779,14 +779,12 @@ const std::string& LLInventoryFilter::getFilterText() if (isFilterObjectTypesWith(LLInventoryType::IT_ANIMATION)) { - //filtered_types += " Animations,"; filtered_types += LLTrans::getString("Animations"); filtered_by_type = TRUE; num_filter_types++; } else { - //not_filtered_types += " Animations,"; not_filtered_types += LLTrans::getString("Animations"); filtered_by_all_types = FALSE; @@ -794,140 +792,120 @@ const std::string& LLInventoryFilter::getFilterText() if (isFilterObjectTypesWith(LLInventoryType::IT_CALLINGCARD)) { - //filtered_types += " Calling Cards,"; filtered_types += LLTrans::getString("Calling Cards"); filtered_by_type = TRUE; num_filter_types++; } else { - //not_filtered_types += " Calling Cards,"; not_filtered_types += LLTrans::getString("Calling Cards"); filtered_by_all_types = FALSE; } if (isFilterObjectTypesWith(LLInventoryType::IT_WEARABLE)) { - //filtered_types += " Clothing,"; filtered_types += LLTrans::getString("Clothing"); filtered_by_type = TRUE; num_filter_types++; } else { - //not_filtered_types += " Clothing,"; not_filtered_types += LLTrans::getString("Clothing"); filtered_by_all_types = FALSE; } if (isFilterObjectTypesWith(LLInventoryType::IT_GESTURE)) { - //filtered_types += " Gestures,"; filtered_types += LLTrans::getString("Gestures"); filtered_by_type = TRUE; num_filter_types++; } else { - //not_filtered_types += " Gestures,"; not_filtered_types += LLTrans::getString("Gestures"); filtered_by_all_types = FALSE; } if (isFilterObjectTypesWith(LLInventoryType::IT_LANDMARK)) { - //filtered_types += " Landmarks,"; filtered_types += LLTrans::getString("Landmarks"); filtered_by_type = TRUE; num_filter_types++; } else { - //not_filtered_types += " Landmarks,"; not_filtered_types += LLTrans::getString("Landmarks"); filtered_by_all_types = FALSE; } if (isFilterObjectTypesWith(LLInventoryType::IT_NOTECARD)) { - //filtered_types += " Notecards,"; filtered_types += LLTrans::getString("Notecards"); filtered_by_type = TRUE; num_filter_types++; } else { - //not_filtered_types += " Notecards,"; not_filtered_types += LLTrans::getString("Notecards"); filtered_by_all_types = FALSE; } if (isFilterObjectTypesWith(LLInventoryType::IT_OBJECT) && isFilterObjectTypesWith(LLInventoryType::IT_ATTACHMENT)) { - //filtered_types += " Objects,"; filtered_types += LLTrans::getString("Objects"); filtered_by_type = TRUE; num_filter_types++; } else { - //not_filtered_types += " Objects,"; not_filtered_types += LLTrans::getString("Objects"); filtered_by_all_types = FALSE; } if (isFilterObjectTypesWith(LLInventoryType::IT_LSL)) { - //filtered_types += " Scripts,"; filtered_types += LLTrans::getString("Scripts"); filtered_by_type = TRUE; num_filter_types++; } else { - //not_filtered_types += " Scripts,"; not_filtered_types += LLTrans::getString("Scripts"); filtered_by_all_types = FALSE; } if (isFilterObjectTypesWith(LLInventoryType::IT_SOUND)) { - //filtered_types += " Sounds,"; filtered_types += LLTrans::getString("Sounds"); filtered_by_type = TRUE; num_filter_types++; } else { - //not_filtered_types += " Sounds,"; not_filtered_types += LLTrans::getString("Sounds"); filtered_by_all_types = FALSE; } if (isFilterObjectTypesWith(LLInventoryType::IT_TEXTURE)) { - //filtered_types += " Textures,"; filtered_types += LLTrans::getString("Textures"); filtered_by_type = TRUE; num_filter_types++; } else { - //not_filtered_types += " Textures,"; not_filtered_types += LLTrans::getString("Textures"); filtered_by_all_types = FALSE; } if (isFilterObjectTypesWith(LLInventoryType::IT_SNAPSHOT)) { - //filtered_types += " Snapshots,"; filtered_types += LLTrans::getString("Snapshots"); filtered_by_type = TRUE; num_filter_types++; } else { - //not_filtered_types += " Snapshots,"; not_filtered_types += LLTrans::getString("Snapshots"); filtered_by_all_types = FALSE; } @@ -943,7 +921,6 @@ const std::string& LLInventoryFilter::getFilterText() } else { - //mFilterText += "No "; mFilterText += LLTrans::getString("No Filters"); mFilterText += not_filtered_types; } @@ -953,7 +930,6 @@ const std::string& LLInventoryFilter::getFilterText() if (isSinceLogoff()) { - //mFilterText += " - Since Logoff"; mFilterText += LLTrans::getString("Since Logoff"); } return mFilterText; diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index e4cabcc988..b5fcf364dd 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -56,58 +56,6 @@ const std::string LLInventoryPanel::RECENTITEMS_SORT_ORDER = std::string("Recent const std::string LLInventoryPanel::INHERIT_SORT_ORDER = std::string(""); static const LLInventoryFVBridgeBuilder INVENTORY_BRIDGE_BUILDER; -// -// class LLFolderViewModelInventory -// -static LLFastTimer::DeclareTimer FTM_INVENTORY_SORT("Sort"); - -void LLFolderViewModelInventory::sort( LLFolderViewFolder* folder ) -{ - LLFastTimer _(FTM_INVENTORY_SORT); - - if (!needsSort(folder->getViewModelItem())) return; - - LLFolderViewModelItemInventory* modelp = static_cast<LLFolderViewModelItemInventory*>(folder->getViewModelItem()); - if (modelp->getUUID().isNull()) return; - - for (std::list<LLFolderViewFolder*>::iterator it = folder->getFoldersBegin(), end_it = folder->getFoldersEnd(); - it != end_it; - ++it) - { - LLFolderViewFolder* child_folderp = *it; - sort(child_folderp); - - if (child_folderp->getFoldersCount() > 0) - { - time_t most_recent_folder_time = - static_cast<LLFolderViewModelItemInventory*>((*child_folderp->getFoldersBegin())->getViewModelItem())->getCreationDate(); - LLFolderViewModelItemInventory* modelp = static_cast<LLFolderViewModelItemInventory*>(child_folderp->getViewModelItem()); - if (most_recent_folder_time > modelp->getCreationDate()) - { - modelp->setCreationDate(most_recent_folder_time); - } - } - if (child_folderp->getItemsCount() > 0) - { - time_t most_recent_item_time = - static_cast<LLFolderViewModelItemInventory*>((*child_folderp->getItemsBegin())->getViewModelItem())->getCreationDate(); - - LLFolderViewModelItemInventory* modelp = static_cast<LLFolderViewModelItemInventory*>(child_folderp->getViewModelItem()); - if (most_recent_item_time > modelp->getCreationDate()) - { - modelp->setCreationDate(most_recent_item_time); - } - } - } - base_t::sort(folder); -} - -bool LLFolderViewModelInventory::contentsReady() -{ - return !LLInventoryModelBackgroundFetch::instance().folderFetchActive(); -} - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLInventoryPanelObserver // @@ -580,8 +528,8 @@ void LLInventoryPanel::modelChanged(U32 mask) else if (!model_item && view_item) { // Remove the item's UI. - view_item->destroyView(); removeItemID(viewmodel_item->getUUID()); + view_item->destroyView(); } } } @@ -1344,150 +1292,3 @@ LLInventoryRecentItemsPanel::LLInventoryRecentItemsPanel( const Params& params) // replace bridge builder to have necessary View bridges. mInvFVBridgeBuilder = &RECENT_ITEMS_BUILDER; } - - -void LLFolderViewModelItemInventory::requestSort() -{ - LLFolderViewModelItemCommon::requestSort(); - if (mRootViewModel->getSorter().isByDate()) - { - // sort by date potentially affects parent folders which use a date - // derived from newest item in them - if (mParent) - { - mParent->requestSort(); - } - } -} - -bool LLFolderViewModelItemInventory::potentiallyVisible() -{ - return passedFilter() // we've passed the filter - || getLastFilterGeneration() < mRootViewModel->getFilter()->getFirstSuccessGeneration() // or we don't know yet - || descendantsPassedFilter(); -} - -bool LLFolderViewModelItemInventory::passedFilter(S32 filter_generation) -{ - if (filter_generation < 0) filter_generation = mRootViewModel->getFilter()->getFirstSuccessGeneration(); - return mPassedFolderFilter - && mLastFilterGeneration >= filter_generation - && (mPassedFilter || descendantsPassedFilter(filter_generation)); -} - -bool LLFolderViewModelItemInventory::descendantsPassedFilter(S32 filter_generation) -{ - if (filter_generation < 0) filter_generation = mRootViewModel->getFilter()->getFirstSuccessGeneration(); - return mMostFilteredDescendantGeneration >= filter_generation; -} - -void LLFolderViewModelItemInventory::setPassedFilter(bool passed, bool passed_folder, S32 filter_generation) -{ - mPassedFilter = passed; - mPassedFolderFilter = passed_folder; - mLastFilterGeneration = filter_generation; -} - -bool LLFolderViewModelItemInventory::filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter ) -{ - bool passed_filter_before = item->passedFilter(); - S32 filter_generation = filter.getCurrentGeneration(); - S32 must_pass_generation = filter.getFirstRequiredGeneration(); - bool changed = false; - - // 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 (item->getLastFilterGeneration() < filter_generation) - { - if (item->getLastFilterGeneration() >= must_pass_generation && - !item->passedFilter(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 - item->setPassedFilter(false, false, filter_generation); - } - else - { - changed |= item->filter( filter ); - } - } - - // track latest generation to pass any child items - if (item->passedFilter()) - { - LLFolderViewModelItemInventory* view_model = this; - - while(view_model && view_model->mMostFilteredDescendantGeneration < filter_generation) - { - view_model->mMostFilteredDescendantGeneration = filter_generation; - view_model = static_cast<LLFolderViewModelItemInventory*>(view_model->mParent); - } - } - - changed |= (item->passedFilter() != passed_filter_before); - if (changed) - { - //TODO RN: ensure this still happens, but without dependency on folderview - LLFolderViewFolder* parent = mFolderViewItem->getParentFolder(); - if (parent) parent->requestArrange(); - } - - return changed; -} - -bool LLFolderViewModelItemInventory::filter( LLFolderViewFilter& filter) -{ - bool changed = false; - - if(!mChildren.empty() - && (getLastFilterGeneration() < filter.getFirstRequiredGeneration() // haven't checked descendants against minimum required generation to pass - || descendantsPassedFilter(filter.getFirstRequiredGeneration()))) // or at least one descendant has passed the minimum requirement - { - // now query children - for (child_list_t::iterator iter = mChildren.begin(); - iter != mChildren.end() && filter.getFilterCount() > 0; - ++iter) - { - changed |= filterChildItem((*iter), filter); - } - } - - // if we didn't use all filter iterations - // that means we filtered all of our descendants - // so filter ourselves now - if (filter.getFilterCount() > 0) - { - const BOOL previous_passed_filter = mPassedFilter; - const BOOL passed_filter = filter.check(this); - const BOOL passed_filter_folder = (getInventoryType() == LLInventoryType::IT_CATEGORY) - ? filter.checkFolder(this) - : true; - - // If our visibility will change as a result of this filter, then - // we need to be rearranged in our parent folder - LLFolderViewFolder* parent_folder = mFolderViewItem->getParentFolder(); - if (parent_folder && passed_filter != previous_passed_filter) - { - parent_folder->requestArrange(); - } - - setPassedFilter(passed_filter, passed_filter_folder, filter.getCurrentGeneration()); - //TODO RN: create interface for string highlighting - //mStringMatchOffset = filter.getStringMatchOffset(this); - filter.decrementFilterCount(); - } - return changed; -} - -LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel() -{ - return &mInventoryViewModel; -} - - -const LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel() const -{ - return &mInventoryViewModel; -} - diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index 3195d9a369..a62b97aa7d 100644 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -31,6 +31,7 @@ #include "llassetstorage.h" #include "lldarray.h" #include "llfolderviewitem.h" +#include "llfolderviewmodelinventory.h" #include "llfloater.h" #include "llinventory.h" #include "llinventoryfilter.h" @@ -42,83 +43,6 @@ class LLInvFVBridge; class LLInventoryFVBridgeBuilder; class LLInvPanelComplObserver; -class LLFolderViewModelInventory; - -class LLFolderViewModelItemInventory - : public LLFolderViewModelItemCommon -{ -public: - LLFolderViewModelItemInventory() - : mRootViewModel(NULL) - {} - void setRootViewModel(LLFolderViewModelInventory* root_view_model) - { - mRootViewModel = root_view_model; - } - virtual const LLUUID& getUUID() const = 0; - virtual time_t getCreationDate() const = 0; // UTC seconds - virtual void setCreationDate(time_t creation_date_utc) = 0; - virtual PermissionMask getPermissionMask() const = 0; - virtual LLFolderType::EType getPreferredType() const = 0; - virtual void showProperties(void) = 0; - virtual BOOL isItemInTrash( void) const { return FALSE; } // TODO: make into pure virtual. - virtual BOOL isUpToDate() const = 0; - virtual bool hasChildren() const = 0; - virtual LLInventoryType::EType getInventoryType() const = 0; - virtual void performAction(LLInventoryModel* model, std::string action) = 0; - virtual LLWearableType::EType getWearableType() const = 0; - virtual EInventorySortGroup getSortGroup() const = 0; - virtual LLInventoryObject* getInventoryObject() const = 0; - virtual void requestSort(); - virtual bool potentiallyVisible(); - virtual bool passedFilter(S32 filter_generation = -1); - virtual bool descendantsPassedFilter(S32 filter_generation = -1); - virtual void setPassedFilter(bool filtered, bool filtered_folder, S32 filter_generation); - virtual bool filter( LLFolderViewFilter& filter); - virtual bool filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter); -protected: - LLFolderViewModelInventory* mRootViewModel; -}; - -class LLInventorySort -{ -public: - LLInventorySort(U32 order = 0) - : mSortOrder(order), - mByDate(false), - mSystemToTop(false), - mFoldersByName(false) - { - mByDate = (order & LLInventoryFilter::SO_DATE); - mSystemToTop = (order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP); - mFoldersByName = (order & LLInventoryFilter::SO_FOLDERS_BY_NAME); - } - - bool isByDate() const { return mByDate; } - U32 getSortOrder() const { return mSortOrder; } - - bool operator()(const LLFolderViewModelItemInventory* const& a, const LLFolderViewModelItemInventory* const& b) const; -private: - U32 mSortOrder; - bool mByDate; - bool mSystemToTop; - bool mFoldersByName; -}; - -class LLFolderViewModelInventory - : public LLFolderViewModel<LLInventorySort, LLFolderViewModelItemInventory, LLFolderViewModelItemInventory, LLInventoryFilter> -{ -public: - typedef LLFolderViewModel<LLInventorySort, LLFolderViewModelItemInventory, LLFolderViewModelItemInventory, LLInventoryFilter> base_t; - - virtual ~LLFolderViewModelInventory() {} - - void sort(LLFolderViewFolder* folder); - - bool contentsReady(); - -}; - class LLInventoryPanel : public LLPanel { diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 61a0331b72..4a9e106687 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -623,9 +623,9 @@ void LLFloaterTexturePicker::draw() LLFolderView* folder_view = mInventoryPanel->getRootFolder(); if (!folder_view) return; - LLInventoryFilter* filter = static_cast<LLFolderViewModelInventory*>(folder_view->getFolderViewModel())->getFilter(); + LLFolderViewFilter* filter = static_cast<LLFolderViewModelInventory*>(folder_view->getFolderViewModel())->getFilter(); - bool is_filter_active = folder_view->getLastFilterGeneration() < filter->getCurrentGeneration() && + bool is_filter_active = folder_view->getViewModelItem()->getLastFilterGeneration() < filter->getCurrentGeneration() && filter->isNotDefault(); // After inventory panel filter is applied we have to update |