This patch adds a Quickfilter drop-down list in the Inventory floater, which allows the user to quickly change the inventory type filter. This is the BASIC version of the Quickfilter patch. There is also a FULL version of the Quickfilter patch, which contains changes to the inventory filtering engine to allow for more specific filtering by type. The main user-visible difference between the two versions is that the basic version lumps Clothing & Body Parts together as one option, while the full version has them as two separate options. This patch was generated against Second Life 1.21.6. It is available under the same terms as the Second Life viewer source (GPLv2 plus FOSS exception). Author: Jacek Antonelli Date: 2008-02-07 diff --git a/linden/indra/llui/llcombobox.cpp b/linden/indra/llui/llcombobox.cpp index 9a2e13b..cb9dd4e 100644 --- a/linden/indra/llui/llcombobox.cpp +++ b/linden/indra/llui/llcombobox.cpp @@ -194,6 +194,11 @@ LLView* LLComboBox::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory * combo_box->add(label, LLSD(value) ); } + + else if (child->hasName("separator")) + { + combo_box->addSeparator(); + } } } diff --git a/linden/indra/newview/llinventoryview.cpp b/linden/indra/newview/llinventoryview.cpp index f9dd70d..f64dd0d 100644 --- a/linden/indra/newview/llinventoryview.cpp +++ b/linden/indra/newview/llinventoryview.cpp @@ -44,6 +44,7 @@ #include "llradiogroup.h" #include "llspinctrl.h" #include "lltextbox.h" +#include "llcombobox.h" #include "llui.h" #include "llfirstuse.h" @@ -549,6 +550,12 @@ void LLInventoryView::init(LLInventoryModel* inventory) mSearchEditor->setSearchCallback(onSearchEdit, this); } + mQuickFilterCombo = getChild("Quick Filter"); + if (mQuickFilterCombo) + { + mQuickFilterCombo->setCommitCallback(onQuickFilterCommit); + } + sActiveViews.put(this); gInventory.addObserver(this); @@ -617,6 +624,11 @@ void LLInventoryView::draw() { mSearchEditor->setText(mActivePanel->getFilterSubString()); } + if (mActivePanel && mQuickFilterCombo) + { + refreshQuickFilter( mQuickFilterCombo ); + } + LLFloater::draw(); } @@ -981,6 +993,238 @@ void LLInventoryView::onSearchEdit(const std::string& search_string, void* user_ } +//static +void LLInventoryView::onQuickFilterCommit(LLUICtrl* ctrl, void* user_data) +{ + + LLComboBox* quickfilter = (LLComboBox*)ctrl; + + + LLInventoryView* view = (LLInventoryView*)(quickfilter->getParent()); + if (!view->mActivePanel) + { + return; + } + + + std::string item_type = quickfilter->getSimple(); + U32 filter_type; + + if (view->getString("filter_type_animation") == item_type) + { + filter_type = 0x1 << LLInventoryType::IT_ANIMATION; + } + + else if (view->getString("filter_type_callingcard") == item_type) + { + filter_type = 0x1 << LLInventoryType::IT_CALLINGCARD; + } + + else if (view->getString("filter_type_wearable") == item_type) + { + filter_type = 0x1 << LLInventoryType::IT_WEARABLE; + } + + else if (view->getString("filter_type_gesture") == item_type) + { + filter_type = 0x1 << LLInventoryType::IT_GESTURE; + } + + else if (view->getString("filter_type_landmark") == item_type) + { + filter_type = 0x1 << LLInventoryType::IT_LANDMARK; + } + + else if (view->getString("filter_type_notecard") == item_type) + { + filter_type = 0x1 << LLInventoryType::IT_NOTECARD; + } + + else if (view->getString("filter_type_object") == item_type) + { + filter_type = 0x1 << LLInventoryType::IT_OBJECT; + } + + else if (view->getString("filter_type_script") == item_type) + { + filter_type = 0x1 << LLInventoryType::IT_LSL; + } + + else if (view->getString("filter_type_sound") == item_type) + { + filter_type = 0x1 << LLInventoryType::IT_SOUND; + } + + else if (view->getString("filter_type_texture") == item_type) + { + filter_type = 0x1 << LLInventoryType::IT_TEXTURE; + } + + else if (view->getString("filter_type_snapshot") == item_type) + { + filter_type = 0x1 << LLInventoryType::IT_SNAPSHOT; + } + + else if (view->getString("filter_type_custom") == item_type) + { + // When they select custom, show the floater then return + if( !(view->filtersVisible(view)) ) + { + view->toggleFindOptions(); + } + return; + } + + else if (view->getString("filter_type_all") == item_type) + { + // Show all types + filter_type = 0xffffffff; + } + + else + { + llwarns << "Ignoring unknown filter: " << item_type << llendl; + return; + } + + view->mActivePanel->setFilterTypes( filter_type ); + + + // Force the filters window to update itself, if it's open. + LLInventoryViewFinder* finder = view->getFinder(); + if( finder ) + { + finder->updateElementsFromFilter(); + } + + // llinfos << "Quick Filter: " << item_type << llendl; + +} + + + +//static +void LLInventoryView::refreshQuickFilter(LLUICtrl* ctrl) +{ + + LLInventoryView* view = (LLInventoryView*)(ctrl->getParent()); + if (!view->mActivePanel) + { + return; + } + + LLComboBox* quickfilter = view->getChild("Quick Filter"); + if (!quickfilter) + { + return; + } + + + U32 filter_type = view->mActivePanel->getFilterTypes(); + + + // Mask to extract only the bit fields we care about. + // *TODO: There's probably a cleaner way to construct this mask. + U32 filter_mask = 0; + filter_mask |= (0x1 << LLInventoryType::IT_ANIMATION); + filter_mask |= (0x1 << LLInventoryType::IT_CALLINGCARD); + filter_mask |= (0x1 << LLInventoryType::IT_WEARABLE); + filter_mask |= (0x1 << LLInventoryType::IT_GESTURE); + filter_mask |= (0x1 << LLInventoryType::IT_LANDMARK); + filter_mask |= (0x1 << LLInventoryType::IT_NOTECARD); + filter_mask |= (0x1 << LLInventoryType::IT_OBJECT); + filter_mask |= (0x1 << LLInventoryType::IT_LSL); + filter_mask |= (0x1 << LLInventoryType::IT_SOUND); + filter_mask |= (0x1 << LLInventoryType::IT_TEXTURE); + filter_mask |= (0x1 << LLInventoryType::IT_SNAPSHOT); + + + filter_type &= filter_mask; + + + //llinfos << "filter_type: " << filter_type << llendl; + + std::string selection; + + + if (filter_type == filter_mask) + { + selection = view->getString("filter_type_all"); + } + + else if (filter_type == (0x1 << LLInventoryType::IT_ANIMATION)) + { + selection = view->getString("filter_type_animation"); + } + + else if (filter_type == (0x1 << LLInventoryType::IT_CALLINGCARD)) + { + selection = view->getString("filter_type_callingcard"); + } + + else if (filter_type == (0x1 << LLInventoryType::IT_WEARABLE)) + { + selection = view->getString("filter_type_wearable"); + } + + else if (filter_type == (0x1 << LLInventoryType::IT_GESTURE)) + { + selection = view->getString("filter_type_gesture"); + } + + else if (filter_type == (0x1 << LLInventoryType::IT_LANDMARK)) + { + selection = view->getString("filter_type_landmark"); + } + + else if (filter_type == (0x1 << LLInventoryType::IT_NOTECARD)) + { + selection = view->getString("filter_type_notecard"); + } + + else if (filter_type == (0x1 << LLInventoryType::IT_OBJECT)) + { + selection = view->getString("filter_type_object"); + } + + else if (filter_type == (0x1 << LLInventoryType::IT_LSL)) + { + selection = view->getString("filter_type_script"); + } + + else if (filter_type == (0x1 << LLInventoryType::IT_SOUND)) + { + selection = view->getString("filter_type_sound"); + } + + else if (filter_type == (0x1 << LLInventoryType::IT_TEXTURE)) + { + selection = view->getString("filter_type_texture"); + } + + else if (filter_type == (0x1 << LLInventoryType::IT_SNAPSHOT)) + { + selection = view->getString("filter_type_snapshot"); + } + + else + { + selection = view->getString("filter_type_custom"); + } + + + // Select the chosen item by label text + BOOL result = quickfilter->setSimple( (selection) ); + + if( !result ) + { + llinfos << "The item didn't exist: " << selection << llendl; + } + +} + + + // static // BOOL LLInventoryView::incrementalFind(LLFolderViewItem* first_item, const char *find_text, BOOL backward) // { diff --git a/linden/indra/newview/llinventoryview.h b/linden/indra/newview/llinventoryview.h index a37d370..cce30aa 100644 --- a/linden/indra/newview/llinventoryview.h +++ b/linden/indra/newview/llinventoryview.h @@ -58,6 +58,7 @@ class LLCheckBoxCtrl; class LLSpinCtrl; class LLScrollableContainerView; class LLTextBox; +class LLComboBox; class LLIconCtrl; class LLSaveFolderState; class LLSearchEditor; @@ -239,6 +240,8 @@ public: static void onFoldersByName(void *user_data); static BOOL checkFoldersByName(void *user_data); static void onSearchEdit(const std::string& search_string, void* user_data ); + static void onQuickFilterCommit(LLUICtrl* ctrl, void* user_data); + static void refreshQuickFilter(LLUICtrl* ctrl); static void onFilterSelected(void* userdata, bool from_click); static void onSelectionChange(const std::deque &items, BOOL user_action, void* data); @@ -259,6 +262,7 @@ protected: protected: LLSearchEditor* mSearchEditor; + LLComboBox* mQuickFilterCombo; LLTabContainer* mFilterTabs; LLHandle mFinderHandle; LLInventoryPanel* mActivePanel; diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_inventory.xml b/linden/indra/newview/skins/default/xui/en-us/floater_inventory.xml index 1cb1da0..9bcb848 100644 --- a/linden/indra/newview/skins/default/xui/en-us/floater_inventory.xml +++ b/linden/indra/newview/skins/default/xui/en-us/floater_inventory.xml @@ -5,18 +5,62 @@ title="Inventory" width="467"> - + + + Quick Filter: + + + + All Types + Animations + Calling Cards + Clothing / Body Parts + Gestures + Landmarks + Notecards + Objects + Scripts + Sounds + Textures + Snapshots + Custom... + + + + All Types + + Animations + Calling Cards + Clothing / Body Parts + Gestures + Landmarks + Notecards + Objects + Scripts + Sounds + Textures + Snapshots + + Custom... + + + + + + - - - - - - - - - - - - - - - - - - - - - - - -