diff --git a/indra/newview/llfloaterlandmark.cpp b/indra/newview/llfloaterlandmark.cpp index 00d7cd86c..d94546a08 100644 --- a/indra/newview/llfloaterlandmark.cpp +++ b/indra/newview/llfloaterlandmark.cpp @@ -104,7 +104,7 @@ BOOL LLFloaterLandmark::postBuild() mInventoryPanel->setAllowMultiSelect(FALSE); // store this filter as the default one - mInventoryPanel->getRootFolder()->getFilter()->markDefault(); + mInventoryPanel->getRootFolder()->getFilter().markDefault(); // Commented out to stop opening all folders with textures mInventoryPanel->openDefaultFolderForType(LLAssetType::AT_LANDMARK); diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index d6e15b422..a89be9419 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -201,7 +201,7 @@ LLFolderView::LLFolderView( const std::string& name, mNeedsAutoRename(FALSE), mDebugFilters(FALSE), mSortOrder(LLInventoryFilter::SO_FOLDERS_BY_NAME), // This gets overridden by a pref immediately - mFilter( new LLInventoryFilter(name) ), + mFilter(LLInventoryFilter::Params().name(name)), mShowSelectionContext(FALSE), mShowSingleSelection(FALSE), mArrangeGeneration(0), @@ -298,9 +298,6 @@ LLFolderView::~LLFolderView( void ) mFolders.clear(); mItemMap.clear(); - - delete mFilter; - mFilter = NULL; } BOOL LLFolderView::canFocusChildren() const @@ -371,7 +368,7 @@ U32 LLFolderView::toggleSearchType(std::string toggle) if (getFilterSubString().length()) { - mFilter->setModified(LLInventoryFilter::FILTER_RESTART); + mFilter.setModified(LLInventoryFilter::FILTER_RESTART); } return mSearchType; @@ -447,7 +444,7 @@ S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_gen LL_RECORD_BLOCK_TIME(FTM_ARRANGE); - filter_generation = mFilter->getFirstSuccessGeneration(); + filter_generation = mFilter.getFirstSuccessGeneration(); mMinWidth = 0; mHasVisibleChildren = hasFilteredDescendants(filter_generation); @@ -455,7 +452,7 @@ S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_gen mLastArrangeGeneration = getRoot()->getArrangeGeneration(); LLInventoryFilter::EFolderShow show_folder_state = - getRoot()->getFilter()->getShowFolderState(); + getRoot()->getFilter().getShowFolderState(); S32 total_width = LEFT_PAD; S32 running_height = mDebugFilters ? llceil(LLFontGL::getFontMonospace()->getLineHeight()) : 0; @@ -541,7 +538,7 @@ S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_gen const std::string LLFolderView::getFilterSubString(BOOL trim) { - return mFilter->getFilterSubString(trim); + return mFilter.getFilterSubString(trim); } static LLTrace::BlockTimerStatHandle FTM_FILTER("Filter Inventory"); @@ -749,7 +746,7 @@ void LLFolderView::sanitizeSelection() LLFolderViewItem* original_selected_item = getCurSelectedItem(); // Cache "Show all folders" filter setting - BOOL show_all_folders = (getRoot()->getFilter()->getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS); + BOOL show_all_folders = (getRoot()->getFilter().getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS); std::vector items_to_remove; selected_items_t::iterator item_iter; @@ -913,7 +910,7 @@ void LLFolderView::draw() if (mDebugFilters) { std::string current_filter_string = llformat("Current Filter: %d, Least Filter: %d, Auto-accept Filter: %d", - mFilter->getCurrentGeneration(), mFilter->getFirstSuccessGeneration(), mFilter->getFirstRequiredGeneration()); + mFilter.getCurrentGeneration(), mFilter.getFirstSuccessGeneration(), mFilter.getFirstRequiredGeneration()); LLFontGL::getFontMonospace()->renderUTF8(current_filter_string, 0, 2, getRect().getHeight() - LLFontGL::getFontMonospace()->getLineHeight(), LLColor4(0.5f, 0.5f, 0.8f, 1.f), LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE ); @@ -945,7 +942,7 @@ void LLFolderView::draw() } if (hasVisibleChildren() - || mFilter->getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS) + || mFilter.getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS) { mStatusText.clear(); mStatusTextBox->setVisible( FALSE ); @@ -953,7 +950,7 @@ void LLFolderView::draw() else if (mShowEmptyMessage) { static LLCachedControl sSearchStatusColor(gColors, "InventorySearchStatusColor", LLColor4::white ); - if (LLInventoryModelBackgroundFetch::instance().folderFetchActive() || mCompletedFilterGeneration < mFilter->getFirstSuccessGeneration()) + if (LLInventoryModelBackgroundFetch::instance().folderFetchActive() || mCompletedFilterGeneration < mFilter.getFirstSuccessGeneration()) { mStatusText = LLTrans::getString("Searching"); } @@ -962,7 +959,7 @@ void LLFolderView::draw() // if(getFilter()) // { // LLStringUtil::format_map_t args; - // args["[SEARCH_TERM]"] = LLURI::escape(getFilter()->getFilterSubStringOrig()); + // args["[SEARCH_TERM]"] = LLURI::escape(getFilter().getFilterSubStringOrig()); mStatusText = LLTrans::getString("InventoryNoMatchingItems"); //, args); // } } @@ -1899,7 +1896,7 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask ) S32 count = mSelectedItems.size(); LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); if ( handled - && ( count > 0 && (hasVisibleChildren() || mFilter->getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS) ) // show menu only if selected items are visible + && ( count > 0 && (hasVisibleChildren() || mFilter.getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS) ) // show menu only if selected items are visible && menu ) { updateMenuOptions(menu); @@ -2178,9 +2175,9 @@ void LLFolderView::doIdle() arrangeAll(); } - mFilter->clearModified(); - BOOL filter_modified_and_active = mCompletedFilterGeneration < mFilter->getCurrentGeneration() && - mFilter->isNotDefault(); + mFilter.clearModified(); + BOOL filter_modified_and_active = mCompletedFilterGeneration < mFilter.getCurrentGeneration() && + mFilter.isNotDefault(); mNeedsAutoSelect = filter_modified_and_active && !(gFocusMgr.childHasKeyboardFocus(this) || gFocusMgr.getMouseCapture()); @@ -2206,7 +2203,7 @@ void LLFolderView::doIdle() // Open filtered folders for folder views with mAutoSelectOverride=TRUE. // Used by LLPlacesFolderView. - if (mAutoSelectOverride && !mFilter->getFilterSubString().empty()) + if (mAutoSelectOverride && !mFilter.getFilterSubString().empty()) { LLOpenFilteredFolders filter; applyFunctorRecursively(filter); @@ -2359,7 +2356,7 @@ void LLFolderView::updateMenuOptions(LLMenuGL* menu) } // Successively filter out invalid options - U32 multi_select_flag = (/*mSelectedItems.size() > 1 ? ITEM_IN_MULTI_SELECTION :*/ 0x0); + U32 multi_select_flag = (mSelectedItems.size() > 1 ? ITEM_IN_MULTI_SELECTION : 0x0); U32 flags = multi_select_flag | FIRST_SELECTED_ITEM; for (selected_items_t::iterator item_itor = mSelectedItems.begin(); item_itor != mSelectedItems.end(); @@ -2509,29 +2506,24 @@ void LLFolderView::onRenamerLost() } } -LLInventoryFilter* LLFolderView::getFilter() -{ - return mFilter; -} - void LLFolderView::setFilterPermMask( PermissionMask filter_perm_mask ) { - mFilter->setFilterPermissions(filter_perm_mask); + mFilter.setFilterPermissions(filter_perm_mask); } U32 LLFolderView::getFilterObjectTypes() const { - return mFilter->getFilterObjectTypes(); + return mFilter.getFilterObjectTypes(); } PermissionMask LLFolderView::getFilterPermissions() const { - return mFilter->getFilterPermissions(); + return mFilter.getFilterPermissions(); } BOOL LLFolderView::isFilterModified() { - return mFilter->isNotDefault(); + return mFilter.isNotDefault(); } void delete_selected_item(void* user_data) diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h index 067c64703..a9e5b9f4e 100644 --- a/indra/newview/llfolderview.h +++ b/indra/newview/llfolderview.h @@ -1,3 +1,4 @@ + /** * @file llfolderview.h * @brief Definition of the folder view collection of classes. @@ -49,6 +50,7 @@ #include "lldepthstack.h" #include "lleditmenuhandler.h" #include "llfontgl.h" +#include "llinventoryfilter.h" #include "lltooldraganddrop.h" #include "llviewertexture.h" @@ -103,11 +105,11 @@ public: void setReshapeCallback(const signal_t::slot_type& cb) { mReshapeSignal.connect(cb); } void setAllowMultiSelect(BOOL allow) { mAllowMultiSelect = allow; } - LLInventoryFilter* getFilter(); + LLInventoryFilter& getFilter() { return mFilter; } const std::string getFilterSubString(BOOL trim = FALSE); U32 getFilterObjectTypes() const; PermissionMask getFilterPermissions() const; - // *NOTE: use getFilter()->getShowFolderState(); + // *NOTE: use getFilter().getShowFolderState(); //LLInventoryFilter::EFolderShow getShowFolderState(); U32 getSortOrder() const; BOOL isFilterModified(); @@ -180,6 +182,7 @@ public: void autoOpenItem(LLFolderViewFolder* item); void closeAutoOpenedFolders(); BOOL autoOpenTest(LLFolderViewFolder* item); + BOOL isOpen() const { return TRUE; } // root folder always open // Copy & paste virtual BOOL canCopy() const; @@ -315,7 +318,7 @@ protected: LLFrameTimer mAutoOpenTimer; LLFrameTimer mSearchTimer; LLWString mSearchString; - LLInventoryFilter* mFilter; + LLInventoryFilter mFilter; LLFrameTimer mMultiSelectionFadeTimer; S32 mArrangeGeneration; @@ -348,11 +351,10 @@ public: }; -bool sort_item_name(LLFolderViewItem* a, LLFolderViewItem* b); -bool sort_item_date(LLFolderViewItem* a, LLFolderViewItem* b); // Flags for buildContextMenu() const U32 SUPPRESS_OPEN_ITEM = 0x1; const U32 FIRST_SELECTED_ITEM = 0x2; +const U32 ITEM_IN_MULTI_SELECTION = 0x4; #endif // LL_LLFOLDERVIEW_H diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp index ed87b4c3e..7b5179df2 100644 --- a/indra/newview/llfolderviewitem.cpp +++ b/indra/newview/llfolderviewitem.cpp @@ -214,12 +214,12 @@ BOOL LLFolderViewItem::potentiallyVisible() { // we haven't been checked against min required filter // or we have and we passed - return getLastFilterGeneration() < getRoot()->getFilter()->getFirstSuccessGeneration() || getFiltered(); + return getLastFilterGeneration() < getRoot()->getFilter().getFirstSuccessGeneration() || getFiltered(); } BOOL LLFolderViewItem::getFiltered() { - return mPassedFilter && mLastFilterGeneration >= getRoot()->getFilter()->getFirstSuccessGeneration(); + return mPassedFilter && mLastFilterGeneration >= getRoot()->getFilter().getFirstSuccessGeneration(); } BOOL LLFolderViewItem::getFiltered(S32 filter_generation) @@ -328,7 +328,7 @@ void LLFolderViewItem::filterFromRoot( void ) { LLFolderViewItem* root = getRoot(); - root->filter(*((LLFolderView*)root)->getFilter()); + root->filter(((LLFolderView*)root)->getFilter()); } // This function is called when the folder view is dirty. It's @@ -1037,7 +1037,7 @@ void LLFolderViewItem::draw() { color.mV[VALPHA] *= 0.5f; } - LLColor4 filter_color = mLastFilterGeneration >= getRoot()->getFilter()->getCurrentGeneration() ? + LLColor4 filter_color = mLastFilterGeneration >= getRoot()->getFilter().getCurrentGeneration() ? LLColor4(0.5f, 0.8f, 0.5f, 1.f) : LLColor4(0.8f, 0.5f, 0.5f, 1.f); LLFontGL::getFontMonospace()->renderUTF8(mStatusText, 0, text_left, y, filter_color, @@ -1163,7 +1163,7 @@ void LLFolderViewFolder::setFilteredFolder(bool filtered, S32 filter_generation) bool LLFolderViewFolder::getFilteredFolder(S32 filter_generation) { - return mPassedFolderFilter && mLastFilterGeneration >= getRoot()->getFilter()->getFirstSuccessGeneration(); + return mPassedFolderFilter && mLastFilterGeneration >= getRoot()->getFilter().getFirstSuccessGeneration(); } // addToFolder() returns TRUE if it succeeds. FALSE otherwise @@ -1557,7 +1557,7 @@ void LLFolderViewFolder::dirtyFilter() BOOL LLFolderViewFolder::getFiltered() { - return getFilteredFolder(getRoot()->getFilter()->getFirstSuccessGeneration()) + return getFilteredFolder(getRoot()->getFilter().getFirstSuccessGeneration()) && LLFolderViewItem::getFiltered(); } @@ -1574,7 +1574,7 @@ BOOL LLFolderViewFolder::hasFilteredDescendants(S32 filter_generation) BOOL LLFolderViewFolder::hasFilteredDescendants() { - return mMostFilteredDescendantGeneration >= getRoot()->getFilter()->getCurrentGeneration(); + return mMostFilteredDescendantGeneration >= getRoot()->getFilter().getCurrentGeneration(); } // Passes selection information on to children and record selection @@ -2585,9 +2585,9 @@ BOOL LLFolderViewFolder::potentiallyVisible() // folder should be visible by it's own filter status return LLFolderViewItem::potentiallyVisible() // or one or more of its descendants have passed the minimum filter requirement - || hasFilteredDescendants(getRoot()->getFilter()->getFirstSuccessGeneration()) + || hasFilteredDescendants(getRoot()->getFilter().getFirstSuccessGeneration()) // or not all of its descendants have been checked against minimum filter requirement - || getCompletedFilterGeneration() < getRoot()->getFilter()->getFirstSuccessGeneration(); + || getCompletedFilterGeneration() < getRoot()->getFilter().getFirstSuccessGeneration(); } // this does prefix traversal, as folders are listed above their contents diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index ca1c113f8..5932fc95d 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -68,8 +68,11 @@ LLInventoryFilter::FilterOps::FilterOps(const Params& p) ///---------------------------------------------------------------------------- /// Class LLInventoryFilter ///---------------------------------------------------------------------------- -LLInventoryFilter::LLInventoryFilter(const std::string& name) -: mName(name), +LLInventoryFilter::LLInventoryFilter(const Params& p) +: mName(p.name), + mFilterBehavior(FILTER_NONE), + mFilterOps(p.filter_ops), + mFilterSubString(p.substring), mFilterModified(FILTER_NONE), mFilterOps(), mFilterSubString(), @@ -81,6 +84,7 @@ LLInventoryFilter::LLInventoryFilter(const std::string& name) mSubStringMatchOffset = std::string::npos; mFilterCount = 0; + // Singu Note: Why aren't we calling fromParams here? // copy mFilterOps into mDefaultFilterOps markDefault(); @@ -105,7 +109,7 @@ bool LLInventoryFilter::check(LLFolderViewItem* item) const bool passed_filtertype = checkAgainstFilterType(item); const bool passed_permissions = checkAgainstPermissions(item); const bool passed_filterlink = checkAgainstFilterLinks(item); - const bool passed_wearable = !mFilterOps.mFilterWornItems || (gAgentWearables.isWearingItem(item_id) || (gAgentAvatarp && gAgentAvatarp->isWearingAttachment(item_id))); + const bool passed_wearable = (mFilterOps.mFilterTypes & FILTERTYPE_WORN) != FILTERTYPE_WORN || (gAgentWearables.isWearingItem(item_id) || (gAgentAvatarp && gAgentAvatarp->isWearingAttachment(item_id))); const bool passed = (passed_filtertype && passed_permissions && passed_filterlink && @@ -138,6 +142,13 @@ bool LLInventoryFilter::checkFolder(const LLFolderViewFolder* folder) const bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const { + // when applying a filter, matching folders get their contents downloaded first + if (isNotDefault() + && !gInventory.isCategoryComplete(folder_id)) + { + LLInventoryModelBackgroundFetch::instance().start(folder_id); + } + // Always check against the clipboard const BOOL passed_clipboard = checkAgainstClipboard(folder_id); @@ -366,6 +377,56 @@ bool LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) con return TRUE; } +bool LLInventoryFilter::checkAgainstFilterType(const LLInventoryItem* item) const +{ + LLInventoryType::EType object_type = item->getInventoryType(); + const LLUUID object_id = item->getUUID(); + + const U32 filterTypes = mFilterOps.mFilterTypes; + + //////////////////////////////////////////////////////////////////////////////// + // FILTERTYPE_OBJECT + // Pass if this item's type is of the correct filter type + if (filterTypes & FILTERTYPE_OBJECT) + { + // If it has no type, pass it, unless it's a link. + if (object_type == LLInventoryType::IT_NONE) + { + if (item && item->getIsLinkType()) + { + return false; + } + } + else if ((1LL << object_type & mFilterOps.mFilterObjectTypes) == U64(0)) + { + return false; + } + } + + //////////////////////////////////////////////////////////////////////////////// + // FILTERTYPE_UUID + // Pass if this item is the target UUID or if it links to the target UUID + if (filterTypes & FILTERTYPE_UUID) + { + if (!item) return false; + + if (item->getLinkedUUID() != mFilterOps.mFilterUUID) + return false; + } + + //////////////////////////////////////////////////////////////////////////////// + // FILTERTYPE_DATE + // Pass if this item is within the date range. + if (filterTypes & FILTERTYPE_DATE) + { + // We don't get the updated item creation date for the task inventory or + // a notecard embedded item. See LLTaskInvFVBridge::getCreationDate(). + return false; + } + + return true; +} + // Items and folders that are on the clipboard or, recursively, in a folder which // is on the clipboard must be filtered out if the clipboard is in the "cut" mode. bool LLInventoryFilter::checkAgainstClipboard(const LLUUID& object_id) const @@ -407,6 +468,17 @@ bool LLInventoryFilter::checkAgainstPermissions(const LLFolderViewItem* item) co return (perm & mFilterOps.mPermissions) == mFilterOps.mPermissions; } +bool LLInventoryFilter::checkAgainstPermissions(const LLInventoryItem* item) const +{ + if (!item) return false; + + LLPointer new_item = new LLViewerInventoryItem(item); + PermissionMask perm = new_item->getPermissionMask(); + new_item = NULL; + + return (perm & mFilterOps.mPermissions) == mFilterOps.mPermissions; +} + bool LLInventoryFilter::checkAgainstFilterLinks(const LLFolderViewItem* item) const { const LLFolderViewEventListener* listener = item->getListener(); @@ -450,7 +522,6 @@ bool LLInventoryFilter::isNotDefault() const not_default |= (mFilterOps.mFilterTypes != mDefaultFilterOps.mFilterTypes); not_default |= (mFilterOps.mFilterLinks != mDefaultFilterOps.mFilterLinks); not_default |= (mFilterSubString.size() > 0); - not_default |= (mFilterOps.mFilterWornItems != mDefaultFilterOps.mFilterWornItems); not_default |= (mFilterOps.mPermissions != mDefaultFilterOps.mPermissions); not_default |= (mFilterOps.mMinDate != mDefaultFilterOps.mMinDate); not_default |= (mFilterOps.mMaxDate != mDefaultFilterOps.mMaxDate); @@ -1070,71 +1141,63 @@ const std::string& LLInventoryFilter::getFilterText() return mFilterText; } -void LLInventoryFilter::toLLSD(LLSD& data) const +LLInventoryFilter& LLInventoryFilter::operator=( const LLInventoryFilter& other ) { - data["filter_types"] = (LLSD::Integer)getFilterObjectTypes(); - data["min_date"] = (LLSD::Integer)getMinDate(); - data["max_date"] = (LLSD::Integer)getMaxDate(); - data["hours_ago"] = (LLSD::Integer)getHoursAgo(); - data["show_folder_state"] = (LLSD::Integer)getShowFolderState(); - data["permissions"] = (LLSD::Integer)getFilterPermissions(); - data["substring"] = (LLSD::String)getFilterSubString(); - data["sort_order"] = (LLSD::Integer)getSortOrder(); - data["since_logoff"] = (LLSD::Boolean)isSinceLogoff(); - data["filter_links"] = (LLSD::Integer)getFilterLinks(); + setFilterObjectTypes(other.getFilterObjectTypes()); + setDateRange(other.getMinDate(), other.getMaxDate()); + setHoursAgo(other.getHoursAgo()); + setDateSearchDirection(other.getDateSearchDirection()); + setShowFolderState(other.getShowFolderState()); + setFilterPermissions(other.getFilterPermissions()); + setFilterSubString(other.getFilterSubString()); + setDateRangeLastLogoff(other.isSinceLogoff()); + return *this; } -void LLInventoryFilter::fromLLSD(LLSD& data) + +void LLInventoryFilter::toParams(Params& params) const { - if(data.has("filter_types")) + params.filter_ops.types = getFilterObjectTypes(); + params.filter_ops.category_types = getFilterCategoryTypes(); + if (getFilterObjectTypes() & FILTERTYPE_WEARABLE) { - setFilterObjectTypes((U32)data["filter_types"].asInteger()); - } - - if(data.has("min_date") && data.has("max_date")) - { - setDateRange(data["min_date"].asInteger(), data["max_date"].asInteger()); - } - - if(data.has("hours_ago")) - { - setHoursAgo((U32)data["hours_ago"].asInteger()); - } - - if(data.has("show_folder_state")) - { - setShowFolderState((EFolderShow)data["show_folder_state"].asInteger()); - } - - if(data.has("permissions")) - { - setFilterPermissions((PermissionMask)data["permissions"].asInteger()); - } - - if(data.has("substring")) - { - setFilterSubString(std::string(data["substring"].asString())); - } - - if(data.has("sort_order")) - { - setSortOrder((U32)data["sort_order"].asInteger()); - } - - if(data.has("since_logoff")) - { - setDateRangeLastLogoff((bool)data["since_logoff"].asBoolean()); - } - - if (data.has("filter_links")) - { - setFilterLinks(data["filter_links"].asInteger()); + params.filter_ops.wearable_types = getFilterWearableTypes(); } + params.filter_ops.date_range.min_date = getMinDate(); + params.filter_ops.date_range.max_date = getMaxDate(); + params.filter_ops.hours_ago = getHoursAgo(); + params.filter_ops.date_search_direction = getDateSearchDirection(); + params.filter_ops.show_folder_state = getShowFolderState(); + params.filter_ops.permissions = getFilterPermissions(); + params.substring = getFilterSubString(); + params.since_logoff = isSinceLogoff(); } -U64 LLInventoryFilter::getFilterTypes() const +void LLInventoryFilter::fromParams(const Params& params) { - return mFilterOps.mFilterTypes; + if (!params.validateBlock()) + { + return; + } + + setFilterObjectTypes(params.filter_ops.types); + setFilterCategoryTypes(params.filter_ops.category_types); + if (params.filter_ops.wearable_types.isProvided()) + { + setFilterWearableTypes(params.filter_ops.wearable_types); + } + + setDateRange(params.filter_ops.date_range.min_date, params.filter_ops.date_range.max_date); + setHoursAgo(params.filter_ops.hours_ago); + setDateSearchDirection(params.filter_ops.date_search_direction); + setShowFolderState(params.filter_ops.show_folder_state); + setFilterPermissions(params.filter_ops.permissions); + setFilterSubString(params.substring); + setDateRangeLastLogoff(params.since_logoff); + if (params.filter_ops.links.isProvided()) + { + setFilterLinks(params.filter_ops.links); + } } U64 LLInventoryFilter::getFilterTypes() const @@ -1159,7 +1222,7 @@ U64 LLInventoryFilter::getFilterWearableTypes() const U64 LLInventoryFilter::getFilterWornItems() const { - return mFilterOps.mFilterWornItems; + return mFilterOps.mFilterTypes & FILTERTYPE_WORN; } bool LLInventoryFilter::hasFilterString() const @@ -1249,6 +1312,11 @@ bool LLInventoryFilter::areDateLimitsSet() || mFilterOps.mHoursAgo != 0; } +bool LLInventoryFilter::showAllResults() const +{ + return hasFilterString(); +} + bool LLInventoryFilter::FilterOps::DateRange::validateBlock( bool emit_errors /*= true*/ ) const diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h index 05d5741ea..52a01046a 100644 --- a/indra/newview/llinventoryfilter.h +++ b/indra/newview/llinventoryfilter.h @@ -32,6 +32,7 @@ class LLFolderViewItem; class LLFolderViewFolder; +class LLInventoryItem; class LLInventoryFilter { @@ -156,7 +157,23 @@ public: bool mFilterWorn; }; - LLInventoryFilter(const std::string& name); + struct Params : public LLInitParam::Block + { + Optional name; + Optional filter_ops; + Optional substring; + Optional since_logoff; + + Params() + : name("name"), + filter_ops(""), + substring("substring"), + since_logoff("since_logoff") + {} + }; + + LLInventoryFilter(const Params& p = Params()); + LLInventoryFilter(const LLInventoryFilter& other) { *this = other; } virtual ~LLInventoryFilter() {} // +-------------------------------------------------------------------+ @@ -206,6 +223,7 @@ public: // + Execution And Results // +-------------------------------------------------------------------+ bool check(LLFolderViewItem* item); + bool check(const LLInventoryItem* item); bool checkFolder(const LLFolderViewFolder* folder) const; bool checkFolder(const LLUUID& folder_id) const; @@ -260,13 +278,17 @@ public: // +-------------------------------------------------------------------+ // + Conversion // +-------------------------------------------------------------------+ - void toLLSD(LLSD& data) const; - void fromLLSD(LLSD& data); + void toParams(Params& params) const; + void fromParams(const Params& p); + + LLInventoryFilter& operator =(const LLInventoryFilter& other); private: bool areDateLimitsSet(); bool checkAgainstFilterType(const LLFolderViewItem* item) const; + bool checkAgainstFilterType(const LLInventoryItem* item) const; bool checkAgainstPermissions(const LLFolderViewItem* item) const; + bool checkAgainstPermissions(const LLInventoryItem* item) const; bool checkAgainstFilterLinks(const LLFolderViewItem* item) const; bool checkAgainstClipboard(const LLUUID& object_id) const; diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index d7c93f491..1e2db53ac 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -195,7 +195,7 @@ void LLInventoryPanel::buildFolderView() LLFolderView* folder_view = createFolderView(new_listener, true/*params.use_label_suffix()*/); mFolderRoot = folder_view->getHandle(); - //addItemID(root_id, mFolderRoot.get()); + addItemID(root_id, mFolderRoot.get()); } BOOL LLInventoryPanel::postBuild() { @@ -381,12 +381,12 @@ void LLInventoryPanel::draw() LLInventoryFilter& LLInventoryPanel::getFilter() { - return *mFolderRoot.get()->getFilter(); + return mFolderRoot.get()->getFilter(); } const LLInventoryFilter& LLInventoryPanel::getFilter() const { - return *mFolderRoot.get()->getFilter(); + return mFolderRoot.get()->getFilter(); } void LLInventoryPanel::setFilterTypes(U64 types, LLInventoryFilter::EFilterType filter_type) @@ -588,9 +588,9 @@ void LLInventoryPanel::modelChanged(U32 mask) { if (model_item && view_item) { - //const LLUUID& idp = view_item->getListener()->getUUID(); + const LLUUID& idp = view_item->getListener()->getUUID(); view_item->destroyView(); - //removeItemID(idp); + removeItemID(idp); } view_item = buildNewViews(item_id); view_folder = dynamic_cast(view_item); @@ -659,7 +659,7 @@ void LLInventoryPanel::modelChanged(U32 mask) // Item is to be moved and we found its new parent in the panel's directory, so move the item's UI. view_item->getParentFolder()->extractItem(view_item); view_item->addToFolder(new_parent, mFolderRoot.get()); - //addItemID(view_item->getListener()->getUUID(), view_item); + addItemID(view_item->getListener()->getUUID(), view_item); if (mInventory) { const LLUUID trash_id = mInventory->findCategoryUUIDForType(LLFolderType::FT_TRASH); @@ -673,7 +673,7 @@ void LLInventoryPanel::modelChanged(U32 mask) { // Remove the item ID before destroying the view because the view-model-item gets // destroyed when the view is destroyed - //removeItemID(view_item->getListener()->getUUID()); + removeItemID(view_item->getListener()->getUUID()); // Item is to be moved outside the panel's directory (e.g. moved to trash for a panel that // doesn't include trash). Just remove the item's UI. @@ -690,7 +690,7 @@ void LLInventoryPanel::modelChanged(U32 mask) { // Remove the item's UI. //LLFolderViewFolder* parent = view_item->getParentFolder(); - //removeItemID(view_item->getListener()->getUUID()); + removeItemID(view_item->getListener()->getUUID()); view_item->destroyView(); } } @@ -900,7 +900,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id) { llassert(parent_folder != NULL); folder_view_item->addToFolder(parent_folder, mFolderRoot.get()); - //addItemID(id, folder_view_item); + addItemID(id, folder_view_item); // In the case of the root folder been shown, open that folder by default once the widget is created if (create_root) { diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index f00b62f92..20646fff7 100644 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -65,6 +65,32 @@ class LLFolderViewGroupedItemBridge; class LLInventoryPanel : public LLPanel { + //-------------------------------------------------------------------- + // Data + //-------------------------------------------------------------------- +public: + struct Filter : public LLInitParam::Block + { + Optional sort_order; + Optional types; + Optional search_string; + + Filter() + : sort_order("sort_order"), + types("types", 0xffffffff), + search_string("search_string") + {} + }; + + struct InventoryState : public LLInitParam::Block + { + Mandatory filter; + //Mandatory sort; + }; + + //-------------------------------------------------------------------- + // Initialization + //-------------------------------------------------------------------- protected: friend class LFFloaterInvPanel; LLInventoryPanel(const std::string& name, diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index 21f226e3c..f0f11fcda 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -40,6 +40,7 @@ #include "llresmgr.h" #include "llscrollcontainer.h" #include "llsdserialize.h" +#include "llsdparam.h" #include "llspinctrl.h" #include "lltooldraganddrop.h" #include "llviewermenu.h" @@ -57,7 +58,6 @@ const S32 INV_MIN_HEIGHT = 150; const S32 INV_FINDER_WIDTH = 160; const S32 INV_FINDER_HEIGHT = 408; -//BOOL LLPanelMainInventory::sOpenNextNewItem = FALSE; class LLFloaterInventoryFinder : public LLFloater { public: @@ -69,8 +69,10 @@ public: virtual void onClose(bool app_quitting); void changeFilter(LLInventoryFilter* filter); void updateElementsFromFilter(); + BOOL getCheckShowLinks(); BOOL getCheckShowEmpty(); BOOL getCheckSinceLogoff(); + U32 getDateSearchDirection(); void onLinks(const LLSD& val); static void onTimeAgo(LLUICtrl*, void *); @@ -86,7 +88,6 @@ protected: LLInventoryFilter* mFilter; }; - ///---------------------------------------------------------------------------- /// LLPanelMainInventory ///---------------------------------------------------------------------------- @@ -167,7 +168,9 @@ BOOL LLPanelMainInventory::postBuild() recent_items_panel->setSinceLogoff(TRUE); recent_items_panel->setSortOrder(gSavedSettings.getU32(LLInventoryPanel::RECENTITEMS_SORT_ORDER)); recent_items_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); - recent_items_panel->getFilter().markDefault(); + LLInventoryFilter& recent_filter = recent_items_panel->getFilter(); + recent_filter.setFilterObjectTypes(recent_filter.getFilterObjectTypes() & ~(0x1 << LLInventoryType::IT_CATEGORY)); + recent_filter.markDefault(); recent_items_panel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, recent_items_panel, _1, _2)); } LLInventoryPanel* worn_items_panel = getChild("Worn Items"); @@ -193,19 +196,33 @@ BOOL LLPanelMainInventory::postBuild() file.close(); // Load the persistent "Recent Items" settings. - // Note that the "All Items" and "Worn Items" settings do not persist per-account. + // Note that the "All Items" settings do not persist. if(recent_items_panel) { if(savedFilterState.has(recent_items_panel->getFilter().getName())) { LLSD recent_items = savedFilterState.get( recent_items_panel->getFilter().getName()); - recent_items_panel->getFilter().fromLLSD(recent_items); + LLInventoryFilter::Params p; + LLParamSDParser parser; + parser.readSD(recent_items, p); + recent_items_panel->getFilter().fromParams(p); + } + } + if(worn_items_panel) + { + if(savedFilterState.has(worn_items_panel->getFilter().getName())) + { + LLSD worn_items = savedFilterState.get( + worn_items_panel->getFilter().getName()); + LLInventoryFilter::Params p; + LLParamSDParser parser; + parser.readSD(worn_items, p); + worn_items_panel->getFilter().fromParams(p); } } } - mFilterEditor = getChild("inventory search editor"); if (mFilterEditor) { @@ -238,39 +255,52 @@ LLPanelMainInventory::~LLPanelMainInventory( void ) LLInventoryPanel* all_items_panel = getChild("All Items"); if (all_items_panel) { - LLInventoryFilter& filter = all_items_panel->getFilter(); LLSD filterState; - filter.toLLSD(filterState); - filterRoot[filter.getName()] = filterState; + LLInventoryPanel::InventoryState p; + all_items_panel->getFilter().toParams(p.filter); + if (p.validateBlock(false)) + { + LLParamSDParser().writeSD(filterState, p); + filterRoot[all_items_panel->getName()] = filterState; + } } - LLInventoryPanel* recent_items_panel = getChild("Recent Items"); - if (recent_items_panel) + LLInventoryPanel* recent_panel = findChild("Recent Items"); + if (recent_panel) { - LLInventoryFilter& filter = recent_items_panel->getFilter(); LLSD filterState; - filter.toLLSD(filterState); - filterRoot[filter.getName()] = filterState; + LLInventoryPanel::InventoryState p; + recent_panel->getFilter().toParams(p.filter); + if (p.validateBlock(false)) + { + LLParamSDParser().writeSD(filterState, p); + filterRoot[recent_panel->getName()] = filterState; + } } - LLInventoryPanel* worn_items_panel = getChild("Worn Items"); - if (worn_items_panel) + LLInventoryPanel* worn_panel = findChild("Worn Items"); + if (worn_panel) { - LLInventoryFilter& filter = worn_items_panel->getFilter(); LLSD filterState; - filter.toLLSD(filterState); - filterRoot[filter.getName()] = filterState; + LLInventoryPanel::InventoryState p; + worn_panel->getFilter().toParams(p.filter); + if (p.validateBlock(false)) + { + LLParamSDParser().writeSD(filterState, p); + filterRoot[worn_panel->getName()] = filterState; + } } - std::ostringstream filterSaveName; - filterSaveName << gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "filters.xml"); - llofstream filtersFile(filterSaveName.str()); + std::string filterSaveName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, FILTERS_FILENAME)); + llofstream filtersFile(filterSaveName.c_str()); if(!LLSDSerialize::toPrettyXML(filterRoot, filtersFile)) { - LL_WARNS() << "Could not write to filters save file " << filterSaveName.str().c_str() << LL_ENDL; + LL_WARNS() << "Could not write to filters save file " << filterSaveName.c_str() << LL_ENDL; } else + { filtersFile.close(); + } vector_replace_with_last(sActiveViews, this); gInventory.removeObserver(this); diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h index f260576c6..2d1706418 100644 --- a/indra/newview/llpanelmaininventory.h +++ b/indra/newview/llpanelmaininventory.h @@ -1,4 +1,4 @@ -/** + /** * @file llpanelmaininventory.h * @brief llpanelmaininventory.h * class definition @@ -80,9 +80,8 @@ public: void* cargo_data, EAcceptance* accept, std::string& tooltip_msg); - /*virtual*/ void changed(U32 mask); + /*virtual*/ void changed(U32); /*virtual*/ void draw(); - LLInventoryPanel* getPanel() { return mActivePanel; } LLInventoryPanel* getActivePanel() { return mActivePanel; } @@ -92,6 +91,7 @@ public: const std::string& getFilterText() const { return mFilterText; } void setSelectCallback(const LLFolderView::signal_t::slot_type& cb); + void onFilterEdit(const std::string& search_string); // // Misc functions @@ -106,14 +106,11 @@ public: static void onFoldersByName(void *user_data); static BOOL checkFoldersByName(void *user_data); - void onFilterSelected(); const std::string getFilterSubString(); void setFilterSubString(const std::string& string); - - static void onQuickFilterCommit(LLUICtrl* ctrl, void* user_data); static void refreshQuickFilter(LLUICtrl* ctrl); @@ -161,6 +158,7 @@ protected: protected: LLFloaterInventoryFinder* getFinder(); + LLFilterEditor* mFilterEditor; LLComboBox* mQuickFilterCombo; LLTabContainer* mFilterTabs; @@ -176,7 +174,6 @@ protected: static std::vector sActiveViews; }; - #endif // LL_LLPANELMAININVENTORY_H diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index 942556a43..cf28f992c 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -1651,7 +1651,7 @@ void LLPanelObjectInventory::reset() LLRect dummy_rect(0, 1, 1, 0); mFolders = new LLFolderView(std::string("task inventory"), dummy_rect, getTaskUUID(), this, LLTaskInvFVBridge::createObjectBridge(this, NULL)); // this ensures that we never say "searching..." or "no items found" - mFolders->getFilter()->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS); + mFolders->getFilter().setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS); LLRect scroller_rect(0, getRect().getHeight(), getRect().getWidth(), 0); mScroller = new LLScrollContainer(std::string("task inventory scroller"), scroller_rect, mFolders ); diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 5481c3c1f..a37348605 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -695,11 +695,10 @@ void LLFloaterTexturePicker::draw() LLFolderView* folder_view = mInventoryPanel->getRootFolder(); if (!folder_view) return; - LLInventoryFilter* filter = folder_view->getFilter(); - if (!filter) return; + LLInventoryFilter& filter = folder_view->getFilter(); - bool is_filter_active = folder_view->getCompletedFilterGeneration() < filter->getCurrentGeneration() && - filter->isNotDefault(); + bool is_filter_active = folder_view->getCompletedFilterGeneration() < filter.getCurrentGeneration() && + filter.isNotDefault(); // After inventory panel filter is applied we have to update // constraint rect for the selected item because of folder view