Merge branch 'master' of git@github.com:Shyotl/SingularityViewer.git
This commit is contained in:
@@ -416,12 +416,17 @@ U32 LLInventoryItem::getCRC32() const
|
||||
return crc;
|
||||
}
|
||||
|
||||
// static
|
||||
void LLInventoryItem::correctInventoryDescription(std::string& desc)
|
||||
{
|
||||
LLStringUtil::replaceNonstandardASCII(desc, ' ');
|
||||
LLStringUtil::replaceChar(desc, '|', ' ');
|
||||
}
|
||||
|
||||
void LLInventoryItem::setDescription(const std::string& d)
|
||||
{
|
||||
std::string new_desc(d);
|
||||
LLStringUtil::replaceNonstandardASCII(new_desc, ' ');
|
||||
LLStringUtil::replaceChar(new_desc, '|', ' ');
|
||||
LLInventoryItem::correctInventoryDescription(new_desc);
|
||||
if( new_desc != mDescription )
|
||||
{
|
||||
mDescription = new_desc;
|
||||
|
||||
@@ -177,6 +177,7 @@ public:
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
void setAssetUUID(const LLUUID& asset_id);
|
||||
static void correctInventoryDescription(std::string& name);
|
||||
void setDescription(const std::string& new_desc);
|
||||
void setSaleInfo(const LLSaleInfo& sale_info);
|
||||
void setPermissions(const LLPermissions& perm);
|
||||
|
||||
@@ -53,6 +53,7 @@ struct InventoryEntry : public LLDictionaryEntry
|
||||
LLAssetType::EType t = (LLAssetType::EType)va_arg(argp,int);
|
||||
mAssetTypes.push_back(t);
|
||||
}
|
||||
va_end(argp);
|
||||
}
|
||||
|
||||
const std::string mHumanName;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* (in header)
|
||||
*
|
||||
* class T {
|
||||
* class LLDoTest : public LLMemberListener<LLInventoryView>
|
||||
* class LLDoTest : public LLMemberListener<LLPanelMainInventory>
|
||||
* {
|
||||
* bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata);
|
||||
* };
|
||||
|
||||
@@ -4618,7 +4618,7 @@ void LLAppViewer::disconnectViewer()
|
||||
saveNameCache();
|
||||
|
||||
// close inventory interface, close all windows
|
||||
LLInventoryView::cleanup();
|
||||
LLPanelMainInventory::cleanup();
|
||||
// [SL:KB] - Patch: Appearance-Misc | Checked: 2013-02-12 (Catznip-3.4)
|
||||
// Destroying all objects below will trigger attachment detaching code and attempt to remove the COF links for them
|
||||
LLAppearanceMgr::instance().setAttachmentInvLinkEnable(false);
|
||||
|
||||
@@ -572,7 +572,7 @@ void LLAvatarActions::share(const LLUUID& id)
|
||||
LLFloaterSidePanelContainer::showPanel("inventory", key);
|
||||
LLFloaterReg::showInstance("im_container");
|
||||
*/
|
||||
LLInventoryView::getActiveInventory()->setVisible(true);
|
||||
LLPanelMainInventory::getActiveInventory()->setVisible(true);
|
||||
|
||||
LLUUID session_id = gIMMgr->computeSessionID(IM_NOTHING_SPECIAL, id);
|
||||
|
||||
|
||||
@@ -331,7 +331,7 @@ void LLFloaterGesture::onClickInventory(void* data)
|
||||
if (!list) return;
|
||||
const LLUUID& item_id = list->getCurrentID();
|
||||
|
||||
LLInventoryView* inv = LLInventoryView::showAgentInventory();
|
||||
LLPanelMainInventory* inv = LLPanelMainInventory::showAgentInventory();
|
||||
if (!inv) return;
|
||||
inv->getPanel()->setSelection(item_id, TRUE);
|
||||
}
|
||||
|
||||
@@ -72,7 +72,6 @@ LLFloaterLandmark::LLFloaterLandmark(const LLSD& data)
|
||||
mFilterEdit(NULL),
|
||||
mContextConeOpacity(0.f),
|
||||
mInventoryPanel(NULL),
|
||||
mSavedFolderState(NULL),
|
||||
mNoCopyLandmarkSelected( FALSE )
|
||||
{
|
||||
LLUICtrlFactory::getInstance()->buildFloater(this,"floater_landmark_ctrl.xml");
|
||||
@@ -115,7 +114,6 @@ BOOL LLFloaterLandmark::postBuild()
|
||||
mInventoryPanel->setSelection(findItemID(mImageAssetID, FALSE), TAKE_FOCUS_NO);
|
||||
}
|
||||
|
||||
mSavedFolderState = new LLSaveFolderState();
|
||||
mNoCopyLandmarkSelected = FALSE;
|
||||
|
||||
getChild<LLButton>("Close")->setClickedCallback(boost::bind(&LLFloaterLandmark::onBtnClose,this));
|
||||
@@ -127,15 +125,11 @@ BOOL LLFloaterLandmark::postBuild()
|
||||
|
||||
setCanMinimize(FALSE);
|
||||
|
||||
mSavedFolderState->setApply(FALSE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
LLFloaterLandmark::~LLFloaterLandmark()
|
||||
{
|
||||
delete mSavedFolderState;
|
||||
mSavedFolderState = NULL;
|
||||
}
|
||||
|
||||
void LLFloaterLandmark::setActive( BOOL active )
|
||||
@@ -394,35 +388,13 @@ void LLFloaterLandmark::onShowFolders(LLUICtrl* ctrl)
|
||||
|
||||
void LLFloaterLandmark::onFilterEdit(const LLSD& value )
|
||||
{
|
||||
std::string upper_case_search_string = value.asString();
|
||||
LLStringUtil::toUpper(upper_case_search_string);
|
||||
|
||||
if (upper_case_search_string.empty())
|
||||
if (!mInventoryPanel)
|
||||
{
|
||||
if (mInventoryPanel->getFilterSubString().empty())
|
||||
{
|
||||
// current filter and new filter empty, do nothing
|
||||
return;
|
||||
}
|
||||
|
||||
mSavedFolderState->setApply(TRUE);
|
||||
mInventoryPanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
|
||||
// add folder with current item to list of previously opened folders
|
||||
LLOpenFoldersWithSelection opener;
|
||||
mInventoryPanel->getRootFolder()->applyFunctorRecursively(opener);
|
||||
mInventoryPanel->getRootFolder()->scrollToShowSelection();
|
||||
|
||||
}
|
||||
else if (mInventoryPanel->getFilterSubString().empty())
|
||||
{
|
||||
// first letter in search term, save existing folder open state
|
||||
if (!mInventoryPanel->getRootFolder()->isFilterModified())
|
||||
{
|
||||
mSavedFolderState->setApply(FALSE);
|
||||
mInventoryPanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
mInventoryPanel->setFilterSubString(upper_case_search_string);
|
||||
// set new filter string
|
||||
// Internally handles saving/restoring folder states.
|
||||
mInventoryPanel->setFilterSubString(value.asString());
|
||||
}
|
||||
|
||||
|
||||
@@ -113,7 +113,6 @@ protected:
|
||||
PermissionMask mNonImmediateFilterPermMask;
|
||||
BOOL mNoCopyLandmarkSelected;
|
||||
F32 mContextConeOpacity;
|
||||
LLSaveFolderState* mSavedFolderState;
|
||||
};
|
||||
|
||||
#endif // LL_FLOATERLANDMARK_H
|
||||
|
||||
@@ -447,7 +447,7 @@ S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_gen
|
||||
|
||||
LLFastTimer t2(FTM_ARRANGE);
|
||||
|
||||
filter_generation = mFilter->getMinRequiredGeneration();
|
||||
filter_generation = mFilter->getFirstSuccessGeneration();
|
||||
mMinWidth = 0;
|
||||
|
||||
mHasVisibleChildren = hasFilteredDescendants(filter_generation);
|
||||
@@ -908,7 +908,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->getMinRequiredGeneration(), mFilter->getMustPassGeneration());
|
||||
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 );
|
||||
@@ -954,7 +954,7 @@ void LLFolderView::draw()
|
||||
else if (mShowEmptyMessage)
|
||||
{
|
||||
static LLCachedControl<LLColor4> sSearchStatusColor(gColors, "InventorySearchStatusColor", LLColor4::white );
|
||||
if (LLInventoryModelBackgroundFetch::instance().folderFetchActive() || mCompletedFilterGeneration < mFilter->getMinRequiredGeneration())
|
||||
if (LLInventoryModelBackgroundFetch::instance().folderFetchActive() || mCompletedFilterGeneration < mFilter->getFirstSuccessGeneration())
|
||||
{
|
||||
mStatusText = LLTrans::getString("Searching");
|
||||
}
|
||||
@@ -2385,6 +2385,22 @@ void LLFolderView::updateMenu()
|
||||
}
|
||||
}
|
||||
|
||||
void LLFolderView::saveFolderState()
|
||||
{
|
||||
mSavedFolderState = std::unique_ptr<LLSaveFolderState>(new LLSaveFolderState());
|
||||
applyFunctorRecursively(*mSavedFolderState);
|
||||
}
|
||||
|
||||
void LLFolderView::restoreFolderState()
|
||||
{
|
||||
if (mSavedFolderState)
|
||||
{
|
||||
mSavedFolderState->setApply(true);
|
||||
applyFunctorRecursively(*mSavedFolderState);
|
||||
mSavedFolderState.reset();
|
||||
}
|
||||
}
|
||||
|
||||
bool LLFolderView::selectFirstItem()
|
||||
{
|
||||
for (folders_t::iterator iter = mFolders.begin();
|
||||
|
||||
@@ -63,6 +63,7 @@ class LLMenuGL;
|
||||
class LLScrollContainer;
|
||||
class LLUICtrl;
|
||||
class LLTextBox;
|
||||
class LLSaveFolderState;
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Class LLFolderView
|
||||
@@ -258,6 +259,8 @@ public:
|
||||
|
||||
bool useLabelSuffix() { return mUseLabelSuffix; }
|
||||
void updateMenu();
|
||||
void saveFolderState();
|
||||
void restoreFolderState();
|
||||
|
||||
// Note: We may eventually have to move that method up the hierarchy to LLFolderViewItem.
|
||||
LLHandle<LLFolderView> getHandle() const { return getDerivedHandle<LLFolderView>(); }
|
||||
@@ -279,6 +282,9 @@ protected:
|
||||
bool selectLastItem();
|
||||
|
||||
BOOL addNoOptions(LLMenuGL* menu) const;
|
||||
|
||||
private:
|
||||
std::unique_ptr<LLSaveFolderState> mSavedFolderState;
|
||||
protected:
|
||||
LLHandle<LLView> mPopupMenuHandle;
|
||||
|
||||
|
||||
@@ -210,12 +210,12 @@ BOOL LLFolderViewItem::potentiallyVisible()
|
||||
{
|
||||
// we haven't been checked against min required filter
|
||||
// or we have and we passed
|
||||
return getLastFilterGeneration() < getRoot()->getFilter()->getMinRequiredGeneration() || getFiltered();
|
||||
return getLastFilterGeneration() < getRoot()->getFilter()->getFirstSuccessGeneration() || getFiltered();
|
||||
}
|
||||
|
||||
BOOL LLFolderViewItem::getFiltered()
|
||||
{
|
||||
return mPassedFilter && mLastFilterGeneration >= getRoot()->getFilter()->getMinRequiredGeneration();
|
||||
return mPassedFilter && mLastFilterGeneration >= getRoot()->getFilter()->getFirstSuccessGeneration();
|
||||
}
|
||||
|
||||
BOOL LLFolderViewItem::getFiltered(S32 filter_generation)
|
||||
@@ -1158,7 +1158,7 @@ void LLFolderViewFolder::setFilteredFolder(bool filtered, S32 filter_generation)
|
||||
|
||||
bool LLFolderViewFolder::getFilteredFolder(S32 filter_generation)
|
||||
{
|
||||
return mPassedFolderFilter && mLastFilterGeneration >= getRoot()->getFilter()->getMinRequiredGeneration();
|
||||
return mPassedFolderFilter && mLastFilterGeneration >= getRoot()->getFilter()->getFirstSuccessGeneration();
|
||||
}
|
||||
|
||||
// addToFolder() returns TRUE if it succeeds. FALSE otherwise
|
||||
@@ -1355,7 +1355,7 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)
|
||||
// if failed to pass filter newer than must_pass_generation
|
||||
// you will automatically fail this time, so we only
|
||||
// check against items that have passed the filter
|
||||
S32 must_pass_generation = filter.getMustPassGeneration();
|
||||
S32 must_pass_generation = filter.getFirstRequiredGeneration();
|
||||
|
||||
bool autoopen_folders = (filter.hasFilterString());
|
||||
|
||||
@@ -1408,7 +1408,7 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)
|
||||
|
||||
// when applying a filter, matching folders get their contents downloaded first
|
||||
if (filter.isNotDefault()
|
||||
&& getFiltered(filter.getMinRequiredGeneration())
|
||||
&& getFiltered(filter.getFirstSuccessGeneration())
|
||||
&& (mListener
|
||||
&& !gInventory.isCategoryComplete(mListener->getUUID())))
|
||||
{
|
||||
@@ -1433,7 +1433,7 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)
|
||||
if (folder->getCompletedFilterGeneration() >= filter_generation)
|
||||
{
|
||||
// track latest generation to pass any child items
|
||||
if (folder->getFiltered() || folder->hasFilteredDescendants(filter.getMinRequiredGeneration()))
|
||||
if (folder->getFiltered() || folder->hasFilteredDescendants(filter.getFirstSuccessGeneration()))
|
||||
{
|
||||
mMostFilteredDescendantGeneration = filter_generation;
|
||||
requestArrange();
|
||||
@@ -1487,7 +1487,7 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)
|
||||
|
||||
item->filter( filter );
|
||||
|
||||
if (item->getFiltered(filter.getMinRequiredGeneration()))
|
||||
if (item->getFiltered(filter.getFirstSuccessGeneration()))
|
||||
{
|
||||
mMostFilteredDescendantGeneration = filter_generation;
|
||||
requestArrange();
|
||||
@@ -1552,7 +1552,7 @@ void LLFolderViewFolder::dirtyFilter()
|
||||
|
||||
BOOL LLFolderViewFolder::getFiltered()
|
||||
{
|
||||
return getFilteredFolder(getRoot()->getFilter()->getMinRequiredGeneration())
|
||||
return getFilteredFolder(getRoot()->getFilter()->getFirstSuccessGeneration())
|
||||
&& LLFolderViewItem::getFiltered();
|
||||
}
|
||||
|
||||
@@ -2572,9 +2572,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()->getMinRequiredGeneration())
|
||||
|| hasFilteredDescendants(getRoot()->getFilter()->getFirstSuccessGeneration())
|
||||
// or not all of its descendants have been checked against minimum filter requirement
|
||||
|| getCompletedFilterGeneration() < getRoot()->getFilter()->getMinRequiredGeneration();
|
||||
|| getCompletedFilterGeneration() < getRoot()->getFilter()->getFirstSuccessGeneration();
|
||||
}
|
||||
|
||||
// this does prefix traversal, as folders are listed above their contents
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace LLInventoryAction
|
||||
}
|
||||
|
||||
typedef LLMemberListener<LLPanelObjectInventory> object_inventory_listener_t;
|
||||
typedef LLMemberListener<LLInventoryView> inventory_listener_t;
|
||||
typedef LLMemberListener<LLPanelMainInventory> inventory_listener_t;
|
||||
typedef LLMemberListener<LLInventoryPanel> inventory_panel_listener_t;
|
||||
|
||||
bool LLInventoryAction::doToSelected(LLFolderView* folder, std::string action)
|
||||
@@ -143,7 +143,7 @@ struct LLNewWindow : public inventory_listener_t
|
||||
S32 left = 0 , top = 0;
|
||||
gFloaterView->getNewFloaterPosition(&left, &top);
|
||||
rect.setLeftTopAndSize(left, top, rect.getWidth(), rect.getHeight());
|
||||
LLInventoryView* iv = new LLInventoryView(std::string("Inventory"),
|
||||
LLPanelMainInventory* iv = new LLPanelMainInventory(std::string("Inventory"),
|
||||
rect,
|
||||
mPtr->getActivePanel()->getModel());
|
||||
iv->getActivePanel()->setFilterTypes(mPtr->getActivePanel()->getFilterObjectTypes());
|
||||
@@ -467,15 +467,15 @@ void init_object_inventory_panel_actions(LLPanelObjectInventory *panel)
|
||||
(new LLBindMemberListener(panel, "Inventory.DoToSelected", boost::bind(&LLInventoryAction::doToSelected, boost::bind(&LLPanelObjectInventory::getRootFolder, panel), _2)));
|
||||
}
|
||||
|
||||
void init_inventory_actions(LLInventoryView *floater)
|
||||
void init_inventory_actions(LLPanelMainInventory *floater)
|
||||
{
|
||||
(new LLBindMemberListener(floater, "Inventory.DoToSelected", boost::bind(&LLInventoryAction::doToSelected, boost::bind(&LLInventoryView::getRootFolder, floater), _2)));
|
||||
(new LLBindMemberListener(floater, "Inventory.CloseAllFolders", boost::bind(&LLInventoryPanel::closeAllFolders, boost::bind(&LLInventoryView::getPanel, floater))));
|
||||
(new LLBindMemberListener(floater, "Inventory.DoToSelected", boost::bind(&LLInventoryAction::doToSelected, boost::bind(&LLPanelMainInventory::getRootFolder, floater), _2)));
|
||||
(new LLBindMemberListener(floater, "Inventory.CloseAllFolders", boost::bind(&LLInventoryPanel::closeAllFolders, boost::bind(&LLPanelMainInventory::getPanel, floater))));
|
||||
(new LLBindMemberListener(floater, "Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "", LLFolderType::FT_TRASH)));
|
||||
(new LLBindMemberListener(floater, "Inventory.DoCreate", boost::bind(&do_create, &gInventory, boost::bind(&LLInventoryView::getPanel, floater), _2, (LLFolderBridge*)0)));
|
||||
(new LLBindMemberListener(floater, "Inventory.DoCreate", boost::bind(&do_create, &gInventory, boost::bind(&LLPanelMainInventory::getPanel, floater), _2, (LLFolderBridge*)0)));
|
||||
(new LLNewWindow())->registerListener(floater, "Inventory.NewWindow");
|
||||
(new LLBindMemberListener(floater, "Inventory.ShowFilters", boost::bind(&LLInventoryView::toggleFindOptions, floater)));
|
||||
(new LLBindMemberListener(floater, "Inventory.ResetFilter", boost::bind(&LLInventoryView::resetFilters, floater)));
|
||||
(new LLBindMemberListener(floater, "Inventory.ShowFilters", boost::bind(&LLPanelMainInventory::toggleFindOptions, floater)));
|
||||
(new LLBindMemberListener(floater, "Inventory.ResetFilter", boost::bind(&LLPanelMainInventory::resetFilters, floater)));
|
||||
(new LLSetSortBy())->registerListener(floater, "Inventory.SetSortBy");
|
||||
(new LLSetSearchType())->registerListener(floater, "Inventory.SetSearchType");
|
||||
}
|
||||
|
||||
@@ -1036,6 +1036,12 @@ LLInventoryModel* LLInvFVBridge::getInventoryModel() const
|
||||
return panel ? panel->getModel() : NULL;
|
||||
}
|
||||
|
||||
LLInventoryFilter* LLInvFVBridge::getInventoryFilter() const
|
||||
{
|
||||
LLInventoryPanel* panel = mInventoryPanel.get();
|
||||
return panel ? panel->getFilter() : NULL;
|
||||
}
|
||||
|
||||
BOOL LLInvFVBridge::isItemInTrash() const
|
||||
{
|
||||
LLInventoryModel* model = getInventoryModel();
|
||||
@@ -6305,7 +6311,7 @@ void LLLinkFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
|
||||
else
|
||||
{
|
||||
getClipboardEntries(false, items, disabled_items, flags);
|
||||
if (LLInventoryView::getActiveInventory() && !isOutboxFolder() && isAgentInventory())
|
||||
if (LLPanelMainInventory::getActiveInventory() && !isOutboxFolder() && isAgentInventory())
|
||||
build_context_menu_folder_options(getInventoryModel(), getFolderID(), items, disabled_items);
|
||||
addDeleteContextMenuOptions(items, disabled_items);
|
||||
}
|
||||
@@ -6339,7 +6345,7 @@ void LLLinkFolderBridge::performAction(LLInventoryModel* model, std::string acti
|
||||
copyToClipboard();
|
||||
return;
|
||||
}
|
||||
if (LLInventoryView* iv = LLInventoryView::getActiveInventory())
|
||||
if (LLPanelMainInventory* iv = LLPanelMainInventory::getActiveInventory())
|
||||
{
|
||||
if (LLFolderViewItem* folder_item = iv->getActivePanel()->getRootFolder()->getItemByID(getFolderID()))
|
||||
{
|
||||
@@ -6508,7 +6514,7 @@ public:
|
||||
virtual void doIt()
|
||||
{
|
||||
LLViewerInventoryItem* item = getItem();
|
||||
if (item)
|
||||
if (item && item->getCreatorUUID().notNull())
|
||||
{
|
||||
LLAvatarActions::showProfile(item->getCreatorUUID());
|
||||
}
|
||||
|
||||
@@ -145,6 +145,7 @@ protected:
|
||||
LLInvFVBridge(LLInventoryPanel* inventory, LLFolderView* root, const LLUUID& uuid);
|
||||
|
||||
LLInventoryModel* getInventoryModel() const;
|
||||
LLInventoryFilter* getInventoryFilter() const;
|
||||
|
||||
BOOL isLinkedObjectInTrash() const; // Is this obj or its baseobj in the trash?
|
||||
BOOL isLinkedObjectMissing() const; // Is this a linked obj whose baseobj is not in inventory?
|
||||
@@ -467,6 +468,7 @@ public:
|
||||
virtual LLUIImagePtr getIcon() const;
|
||||
virtual void performAction(LLInventoryModel* model, std::string action);
|
||||
virtual void openItem();
|
||||
virtual BOOL isItemWearable() const { return TRUE; }
|
||||
virtual std::string getLabelSuffix() const;
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
virtual BOOL renameItem(const std::string& new_name);
|
||||
@@ -500,6 +502,7 @@ public:
|
||||
virtual LLUIImagePtr getIcon() const;
|
||||
virtual void performAction(LLInventoryModel* model, std::string action);
|
||||
virtual void openItem();
|
||||
virtual BOOL isItemWearable() const { return TRUE; }
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
virtual std::string getLabelSuffix() const;
|
||||
virtual BOOL renameItem(const std::string& new_name);
|
||||
|
||||
@@ -65,21 +65,17 @@ LLInventoryFilter::FilterOps::FilterOps() :
|
||||
///----------------------------------------------------------------------------
|
||||
LLInventoryFilter::LLInventoryFilter(const std::string& name)
|
||||
: mName(name),
|
||||
mModified(FALSE),
|
||||
mNeedTextRebuild(TRUE)
|
||||
mFilterModified(FILTER_NONE),
|
||||
mFilterOps(),
|
||||
mFilterSubString(),
|
||||
mCurrentGeneration(0),
|
||||
mFirstRequiredGeneration(0),
|
||||
mFirstSuccessGeneration(0)
|
||||
{
|
||||
mOrder = SO_FOLDERS_BY_NAME; // This gets overridden by a pref immediately
|
||||
|
||||
mSubStringMatchOffset = 0;
|
||||
mFilterSubString.clear();
|
||||
mFilterGeneration = 0;
|
||||
mMustPassGeneration = S32_MAX;
|
||||
mMinRequiredGeneration = 0;
|
||||
mSubStringMatchOffset = std::string::npos;
|
||||
mFilterCount = 0;
|
||||
mNextFilterGeneration = mFilterGeneration + 1;
|
||||
|
||||
mLastLogoff = gSavedPerAccountSettings.getU32("LastLogoff");
|
||||
mFilterBehavior = FILTER_NONE;
|
||||
|
||||
// copy mFilterOps into mDefaultFilterOps
|
||||
markDefault();
|
||||
@@ -89,7 +85,7 @@ LLInventoryFilter::~LLInventoryFilter()
|
||||
{
|
||||
}
|
||||
|
||||
BOOL LLInventoryFilter::check(LLFolderViewItem* item)
|
||||
bool LLInventoryFilter::check(LLFolderViewItem* item)
|
||||
{
|
||||
// Clipboard cut items are *always* filtered so we need this value upfront
|
||||
const LLFolderViewEventListener* listener = item->getListener();
|
||||
@@ -116,6 +112,33 @@ BOOL LLInventoryFilter::check(LLFolderViewItem* item)
|
||||
passed_wearable &&
|
||||
(mFilterSubString.size() == 0 || mSubStringMatchOffset != std::string::npos));
|
||||
|
||||
if (!passed)
|
||||
{
|
||||
bool passed_label = (mFilterSubString.size() == 0 || mSubStringMatchOffset != std::string::npos);
|
||||
LL_INFOS() << item->getSearchableLabel() << " filtered." <<
|
||||
" passed_filtertype:" << passed_filtertype <<
|
||||
" passed_permissions:" << passed_permissions <<
|
||||
" passed_filterlink:" << passed_filterlink <<
|
||||
" passed_wearable:" << passed_wearable <<
|
||||
" passed_label:" << passed_label <<
|
||||
" passed:" << passed;
|
||||
|
||||
if ((mFilterOps.mFilterTypes & FILTERTYPE_NONE))
|
||||
LL_CONT << " FILTERTYPE_NONE ";
|
||||
if ((mFilterOps.mFilterTypes & FILTERTYPE_OBJECT) )
|
||||
LL_CONT << " FILTERTYPE_OBJECT ";
|
||||
if ((mFilterOps.mFilterTypes & FILTERTYPE_CATEGORY))
|
||||
LL_CONT << " FILTERTYPE_CATEGORY ";
|
||||
if ((mFilterOps.mFilterTypes & FILTERTYPE_UUID))
|
||||
LL_CONT << " FILTERTYPE_UUID ";
|
||||
if ((mFilterOps.mFilterTypes & FILTERTYPE_DATE))
|
||||
LL_CONT << " FILTERTYPE_DATE ";
|
||||
if ((mFilterOps.mFilterTypes & FILTERTYPE_WEARABLE))
|
||||
LL_CONT << " FILTERTYPE_WEARABLE ";
|
||||
if ((mFilterOps.mFilterTypes & FILTERTYPE_EMPTYFOLDERS))
|
||||
LL_CONT << " FILTERTYPE_EMPTYFOLDERS ";
|
||||
LL_CONT << LL_ENDL;
|
||||
}
|
||||
return passed;
|
||||
}
|
||||
|
||||
@@ -137,7 +160,12 @@ bool LLInventoryFilter::checkFolder(const LLFolderViewFolder* folder) const
|
||||
}
|
||||
|
||||
const LLUUID folder_id = listener->getUUID();
|
||||
|
||||
|
||||
return checkFolder(folder_id);
|
||||
}
|
||||
|
||||
bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const
|
||||
{
|
||||
// Always check against the clipboard
|
||||
const BOOL passed_clipboard = checkAgainstClipboard(folder_id);
|
||||
|
||||
@@ -147,13 +175,19 @@ bool LLInventoryFilter::checkFolder(const LLFolderViewFolder* folder) const
|
||||
return passed_clipboard;
|
||||
}
|
||||
|
||||
// when applying a filter, matching folders get their contents downloaded first
|
||||
if (isNotDefault()
|
||||
&& !gInventory.isCategoryComplete(folder_id))
|
||||
{
|
||||
LLInventoryModelBackgroundFetch::instance().start(folder_id);
|
||||
}
|
||||
if (mFilterOps.mFilterTypes & FILTERTYPE_CATEGORY)
|
||||
{
|
||||
// Can only filter categories for items in your inventory
|
||||
// (e.g. versus in-world object contents).
|
||||
const LLViewerInventoryCategory *cat = gInventory.getCategory(folder_id);
|
||||
if (!cat)
|
||||
return false;
|
||||
return folder_id.isNull();
|
||||
LLFolderType::EType cat_type = cat->getPreferredType();
|
||||
if (cat_type != LLFolderType::FT_NONE && (1LL << cat_type & mFilterOps.mFilterCategoryTypes) == U64(0))
|
||||
return false;
|
||||
@@ -162,7 +196,7 @@ bool LLInventoryFilter::checkFolder(const LLFolderViewFolder* folder) const
|
||||
return passed_clipboard;
|
||||
}
|
||||
|
||||
BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) const
|
||||
bool LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) const
|
||||
{
|
||||
const LLFolderViewEventListener* listener = item->getListener();
|
||||
if (!listener) return FALSE;
|
||||
@@ -183,11 +217,13 @@ BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) con
|
||||
{
|
||||
if (object && object->getIsLinkType())
|
||||
{
|
||||
LL_INFOS() << "getIsLinkType" << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else if ((1LL << object_type & mFilterOps.mFilterObjectTypes) == U64(0))
|
||||
{
|
||||
LL_INFOS() << "Filtered type" << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@@ -197,10 +233,17 @@ BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) con
|
||||
// Pass if this item is the target UUID or if it links to the target UUID
|
||||
if (filterTypes & FILTERTYPE_UUID)
|
||||
{
|
||||
if (!object) return FALSE;
|
||||
if (!object)
|
||||
{
|
||||
LL_INFOS() << "UUID type" << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (object->getLinkedUUID() != mFilterOps.mFilterUUID)
|
||||
{
|
||||
LL_INFOS() << "getLinkedUUID type" << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -210,6 +253,7 @@ BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) con
|
||||
{
|
||||
const U16 HOURS_TO_SECONDS = 3600;
|
||||
time_t earliest = time_corrected() - mFilterOps.mHoursAgo * HOURS_TO_SECONDS;
|
||||
|
||||
if (mFilterOps.mMinDate > time_min() && mFilterOps.mMinDate < earliest)
|
||||
{
|
||||
earliest = mFilterOps.mMinDate;
|
||||
@@ -220,7 +264,10 @@ BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) con
|
||||
}
|
||||
if (listener->getCreationDate() < earliest ||
|
||||
listener->getCreationDate() > mFilterOps.mMaxDate)
|
||||
{
|
||||
LL_INFOS() << "FILTERTYPE_DATE type" << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -231,7 +278,10 @@ BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) con
|
||||
LLWearableType::EType type = listener->getWearableType();
|
||||
if ((0x1LL << type & mFilterOps.mFilterWearableTypes) == 0)
|
||||
{
|
||||
return FALSE;
|
||||
{
|
||||
LL_INFOS() << "FILTERTYPE_WEARABLE type" << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,6 +308,7 @@ BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) con
|
||||
}
|
||||
if (descendents_actual == 0)
|
||||
{
|
||||
LL_INFOS() << "FILTERTYPE_EMPTYFOLDERS type" << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@@ -291,7 +342,7 @@ bool LLInventoryFilter::checkAgainstClipboard(const LLUUID& object_id) const
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOL LLInventoryFilter::checkAgainstPermissions(const LLFolderViewItem* item) const
|
||||
bool LLInventoryFilter::checkAgainstPermissions(const LLFolderViewItem* item) const
|
||||
{
|
||||
const LLFolderViewEventListener* listener = item->getListener();
|
||||
if (!listener) return FALSE;
|
||||
@@ -308,7 +359,7 @@ BOOL LLInventoryFilter::checkAgainstPermissions(const LLFolderViewItem* item) co
|
||||
return (perm & mFilterOps.mPermissions) == mFilterOps.mPermissions;
|
||||
}
|
||||
|
||||
BOOL LLInventoryFilter::checkAgainstFilterLinks(const LLFolderViewItem* item) const
|
||||
bool LLInventoryFilter::checkAgainstFilterLinks(const LLFolderViewItem* item) const
|
||||
{
|
||||
const LLFolderViewEventListener* listener = item->getListener();
|
||||
if (!listener) return TRUE;
|
||||
@@ -336,16 +387,16 @@ std::string::size_type LLInventoryFilter::getStringMatchOffset() const
|
||||
}
|
||||
|
||||
// has user modified default filter params?
|
||||
BOOL LLInventoryFilter::isNotDefault() const
|
||||
bool LLInventoryFilter::isNotDefault() const
|
||||
{
|
||||
BOOL not_default = FALSE;
|
||||
bool not_default = false;
|
||||
|
||||
not_default |= (mFilterOps.mFilterObjectTypes != mDefaultFilterOps.mFilterObjectTypes);
|
||||
not_default |= (mFilterOps.mFilterCategoryTypes != mDefaultFilterOps.mFilterCategoryTypes);
|
||||
not_default |= (mFilterOps.mFilterWearableTypes != mDefaultFilterOps.mFilterWearableTypes);
|
||||
not_default |= (mFilterOps.mFilterTypes != mDefaultFilterOps.mFilterTypes);
|
||||
not_default |= (mFilterOps.mFilterLinks != mDefaultFilterOps.mFilterLinks);
|
||||
not_default |= (mFilterSubString.size());
|
||||
not_default |= (mFilterSubString.size() > 0);
|
||||
not_default |= (mFilterOps.mFilterWorn != mDefaultFilterOps.mFilterWorn);
|
||||
not_default |= (mFilterOps.mPermissions != mDefaultFilterOps.mPermissions);
|
||||
not_default |= (mFilterOps.mMinDate != mDefaultFilterOps.mMinDate);
|
||||
@@ -355,7 +406,7 @@ BOOL LLInventoryFilter::isNotDefault() const
|
||||
return not_default;
|
||||
}
|
||||
|
||||
BOOL LLInventoryFilter::isActive() const
|
||||
bool LLInventoryFilter::isActive() const
|
||||
{
|
||||
return mFilterOps.mFilterObjectTypes != 0xffffffffffffffffULL
|
||||
|| mFilterOps.mFilterCategoryTypes != 0xffffffffffffffffULL
|
||||
@@ -370,16 +421,9 @@ BOOL LLInventoryFilter::isActive() const
|
||||
|| mFilterOps.mHoursAgo != 0;
|
||||
}
|
||||
|
||||
BOOL LLInventoryFilter::isModified() const
|
||||
bool LLInventoryFilter::isModified() const
|
||||
{
|
||||
return mModified;
|
||||
}
|
||||
|
||||
BOOL LLInventoryFilter::isModifiedAndClear()
|
||||
{
|
||||
BOOL ret = mModified;
|
||||
mModified = FALSE;
|
||||
return ret;
|
||||
return mFilterModified != FILTER_NONE;
|
||||
}
|
||||
|
||||
void LLInventoryFilter::updateFilterTypes(U64 types, U64& current_types)
|
||||
@@ -411,29 +455,39 @@ void LLInventoryFilter::updateFilterTypes(U64 types, U64& current_types)
|
||||
|
||||
void LLInventoryFilter::setFilterObjectTypes(U64 types)
|
||||
{
|
||||
if (types == mFilterOps.mFilterObjectTypes && mFilterOps.mFilterTypes & FILTERTYPE_OBJECT)
|
||||
return;
|
||||
updateFilterTypes(types, mFilterOps.mFilterObjectTypes);
|
||||
LL_INFOS() << "setFilterObjectTypes" << LL_ENDL;
|
||||
mFilterOps.mFilterTypes |= FILTERTYPE_OBJECT;
|
||||
}
|
||||
|
||||
void LLInventoryFilter::setFilterCategoryTypes(U64 types)
|
||||
{
|
||||
updateFilterTypes(types, mFilterOps.mFilterCategoryTypes);
|
||||
LL_INFOS() << "setFilterCategoryTypes" << LL_ENDL;
|
||||
mFilterOps.mFilterTypes |= FILTERTYPE_CATEGORY;
|
||||
}
|
||||
|
||||
void LLInventoryFilter::setFilterWearableTypes(U64 types)
|
||||
{
|
||||
updateFilterTypes(types, mFilterOps.mFilterWearableTypes);
|
||||
LL_INFOS() << "setFilterWearableTypes" << LL_ENDL;
|
||||
mFilterOps.mFilterTypes |= FILTERTYPE_WEARABLE;
|
||||
}
|
||||
|
||||
void LLInventoryFilter::setFilterEmptySystemFolders()
|
||||
{
|
||||
LL_INFOS() << "setFilterEmptySystemFolders" << LL_ENDL;
|
||||
mFilterOps.mFilterTypes |= FILTERTYPE_EMPTYFOLDERS;
|
||||
}
|
||||
|
||||
void LLInventoryFilter::setFilterUUID(const LLUUID& object_id)
|
||||
{
|
||||
if (mFilterOps.mFilterUUID == object_id)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (mFilterOps.mFilterUUID == LLUUID::null)
|
||||
{
|
||||
setModified(FILTER_MORE_RESTRICTIVE);
|
||||
@@ -443,7 +497,10 @@ void LLInventoryFilter::setFilterUUID(const LLUUID& object_id)
|
||||
setModified(FILTER_RESTART);
|
||||
}
|
||||
mFilterOps.mFilterUUID = object_id;
|
||||
mFilterOps.mFilterTypes = FILTERTYPE_UUID;
|
||||
if(object_id.isNull())
|
||||
mFilterOps.mFilterTypes &= ~FILTERTYPE_UUID;
|
||||
else
|
||||
mFilterOps.mFilterTypes |= FILTERTYPE_UUID;
|
||||
}
|
||||
|
||||
void LLInventoryFilter::setFilterSubString(const std::string& string)
|
||||
@@ -478,18 +535,12 @@ void LLInventoryFilter::setFilterSubString(const std::string& string)
|
||||
}
|
||||
|
||||
// Cancel out UUID once the search string is modified
|
||||
if (mFilterOps.mFilterTypes == FILTERTYPE_UUID)
|
||||
if (mFilterOps.mFilterTypes & FILTERTYPE_UUID)
|
||||
{
|
||||
mFilterOps.mFilterTypes &= ~FILTERTYPE_UUID;
|
||||
//mFilterOps.mFilterUUID == LLUUID::null;
|
||||
mFilterOps.mFilterUUID == LLUUID::null;
|
||||
setModified(FILTER_RESTART);
|
||||
}
|
||||
|
||||
// Cancel out filter links once the search string is modified
|
||||
// Singu Note: No, don't do this...
|
||||
{
|
||||
//mFilterOps.mFilterLinks = FILTERLINK_INCLUDE_LINKS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -531,39 +582,53 @@ void LLInventoryFilter::setDateRange(time_t min_date, time_t max_date)
|
||||
mFilterOps.mMaxDate = llmax(mFilterOps.mMinDate, max_date);
|
||||
setModified();
|
||||
}
|
||||
mFilterOps.mFilterTypes |= FILTERTYPE_DATE;
|
||||
|
||||
if (areDateLimitsSet())
|
||||
{
|
||||
mFilterOps.mFilterTypes |= FILTERTYPE_DATE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mFilterOps.mFilterTypes &= ~FILTERTYPE_DATE;
|
||||
}
|
||||
}
|
||||
|
||||
void LLInventoryFilter::setDateRangeLastLogoff(BOOL sl)
|
||||
{
|
||||
static LLCachedControl<U32> s_last_logoff(gSavedPerAccountSettings, "LastLogoff", 0);
|
||||
if (sl && !isSinceLogoff())
|
||||
{
|
||||
setDateRange(mLastLogoff, time_max());
|
||||
setDateRange(s_last_logoff, time_max());
|
||||
setModified();
|
||||
}
|
||||
if (!sl && isSinceLogoff())
|
||||
{
|
||||
setDateRange(0, time_max());
|
||||
setDateRange(time_min(), time_max());
|
||||
setModified();
|
||||
}
|
||||
mFilterOps.mFilterTypes |= FILTERTYPE_DATE;
|
||||
|
||||
if (areDateLimitsSet())
|
||||
{
|
||||
mFilterOps.mFilterTypes |= FILTERTYPE_DATE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mFilterOps.mFilterTypes &= ~FILTERTYPE_DATE;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLInventoryFilter::isSinceLogoff() const
|
||||
bool LLInventoryFilter::isSinceLogoff() const
|
||||
{
|
||||
bool min_date = (mFilterOps.mMinDate == (time_t)mLastLogoff);
|
||||
static LLCachedControl<U32> s_last_logoff(gSavedSettings, "LastLogoff", 0);
|
||||
bool min_date = (mFilterOps.mMinDate == (time_t)s_last_logoff);
|
||||
bool max_date = (mFilterOps.mMaxDate == time_max());
|
||||
bool is_filter = (mFilterOps.mFilterTypes & FILTERTYPE_DATE);
|
||||
return min_date && max_date && is_filter;
|
||||
//return (mFilterOps.mMinDate == (time_t)mLastLogoff) &&
|
||||
// (mFilterOps.mMaxDate == time_max()) &&
|
||||
// (mFilterOps.mFilterTypes & FILTERTYPE_DATE);
|
||||
}
|
||||
|
||||
void LLInventoryFilter::clearModified()
|
||||
{
|
||||
mModified = FALSE;
|
||||
mFilterBehavior = FILTER_NONE;
|
||||
mFilterModified = FILTER_NONE;
|
||||
}
|
||||
|
||||
void LLInventoryFilter::setHoursAgo(U32 hours)
|
||||
@@ -573,7 +638,7 @@ void LLInventoryFilter::setHoursAgo(U32 hours)
|
||||
bool are_date_limits_valid = mFilterOps.mMinDate == time_min() && mFilterOps.mMaxDate == time_max();
|
||||
|
||||
bool is_increasing = hours > mFilterOps.mHoursAgo;
|
||||
bool is_increasing_from_zero = is_increasing && !mFilterOps.mHoursAgo;
|
||||
bool is_increasing_from_zero = is_increasing && !mFilterOps.mHoursAgo && !isSinceLogoff();
|
||||
|
||||
// *NOTE: need to cache last filter time, in case filter goes stale
|
||||
BOOL less_restrictive = ((are_date_limits_valid && ((is_increasing && mFilterOps.mHoursAgo))) || !hours);
|
||||
@@ -595,9 +660,18 @@ void LLInventoryFilter::setHoursAgo(U32 hours)
|
||||
setModified(FILTER_RESTART);
|
||||
}
|
||||
}
|
||||
mFilterOps.mFilterTypes |= FILTERTYPE_DATE;
|
||||
|
||||
if (areDateLimitsSet())
|
||||
{
|
||||
mFilterOps.mFilterTypes |= FILTERTYPE_DATE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mFilterOps.mFilterTypes &= ~FILTERTYPE_DATE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLInventoryFilter::setFilterLinks(U64 filter_links)
|
||||
{
|
||||
if (mFilterOps.mFilterLinks != filter_links)
|
||||
@@ -653,83 +727,68 @@ void LLInventoryFilter::resetDefault()
|
||||
setModified();
|
||||
}
|
||||
|
||||
void LLInventoryFilter::setModified(EFilterBehavior behavior)
|
||||
void LLInventoryFilter::setModified(EFilterModified behavior)
|
||||
{
|
||||
mModified = TRUE;
|
||||
mNeedTextRebuild = TRUE;
|
||||
mFilterGeneration = mNextFilterGeneration++;
|
||||
mFilterText.clear();
|
||||
mCurrentGeneration++;
|
||||
|
||||
if (mFilterBehavior == FILTER_NONE)
|
||||
if (mFilterModified == FILTER_NONE)
|
||||
{
|
||||
mFilterBehavior = behavior;
|
||||
mFilterModified = behavior;
|
||||
}
|
||||
else if (mFilterBehavior != behavior)
|
||||
else if (mFilterModified != behavior)
|
||||
{
|
||||
// trying to do both less restrictive and more restrictive filter
|
||||
// basically means restart from scratch
|
||||
mFilterBehavior = FILTER_RESTART;
|
||||
mFilterModified = FILTER_RESTART;
|
||||
}
|
||||
|
||||
if (isNotDefault())
|
||||
// if not keeping current filter results, update last valid as well
|
||||
switch(mFilterModified)
|
||||
{
|
||||
// if not keeping current filter results, update last valid as well
|
||||
switch(mFilterBehavior)
|
||||
{
|
||||
case FILTER_RESTART:
|
||||
mMustPassGeneration = mFilterGeneration;
|
||||
mMinRequiredGeneration = mFilterGeneration;
|
||||
break;
|
||||
case FILTER_LESS_RESTRICTIVE:
|
||||
mMustPassGeneration = mFilterGeneration;
|
||||
break;
|
||||
case FILTER_MORE_RESTRICTIVE:
|
||||
mMinRequiredGeneration = mFilterGeneration;
|
||||
// must have passed either current filter generation (meaningless, as it hasn't been run yet)
|
||||
// or some older generation, so keep the value
|
||||
mMustPassGeneration = llmin(mMustPassGeneration, mFilterGeneration);
|
||||
break;
|
||||
default:
|
||||
LL_ERRS() << "Bad filter behavior specified" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// shortcut disabled filters to show everything immediately
|
||||
mMinRequiredGeneration = 0;
|
||||
mMustPassGeneration = S32_MAX;
|
||||
case FILTER_RESTART:
|
||||
mFirstRequiredGeneration = mCurrentGeneration;
|
||||
mFirstSuccessGeneration = mCurrentGeneration;
|
||||
break;
|
||||
case FILTER_LESS_RESTRICTIVE:
|
||||
mFirstRequiredGeneration = mCurrentGeneration;
|
||||
break;
|
||||
case FILTER_MORE_RESTRICTIVE:
|
||||
mFirstSuccessGeneration = mCurrentGeneration;
|
||||
break;
|
||||
default:
|
||||
LL_ERRS() << "Bad filter behavior specified" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLInventoryFilter::isFilterObjectTypesWith(LLInventoryType::EType t) const
|
||||
bool LLInventoryFilter::isFilterObjectTypesWith(LLInventoryType::EType t) const
|
||||
{
|
||||
return mFilterOps.mFilterObjectTypes & (1LL << t);
|
||||
}
|
||||
|
||||
const std::string& LLInventoryFilter::getFilterText()
|
||||
{
|
||||
if (!mNeedTextRebuild)
|
||||
if (!mFilterText.empty())
|
||||
{
|
||||
return mFilterText;
|
||||
}
|
||||
|
||||
mNeedTextRebuild = FALSE;
|
||||
std::string filtered_types;
|
||||
std::string not_filtered_types;
|
||||
BOOL filtered_by_type = FALSE;
|
||||
BOOL filtered_by_all_types = TRUE;
|
||||
S32 num_filter_types = 0;
|
||||
|
||||
mFilterText.clear();
|
||||
|
||||
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;
|
||||
@@ -737,146 +796,126 @@ 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;
|
||||
}
|
||||
|
||||
if (!LLInventoryModelBackgroundFetch::instance().folderFetchActive()
|
||||
&& filtered_by_type
|
||||
if (!LLInventoryModelBackgroundFetch::instance().folderFetchActive()
|
||||
&& filtered_by_type
|
||||
&& !filtered_by_all_types)
|
||||
{
|
||||
mFilterText += " - ";
|
||||
@@ -886,7 +925,6 @@ const std::string& LLInventoryFilter::getFilterText()
|
||||
}
|
||||
else
|
||||
{
|
||||
//mFilterText += "No ";
|
||||
mFilterText += LLTrans::getString("No Filters");
|
||||
mFilterText += not_filtered_types;
|
||||
}
|
||||
@@ -896,13 +934,11 @@ const std::string& LLInventoryFilter::getFilterText()
|
||||
|
||||
if (isSinceLogoff())
|
||||
{
|
||||
//mFilterText += " - Since Logoff";
|
||||
mFilterText += LLTrans::getString("Since Logoff");
|
||||
}
|
||||
|
||||
if (getFilterWorn())
|
||||
{
|
||||
//mFilterText += " - Worn";
|
||||
mFilterText += LLTrans::getString("Worn");
|
||||
}
|
||||
|
||||
@@ -965,6 +1001,11 @@ void LLInventoryFilter::fromLLSD(LLSD& data)
|
||||
}
|
||||
}
|
||||
|
||||
U64 LLInventoryFilter::getFilterTypes() const
|
||||
{
|
||||
return mFilterOps.mFilterTypes;
|
||||
}
|
||||
|
||||
U64 LLInventoryFilter::getFilterObjectTypes() const
|
||||
{
|
||||
return mFilterOps.mFilterObjectTypes;
|
||||
@@ -975,11 +1016,21 @@ U64 LLInventoryFilter::getFilterCategoryTypes() const
|
||||
return mFilterOps.mFilterCategoryTypes;
|
||||
}
|
||||
|
||||
BOOL LLInventoryFilter::hasFilterString() const
|
||||
U64 LLInventoryFilter::getFilterWearableTypes() const
|
||||
{
|
||||
return mFilterOps.mFilterWearableTypes;
|
||||
}
|
||||
|
||||
bool LLInventoryFilter::hasFilterString() const
|
||||
{
|
||||
return mFilterSubString.size() > 0;
|
||||
}
|
||||
|
||||
std::string::size_type LLInventoryFilter::getFilterStringSize() const
|
||||
{
|
||||
return mFilterSubString.size();
|
||||
}
|
||||
|
||||
PermissionMask LLInventoryFilter::getFilterPermissions() const
|
||||
{
|
||||
return mFilterOps.mPermissions;
|
||||
@@ -1010,10 +1061,6 @@ U32 LLInventoryFilter::getSortOrder() const
|
||||
{
|
||||
return mOrder;
|
||||
}
|
||||
const std::string& LLInventoryFilter::getName() const
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
|
||||
void LLInventoryFilter::setFilterCount(S32 count)
|
||||
{
|
||||
@@ -1031,13 +1078,26 @@ void LLInventoryFilter::decrementFilterCount()
|
||||
|
||||
S32 LLInventoryFilter::getCurrentGeneration() const
|
||||
{
|
||||
return mFilterGeneration;
|
||||
return mCurrentGeneration;
|
||||
}
|
||||
S32 LLInventoryFilter::getMinRequiredGeneration() const
|
||||
S32 LLInventoryFilter::getFirstSuccessGeneration() const
|
||||
{
|
||||
return mMinRequiredGeneration;
|
||||
return mFirstSuccessGeneration;
|
||||
}
|
||||
S32 LLInventoryFilter::getMustPassGeneration() const
|
||||
S32 LLInventoryFilter::getFirstRequiredGeneration() const
|
||||
{
|
||||
return mMustPassGeneration;
|
||||
return mFirstRequiredGeneration;
|
||||
}
|
||||
|
||||
bool LLInventoryFilter::areDateLimitsSet()
|
||||
{
|
||||
return mFilterOps.mMinDate != time_min()
|
||||
|| mFilterOps.mMaxDate != time_max()
|
||||
|| mFilterOps.mHoursAgo != 0;
|
||||
}
|
||||
|
||||
bool LLInventoryFilter::showAllResults() const
|
||||
{
|
||||
return hasFilterString();
|
||||
}
|
||||
|
||||
|
||||
@@ -36,20 +36,20 @@ class LLFolderViewFolder;
|
||||
class LLInventoryFilter
|
||||
{
|
||||
public:
|
||||
enum EFolderShow
|
||||
{
|
||||
SHOW_ALL_FOLDERS,
|
||||
SHOW_NON_EMPTY_FOLDERS,
|
||||
SHOW_NO_FOLDERS
|
||||
};
|
||||
|
||||
enum EFilterBehavior
|
||||
enum EFilterModified
|
||||
{
|
||||
FILTER_NONE, // nothing to do, already filtered
|
||||
FILTER_RESTART, // restart filtering from scratch
|
||||
FILTER_LESS_RESTRICTIVE, // existing filtered items will certainly pass this filter
|
||||
FILTER_MORE_RESTRICTIVE // if you didn't pass the previous filter, you definitely won't pass this one
|
||||
};
|
||||
|
||||
enum EFolderShow
|
||||
{
|
||||
SHOW_ALL_FOLDERS,
|
||||
SHOW_NON_EMPTY_FOLDERS,
|
||||
SHOW_NO_FOLDERS
|
||||
};
|
||||
|
||||
enum EFilterType {
|
||||
FILTERTYPE_NONE = 0,
|
||||
@@ -76,16 +76,37 @@ public:
|
||||
SO_SYSTEM_FOLDERS_TO_TOP = 0x1 << 2 // Force system folders to be on top
|
||||
};
|
||||
|
||||
struct FilterOps
|
||||
{
|
||||
FilterOps();
|
||||
U32 mFilterTypes;
|
||||
U64 mFilterObjectTypes, // For _OBJECT
|
||||
mFilterWearableTypes,
|
||||
mFilterLinks,
|
||||
mFilterCategoryTypes; // For _CATEGORY
|
||||
LLUUID mFilterUUID; // for UUID
|
||||
|
||||
time_t mMinDate,
|
||||
mMaxDate;
|
||||
U32 mHoursAgo;
|
||||
EFolderShow mShowFolderState;
|
||||
PermissionMask mPermissions;
|
||||
|
||||
bool mFilterWorn;
|
||||
};
|
||||
|
||||
LLInventoryFilter(const std::string& name);
|
||||
virtual ~LLInventoryFilter();
|
||||
|
||||
// +-------------------------------------------------------------------+
|
||||
// + Parameters
|
||||
// +-------------------------------------------------------------------+
|
||||
void setFilterObjectTypes(U64 types);
|
||||
U64 getFilterTypes() const;
|
||||
U64 getFilterObjectTypes() const;
|
||||
U64 getFilterCategoryTypes() const;
|
||||
BOOL isFilterObjectTypesWith(LLInventoryType::EType t) const;
|
||||
U64 getFilterWearableTypes() const;
|
||||
bool isFilterObjectTypesWith(LLInventoryType::EType t) const;
|
||||
void setFilterObjectTypes(U64 types);
|
||||
void setFilterCategoryTypes(U64 types);
|
||||
void setFilterUUID(const LLUUID &object_id);
|
||||
void setFilterWearableTypes(U64 types);
|
||||
@@ -95,7 +116,7 @@ public:
|
||||
void setFilterSubString(const std::string& string);
|
||||
const std::string& getFilterSubString(BOOL trim = FALSE) const;
|
||||
const std::string& getFilterSubStringOrig() const { return mFilterSubStringOrig; }
|
||||
BOOL hasFilterString() const;
|
||||
bool hasFilterString() const;
|
||||
|
||||
void setFilterWorn(bool worn) { mFilterOps.mFilterWorn = worn; }
|
||||
bool getFilterWorn() const { return mFilterOps.mFilterWorn; }
|
||||
@@ -117,15 +138,14 @@ public:
|
||||
// +-------------------------------------------------------------------+
|
||||
// + Execution And Results
|
||||
// +-------------------------------------------------------------------+
|
||||
BOOL check(LLFolderViewItem* item);
|
||||
bool check(LLFolderViewItem* item);
|
||||
bool checkFolder(const LLFolderViewFolder* folder) const;
|
||||
BOOL checkAgainstFilterType(const LLFolderViewItem* item) const;
|
||||
BOOL checkAgainstPermissions(const LLFolderViewItem* item) const;
|
||||
BOOL checkAgainstFilterLinks(const LLFolderViewItem* item) const;
|
||||
bool checkAgainstClipboard(const LLUUID& object_id) const;
|
||||
bool checkFolder(const LLUUID& folder_id) const;
|
||||
|
||||
bool showAllResults() const;
|
||||
|
||||
std::string::size_type getStringMatchOffset() const;
|
||||
|
||||
std::string::size_type getFilterStringSize() const;
|
||||
// +-------------------------------------------------------------------+
|
||||
// + Presentation
|
||||
// +-------------------------------------------------------------------+
|
||||
@@ -135,21 +155,18 @@ public:
|
||||
void setSortOrder(U32 order);
|
||||
U32 getSortOrder() const;
|
||||
|
||||
|
||||
|
||||
// +-------------------------------------------------------------------+
|
||||
// + Status
|
||||
// +-------------------------------------------------------------------+
|
||||
BOOL isActive() const;
|
||||
bool isActive() const;
|
||||
|
||||
BOOL isModified() const;
|
||||
BOOL isModifiedAndClear();
|
||||
BOOL isSinceLogoff() const;
|
||||
bool isModified() const;
|
||||
bool isSinceLogoff() const;
|
||||
void clearModified();
|
||||
const std::string& getName() const;
|
||||
const std::string& getName() const { return mName; }
|
||||
const std::string& getFilterText();
|
||||
//RN: this is public to allow system to externally force a global refilter
|
||||
void setModified(EFilterBehavior behavior = FILTER_RESTART);
|
||||
void setModified(EFilterModified behavior = FILTER_RESTART);
|
||||
|
||||
// +-------------------------------------------------------------------+
|
||||
// + Count
|
||||
@@ -161,7 +178,7 @@ public:
|
||||
// +-------------------------------------------------------------------+
|
||||
// + Default
|
||||
// +-------------------------------------------------------------------+
|
||||
BOOL isNotDefault() const;
|
||||
bool isNotDefault() const;
|
||||
void markDefault();
|
||||
void resetDefault();
|
||||
|
||||
@@ -169,8 +186,8 @@ public:
|
||||
// + Generation
|
||||
// +-------------------------------------------------------------------+
|
||||
S32 getCurrentGeneration() const;
|
||||
S32 getMinRequiredGeneration() const;
|
||||
S32 getMustPassGeneration() const;
|
||||
S32 getFirstSuccessGeneration() const;
|
||||
S32 getFirstRequiredGeneration() const;
|
||||
|
||||
// +-------------------------------------------------------------------+
|
||||
// + Conversion
|
||||
@@ -179,27 +196,13 @@ public:
|
||||
void fromLLSD(LLSD& data);
|
||||
|
||||
private:
|
||||
struct FilterOps
|
||||
{
|
||||
FilterOps();
|
||||
U32 mFilterTypes;
|
||||
|
||||
U64 mFilterObjectTypes; // For _OBJECT
|
||||
U64 mFilterWearableTypes;
|
||||
U64 mFilterCategoryTypes; // For _CATEGORY
|
||||
LLUUID mFilterUUID; // for UUID
|
||||
|
||||
time_t mMinDate;
|
||||
time_t mMaxDate;
|
||||
U32 mHoursAgo;
|
||||
EFolderShow mShowFolderState;
|
||||
PermissionMask mPermissions;
|
||||
U64 mFilterLinks;
|
||||
bool mFilterWorn;
|
||||
};
|
||||
bool areDateLimitsSet();
|
||||
bool checkAgainstFilterType(const LLFolderViewItem* item) const;
|
||||
bool checkAgainstPermissions(const LLFolderViewItem* item) const;
|
||||
bool checkAgainstFilterLinks(const LLFolderViewItem* item) const;
|
||||
bool checkAgainstClipboard(const LLUUID& object_id) const;
|
||||
|
||||
U32 mOrder;
|
||||
U32 mLastLogoff;
|
||||
|
||||
FilterOps mFilterOps;
|
||||
FilterOps mDefaultFilterOps;
|
||||
@@ -209,16 +212,16 @@ private:
|
||||
std::string mFilterSubStringOrig;
|
||||
const std::string mName;
|
||||
|
||||
S32 mFilterGeneration;
|
||||
S32 mMustPassGeneration;
|
||||
S32 mMinRequiredGeneration;
|
||||
S32 mNextFilterGeneration;
|
||||
S32 mCurrentGeneration;
|
||||
// The following makes checking for pass/no pass possible even if the item is not checked against the current generation
|
||||
// Any item that *did not pass* the "required generation" will *not pass* the current one
|
||||
// Any item that *passes* the "success generation" will *pass* the current one
|
||||
S32 mFirstRequiredGeneration;
|
||||
S32 mFirstSuccessGeneration;
|
||||
|
||||
S32 mFilterCount;
|
||||
EFilterBehavior mFilterBehavior;
|
||||
EFilterModified mFilterModified;
|
||||
|
||||
BOOL mModified;
|
||||
BOOL mNeedTextRebuild;
|
||||
std::string mFilterText;
|
||||
};
|
||||
|
||||
|
||||
@@ -3213,7 +3213,7 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**)
|
||||
gInventoryCallbacks.fire(cbinfo.mCallback, cbinfo.mInvID);
|
||||
}
|
||||
// Don't show the inventory. We used to call showAgentInventory here.
|
||||
//LLInventoryView* view = LLInventoryView::getActiveInventory();
|
||||
//LLPanelMainInventory* view = LLPanelMainInventory::getActiveInventory();
|
||||
//if(view)
|
||||
//{
|
||||
// const BOOL take_keyboard_focus = FALSE;
|
||||
@@ -3223,10 +3223,10 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**)
|
||||
// // HACK to open inventory offers that are accepted. This information
|
||||
// // really needs to flow through the instant messages and inventory
|
||||
// // transfer/update messages.
|
||||
// if (LLInventoryView::sOpenNextNewItem)
|
||||
// if (LLPanelMainInventory::sOpenNextNewItem)
|
||||
// {
|
||||
// view->openSelected();
|
||||
// LLInventoryView::sOpenNextNewItem = FALSE;
|
||||
// LLPanelMainInventory::sOpenNextNewItem = FALSE;
|
||||
// }
|
||||
//
|
||||
// // restore keyboard focus
|
||||
|
||||
@@ -404,7 +404,38 @@ void LLInventoryPanel::setFilterWorn(bool worn)
|
||||
|
||||
void LLInventoryPanel::setFilterSubString(const std::string& string)
|
||||
{
|
||||
getFilter()->setFilterSubString(string);
|
||||
if (!getRootFolder())
|
||||
return;
|
||||
|
||||
std::string uppercase_search_string = string;
|
||||
LLStringUtil::toUpper(uppercase_search_string);
|
||||
const std::string prior_search_string = getFilterSubString();
|
||||
|
||||
if (prior_search_string == uppercase_search_string)
|
||||
{
|
||||
// current filter and new filter match, do nothing
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.empty())
|
||||
{
|
||||
// Unlike v3, do not clear other filters. Text is independent.
|
||||
getFilter()->setFilterSubString(LLStringUtil::null);
|
||||
getRootFolder()->restoreFolderState();
|
||||
LLOpenFoldersWithSelection opener;
|
||||
getRootFolder()->applyFunctorRecursively(opener);
|
||||
getRootFolder()->scrollToShowSelection();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (prior_search_string.empty())
|
||||
{
|
||||
// save current folder open state if no filter currently applied
|
||||
getRootFolder()->saveFolderState();
|
||||
}
|
||||
// set new filter string
|
||||
getFilter()->setFilterSubString(string);
|
||||
}
|
||||
}
|
||||
|
||||
const std::string LLInventoryPanel::getFilterSubString()
|
||||
@@ -412,7 +443,6 @@ const std::string LLInventoryPanel::getFilterSubString()
|
||||
return mFolderRoot.get()->getFilterSubString();
|
||||
}
|
||||
|
||||
|
||||
void LLInventoryPanel::setSortOrder(U32 order)
|
||||
{
|
||||
getFilter()->setSortOrder(order);
|
||||
@@ -1081,7 +1111,7 @@ void LLInventoryPanel::dumpSelectionInformation(void* user_data)
|
||||
LLInventoryPanel* LLInventoryPanel::getActiveInventoryPanel(BOOL auto_open)
|
||||
{
|
||||
LLInventoryPanel* res = NULL;
|
||||
LLInventoryView* floater_inventory = LLInventoryView::getActiveInventory();
|
||||
LLPanelMainInventory* floater_inventory = LLPanelMainInventory::getActiveInventory();
|
||||
if (!floater_inventory)
|
||||
{
|
||||
LL_WARNS() << "Could not find My Inventory floater" << LL_ENDL;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @file llinventoryview.h
|
||||
* @brief LLInventoryView, LLInventoryFolder, and LLInventoryItem
|
||||
* @file llpanelmaininventory.h
|
||||
* @brief LLPanelMainInventory, LLInventoryFolder, and LLInventoryItem
|
||||
* class definition
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
@@ -222,7 +222,7 @@ protected:
|
||||
BOOL mViewsInitialized; // Views have been generated
|
||||
};
|
||||
|
||||
class LLInventoryView;
|
||||
class LLPanelMainInventory;
|
||||
|
||||
|
||||
|
||||
@@ -234,7 +234,7 @@ class LLInventoryView;
|
||||
// useful functions with the inventory view
|
||||
// *FIX: move these methods.
|
||||
|
||||
void init_inventory_actions(LLInventoryView *floater);
|
||||
void init_inventory_actions(LLPanelMainInventory *floater);
|
||||
void init_inventory_panel_actions(LLInventoryPanel *panel);
|
||||
|
||||
class LLInventoryCategory;
|
||||
|
||||
@@ -185,7 +185,7 @@ struct MenuFloaterDict : public LLSingleton<MenuFloaterDict>
|
||||
//Singu TODO: Re-implement f1 help.
|
||||
//registerFloater("help f1", boost::bind(/*gViewerHtmlHelp.show*/));
|
||||
registerFloater("help tutorial", boost::bind(LLFloaterHUD::showHUD));
|
||||
registerFloater("inventory", boost::bind(LLInventoryView::toggleVisibility, (void*)NULL), boost::bind(is_visible_view, static_cast<boost::function<LLView* ()> >(LLInventoryView::getActiveInventory)));
|
||||
registerFloater("inventory", boost::bind(LLPanelMainInventory::toggleVisibility, (void*)NULL), boost::bind(is_visible_view, static_cast<boost::function<LLView* ()> >(LLPanelMainInventory::getActiveInventory)));
|
||||
registerFloater("local assets", boost::bind(FloaterLocalAssetBrowser::show, (void*)0));
|
||||
registerFloater("mean events", boost::bind(LLFloaterBump::show, (void*)NULL));
|
||||
registerFloater("media ticker", boost::bind(handle_ticker_toggle, (void*)NULL), boost::bind(SHFloaterMediaTicker::instanceExists));
|
||||
|
||||
@@ -2557,6 +2557,8 @@ void LLMeshRepository::notifyLoadedMeshes()
|
||||
|
||||
S32 push_count = LLMeshRepoThread::sMaxConcurrentRequests-(LLMeshRepoThread::sActiveHeaderRequests+LLMeshRepoThread::sActiveLODRequests);
|
||||
|
||||
push_count = llmin(push_count, (S32)mPendingRequests.size());
|
||||
|
||||
if (push_count > 0)
|
||||
{
|
||||
//calculate "score" for pending requests
|
||||
|
||||
@@ -51,19 +51,19 @@
|
||||
|
||||
const std::string FILTERS_FILENAME("filters.xml");
|
||||
|
||||
std::vector<LLInventoryView*> LLInventoryView::sActiveViews;
|
||||
std::vector<LLPanelMainInventory*> LLPanelMainInventory::sActiveViews;
|
||||
const S32 INV_MIN_WIDTH = 240;
|
||||
const S32 INV_MIN_HEIGHT = 150;
|
||||
const S32 INV_FINDER_WIDTH = 160;
|
||||
const S32 INV_FINDER_HEIGHT = 408;
|
||||
|
||||
//BOOL LLInventoryView::sOpenNextNewItem = FALSE;
|
||||
//BOOL LLPanelMainInventory::sOpenNextNewItem = FALSE;
|
||||
class LLFloaterInventoryFinder : public LLFloater
|
||||
{
|
||||
public:
|
||||
LLFloaterInventoryFinder(const std::string& name,
|
||||
const LLRect& rect,
|
||||
LLInventoryView* inventory_view);
|
||||
LLPanelMainInventory* inventory_view);
|
||||
virtual void draw();
|
||||
/*virtual*/ BOOL postBuild();
|
||||
virtual void onClose(bool app_quitting);
|
||||
@@ -78,7 +78,7 @@ public:
|
||||
static void selectNoTypes(void* user_data);
|
||||
|
||||
protected:
|
||||
LLInventoryView* mInventoryView;
|
||||
LLPanelMainInventory* mPanelMainInventory;
|
||||
LLSpinCtrl* mSpinSinceDays;
|
||||
LLSpinCtrl* mSpinSinceHours;
|
||||
LLInventoryFilter* mFilter;
|
||||
@@ -86,10 +86,10 @@ protected:
|
||||
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// LLInventoryView
|
||||
/// LLPanelMainInventory
|
||||
///----------------------------------------------------------------------------
|
||||
// Default constructor
|
||||
LLInventoryView::LLInventoryView(const std::string& name,
|
||||
LLPanelMainInventory::LLPanelMainInventory(const std::string& name,
|
||||
const std::string& rect,
|
||||
LLInventoryModel* inventory) :
|
||||
LLFloater(name, rect, std::string("Inventory"), RESIZE_YES,
|
||||
@@ -99,14 +99,13 @@ LLInventoryView::LLInventoryView(const std::string& name,
|
||||
mFilterTabs(nullptr),
|
||||
mActivePanel(nullptr),
|
||||
mResortActivePanel(true),
|
||||
mSavedFolderState(nullptr),
|
||||
mFilterText("")
|
||||
//LLHandle<LLFloater> mFinderHandle takes care of its own initialization
|
||||
{
|
||||
init(inventory);
|
||||
}
|
||||
|
||||
LLInventoryView::LLInventoryView(const std::string& name,
|
||||
LLPanelMainInventory::LLPanelMainInventory(const std::string& name,
|
||||
const LLRect& rect,
|
||||
LLInventoryModel* inventory) :
|
||||
LLFloater(name, rect, std::string("Inventory"), RESIZE_YES,
|
||||
@@ -116,7 +115,6 @@ LLInventoryView::LLInventoryView(const std::string& name,
|
||||
mFilterTabs(nullptr),
|
||||
mActivePanel(nullptr),
|
||||
mResortActivePanel(true),
|
||||
mSavedFolderState(nullptr),
|
||||
mFilterText("")
|
||||
//LLHandle<LLFloater> mFinderHandle takes care of its own initialization
|
||||
{
|
||||
@@ -125,7 +123,7 @@ LLInventoryView::LLInventoryView(const std::string& name,
|
||||
}
|
||||
|
||||
|
||||
void LLInventoryView::init(LLInventoryModel* inventory)
|
||||
void LLPanelMainInventory::init(LLInventoryModel* inventory)
|
||||
{
|
||||
// Callbacks
|
||||
init_inventory_actions(this);
|
||||
@@ -142,13 +140,10 @@ void LLInventoryView::init(LLInventoryModel* inventory)
|
||||
addBoolControl("Inventory.SearchDesc", FALSE);
|
||||
addBoolControl("Inventory.SearchCreator", FALSE);
|
||||
|
||||
mSavedFolderState = new LLSaveFolderState();
|
||||
mSavedFolderState->setApply(FALSE);
|
||||
|
||||
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_inventory.xml", NULL);
|
||||
}
|
||||
|
||||
BOOL LLInventoryView::postBuild()
|
||||
BOOL LLPanelMainInventory::postBuild()
|
||||
{
|
||||
gInventory.addObserver(this);
|
||||
|
||||
@@ -161,8 +156,7 @@ BOOL LLInventoryView::postBuild()
|
||||
// "All Items" is the previous only view, so it gets the InventorySortOrder
|
||||
mActivePanel->setSortOrder(gSavedSettings.getU32(LLInventoryPanel::DEFAULT_SORT_ORDER));
|
||||
mActivePanel->getFilter()->markDefault();
|
||||
mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
|
||||
mActivePanel->setSelectCallback(boost::bind(&LLInventoryView::onSelectionChange, this, mActivePanel, _1, _2));
|
||||
mActivePanel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, mActivePanel, _1, _2));
|
||||
mResortActivePanel = true;
|
||||
}
|
||||
LLInventoryPanel* recent_items_panel = getChild<LLInventoryPanel>("Recent Items");
|
||||
@@ -172,7 +166,7 @@ BOOL LLInventoryView::postBuild()
|
||||
recent_items_panel->setSortOrder(gSavedSettings.getU32(LLInventoryPanel::RECENTITEMS_SORT_ORDER));
|
||||
recent_items_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
|
||||
recent_items_panel->getFilter()->markDefault();
|
||||
recent_items_panel->setSelectCallback(boost::bind(&LLInventoryView::onSelectionChange, this, recent_items_panel, _1, _2));
|
||||
recent_items_panel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, recent_items_panel, _1, _2));
|
||||
}
|
||||
LLInventoryPanel* worn_items_panel = getChild<LLInventoryPanel>("Worn Items");
|
||||
if (worn_items_panel)
|
||||
@@ -182,13 +176,13 @@ BOOL LLInventoryView::postBuild()
|
||||
worn_items_panel->getFilter()->markDefault();
|
||||
worn_items_panel->setFilterWorn(true);
|
||||
worn_items_panel->setFilterLinks(LLInventoryFilter::FILTERLINK_EXCLUDE_LINKS);
|
||||
worn_items_panel->setSelectCallback(boost::bind(&LLInventoryView::onSelectionChange, this, worn_items_panel, _1, _2));
|
||||
worn_items_panel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, worn_items_panel, _1, _2));
|
||||
}
|
||||
|
||||
// Now load the stored settings from disk, if available.
|
||||
std::ostringstream filterSaveName;
|
||||
filterSaveName << gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, FILTERS_FILENAME);
|
||||
LL_INFOS() << "LLInventoryView::init: reading from " << filterSaveName.str() << LL_ENDL;
|
||||
LL_INFOS() << "LLPanelMainInventory::init: reading from " << filterSaveName.str() << LL_ENDL;
|
||||
llifstream file(filterSaveName.str());
|
||||
LLSD savedFilterState;
|
||||
if (file.is_open())
|
||||
@@ -213,20 +207,20 @@ BOOL LLInventoryView::postBuild()
|
||||
mFilterEditor = getChild<LLFilterEditor>("inventory search editor");
|
||||
if (mFilterEditor)
|
||||
{
|
||||
mFilterEditor->setCommitCallback(boost::bind(&LLInventoryView::onFilterEdit, this, _2));
|
||||
mFilterEditor->setCommitCallback(boost::bind(&LLPanelMainInventory::onFilterEdit, this, _2));
|
||||
}
|
||||
|
||||
mQuickFilterCombo = getChild<LLComboBox>("Quick Filter");
|
||||
|
||||
if (mQuickFilterCombo)
|
||||
{
|
||||
mQuickFilterCombo->setCommitCallback(boost::bind(LLInventoryView::onQuickFilterCommit, _1, this));
|
||||
mQuickFilterCombo->setCommitCallback(boost::bind(LLPanelMainInventory::onQuickFilterCommit, _1, this));
|
||||
}
|
||||
|
||||
|
||||
sActiveViews.push_back(this);
|
||||
|
||||
getChild<LLTabContainer>("inventory filter tabs")->setCommitCallback(boost::bind(&LLInventoryView::onFilterSelected,this));
|
||||
getChild<LLTabContainer>("inventory filter tabs")->setCommitCallback(boost::bind(&LLPanelMainInventory::onFilterSelected,this));
|
||||
|
||||
childSetAction("Inventory.ResetAll",onResetAll,this);
|
||||
childSetAction("Inventory.ExpandAll",onExpandAll,this);
|
||||
@@ -235,7 +229,7 @@ BOOL LLInventoryView::postBuild()
|
||||
}
|
||||
|
||||
// Destroys the object
|
||||
LLInventoryView::~LLInventoryView( void )
|
||||
LLPanelMainInventory::~LLPanelMainInventory( void )
|
||||
{
|
||||
// Save the filters state.
|
||||
LLSD filterRoot;
|
||||
@@ -287,10 +281,9 @@ LLInventoryView::~LLInventoryView( void )
|
||||
|
||||
vector_replace_with_last(sActiveViews, this);
|
||||
gInventory.removeObserver(this);
|
||||
delete mSavedFolderState;
|
||||
}
|
||||
|
||||
void LLInventoryView::startSearch()
|
||||
void LLPanelMainInventory::startSearch()
|
||||
{
|
||||
// this forces focus to line editor portion of search editor
|
||||
if (mFilterEditor)
|
||||
@@ -300,18 +293,18 @@ void LLInventoryView::startSearch()
|
||||
}
|
||||
|
||||
// virtual, from LLView
|
||||
void LLInventoryView::setVisible( BOOL visible )
|
||||
void LLPanelMainInventory::setVisible( BOOL visible )
|
||||
{
|
||||
gSavedSettings.setBOOL("ShowInventory", visible);
|
||||
LLFloater::setVisible(visible);
|
||||
}
|
||||
|
||||
// Destroy all but the last floater, which is made invisible.
|
||||
void LLInventoryView::onClose(bool app_quitting)
|
||||
void LLPanelMainInventory::onClose(bool app_quitting)
|
||||
{
|
||||
// S32 count = sActiveViews.count();
|
||||
// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g)
|
||||
// See LLInventoryView::closeAll() on why we're doing it this way
|
||||
// See LLPanelMainInventory::closeAll() on why we're doing it this way
|
||||
S32 count = 0;
|
||||
for (S32 idx = 0, cnt = sActiveViews.size(); idx < cnt; idx++)
|
||||
{
|
||||
@@ -330,21 +323,13 @@ void LLInventoryView::onClose(bool app_quitting)
|
||||
{
|
||||
gSavedSettings.setBOOL("ShowInventory", FALSE);
|
||||
}
|
||||
// clear filters, but save user's folder state first
|
||||
if (!mActivePanel->getRootFolder()->isFilterModified())
|
||||
{
|
||||
mSavedFolderState->setApply(FALSE);
|
||||
mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
|
||||
}
|
||||
|
||||
// onClearSearch(this);
|
||||
|
||||
// pass up
|
||||
LLFloater::setVisible(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLInventoryView::handleKeyHere(KEY key, MASK mask)
|
||||
BOOL LLPanelMainInventory::handleKeyHere(KEY key, MASK mask)
|
||||
{
|
||||
LLFolderView* root_folder = mActivePanel ? mActivePanel->getRootFolder() : NULL;
|
||||
if (root_folder)
|
||||
@@ -376,7 +361,7 @@ BOOL LLInventoryView::handleKeyHere(KEY key, MASK mask)
|
||||
|
||||
// static
|
||||
// *TODO: remove take_keyboard_focus param
|
||||
LLInventoryView* LLInventoryView::showAgentInventory(BOOL take_keyboard_focus)
|
||||
LLPanelMainInventory* LLPanelMainInventory::showAgentInventory(BOOL take_keyboard_focus)
|
||||
{
|
||||
if (gDisconnected || gNoRender)
|
||||
{
|
||||
@@ -390,7 +375,7 @@ LLInventoryView* LLInventoryView::showAgentInventory(BOOL take_keyboard_focus)
|
||||
}
|
||||
// [/RLVa:KB]
|
||||
|
||||
LLInventoryView* iv = LLInventoryView::getActiveInventory();
|
||||
LLPanelMainInventory* iv = LLPanelMainInventory::getActiveInventory();
|
||||
#if 0 && !LL_RELEASE_FOR_DOWNLOAD
|
||||
if (sActiveViews.count() == 1)
|
||||
{
|
||||
@@ -401,7 +386,7 @@ LLInventoryView* LLInventoryView::showAgentInventory(BOOL take_keyboard_focus)
|
||||
if(!iv && !gAgentCamera.cameraMouselook())
|
||||
{
|
||||
// create one.
|
||||
iv = new LLInventoryView(std::string("Inventory"),
|
||||
iv = new LLPanelMainInventory(std::string("Inventory"),
|
||||
std::string("FloaterInventoryRect"),
|
||||
&gInventory);
|
||||
iv->open();
|
||||
@@ -425,16 +410,16 @@ LLInventoryView* LLInventoryView::showAgentInventory(BOOL take_keyboard_focus)
|
||||
}
|
||||
|
||||
// static
|
||||
LLInventoryView* LLInventoryView::getActiveInventory()
|
||||
LLPanelMainInventory* LLPanelMainInventory::getActiveInventory()
|
||||
{
|
||||
LLInventoryView* iv = NULL;
|
||||
LLPanelMainInventory* iv = NULL;
|
||||
S32 count = sActiveViews.size();
|
||||
if(count > 0)
|
||||
{
|
||||
iv = sActiveViews.at(0);
|
||||
S32 z_order = gFloaterView->getZOrder(iv);
|
||||
S32 z_next = 0;
|
||||
LLInventoryView* next_iv = NULL;
|
||||
LLPanelMainInventory* next_iv = NULL;
|
||||
for(S32 i = 1; i < count; ++i)
|
||||
{
|
||||
next_iv = sActiveViews.at(i);
|
||||
@@ -450,7 +435,7 @@ LLInventoryView* LLInventoryView::getActiveInventory()
|
||||
}
|
||||
|
||||
// static
|
||||
void LLInventoryView::toggleVisibility()
|
||||
void LLPanelMainInventory::toggleVisibility()
|
||||
{
|
||||
S32 count = sActiveViews.size();
|
||||
if (0 == count)
|
||||
@@ -483,7 +468,7 @@ void LLInventoryView::toggleVisibility()
|
||||
}
|
||||
|
||||
// static
|
||||
void LLInventoryView::cleanup()
|
||||
void LLPanelMainInventory::cleanup()
|
||||
{
|
||||
S32 count = sActiveViews.size();
|
||||
for (S32 i = 0; i < count; i++)
|
||||
@@ -493,7 +478,7 @@ void LLInventoryView::cleanup()
|
||||
}
|
||||
|
||||
|
||||
void LLInventoryView::updateSortControls()
|
||||
void LLPanelMainInventory::updateSortControls()
|
||||
{
|
||||
U32 order = mActivePanel ? mActivePanel->getSortOrder() : gSavedSettings.getU32("InventorySortOrder");
|
||||
bool sort_by_date = order & LLInventoryFilter::SO_DATE;
|
||||
@@ -506,7 +491,7 @@ void LLInventoryView::updateSortControls()
|
||||
getControl("Inventory.SystemFoldersToTop")->setValue(sys_folders_on_top);
|
||||
}
|
||||
|
||||
void LLInventoryView::resetFilters()
|
||||
void LLPanelMainInventory::resetFilters()
|
||||
{
|
||||
LLFloaterInventoryFinder *finder = getFinder();
|
||||
getActivePanel()->getFilter()->resetDefault();
|
||||
@@ -519,72 +504,25 @@ void LLInventoryView::resetFilters()
|
||||
}
|
||||
|
||||
// static
|
||||
BOOL LLInventoryView::filtersVisible(void* user_data)
|
||||
BOOL LLPanelMainInventory::filtersVisible(void* user_data)
|
||||
{
|
||||
LLInventoryView* self = (LLInventoryView*)user_data;
|
||||
LLPanelMainInventory* self = (LLPanelMainInventory*)user_data;
|
||||
if(!self) return FALSE;
|
||||
|
||||
return self->getFinder() != NULL;
|
||||
}
|
||||
|
||||
void LLInventoryView::onClearSearch()
|
||||
|
||||
void LLPanelMainInventory::onFilterEdit(const std::string& search_string )
|
||||
{
|
||||
LLFloater *finder = getFinder();
|
||||
if (mActivePanel)
|
||||
{
|
||||
mActivePanel->setFilterSubString(LLStringUtil::null);
|
||||
mActivePanel->setFilterTypes(0xffffffffffffffffULL);
|
||||
}
|
||||
|
||||
if (finder)
|
||||
{
|
||||
LLFloaterInventoryFinder::selectAllTypes(finder);
|
||||
}
|
||||
|
||||
// re-open folders that were initially open
|
||||
if (mActivePanel)
|
||||
{
|
||||
mSavedFolderState->setApply(TRUE);
|
||||
mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
|
||||
LLOpenFoldersWithSelection opener;
|
||||
mActivePanel->getRootFolder()->applyFunctorRecursively(opener);
|
||||
mActivePanel->getRootFolder()->scrollToShowSelection();
|
||||
}
|
||||
//self->mFilterSubString = "";
|
||||
}
|
||||
|
||||
void LLInventoryView::onFilterEdit(const std::string& search_string )
|
||||
{
|
||||
if (search_string == "")
|
||||
{
|
||||
onClearSearch();
|
||||
}
|
||||
if (!mActivePanel)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LLInventoryModelBackgroundFetch::instance().start();
|
||||
|
||||
//self->mFilterSubString = search_string;
|
||||
std::string filter_text = search_string;
|
||||
std::string uppercase_search_string = filter_text;
|
||||
LLStringUtil::toUpper(uppercase_search_string);
|
||||
if (mActivePanel->getFilterSubString().empty() && uppercase_search_string.empty() /*self->mFilterSubString.empty()*/)
|
||||
{
|
||||
// current filter and new filter empty, do nothing
|
||||
return;
|
||||
}
|
||||
|
||||
// save current folder open state if no filter currently applied
|
||||
if (!mActivePanel->getRootFolder()->isFilterModified())
|
||||
{
|
||||
mSavedFolderState->setApply(FALSE);
|
||||
mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
|
||||
}
|
||||
|
||||
// set new filter string
|
||||
mActivePanel->setFilterSubString(uppercase_search_string/*self->mFilterSubString*/);
|
||||
// Internally handles saving/restoring folder states.
|
||||
mActivePanel->setFilterSubString(search_string);
|
||||
}
|
||||
|
||||
struct FilterEntry : public LLDictionaryEntry
|
||||
@@ -599,7 +537,7 @@ class LLFilterDictionary : public LLSingleton<LLFilterDictionary>,
|
||||
public:
|
||||
LLFilterDictionary()
|
||||
{}
|
||||
void init(LLInventoryView *view)
|
||||
void init(LLPanelMainInventory *view)
|
||||
{
|
||||
addEntry(0x1 << LLInventoryType::IT_ANIMATION, new FilterEntry(view->getString("filter_type_animation")));
|
||||
addEntry(0x1 << LLInventoryType::IT_CALLINGCARD, new FilterEntry(view->getString("filter_type_callingcard")));
|
||||
@@ -621,12 +559,12 @@ public:
|
||||
};
|
||||
|
||||
//static
|
||||
void LLInventoryView::onQuickFilterCommit(LLUICtrl* ctrl, void* user_data)
|
||||
void LLPanelMainInventory::onQuickFilterCommit(LLUICtrl* ctrl, void* user_data)
|
||||
{
|
||||
|
||||
LLComboBox* quickfilter = (LLComboBox*)ctrl;
|
||||
|
||||
LLInventoryView* view = (LLInventoryView*)(quickfilter->getParent());
|
||||
LLPanelMainInventory* view = (LLPanelMainInventory*)(quickfilter->getParent());
|
||||
if (!view->mActivePanel)
|
||||
{
|
||||
return;
|
||||
@@ -669,9 +607,9 @@ void LLInventoryView::onQuickFilterCommit(LLUICtrl* ctrl, void* user_data)
|
||||
|
||||
|
||||
//static
|
||||
void LLInventoryView::refreshQuickFilter(LLUICtrl* ctrl)
|
||||
void LLPanelMainInventory::refreshQuickFilter(LLUICtrl* ctrl)
|
||||
{
|
||||
LLInventoryView* view = (LLInventoryView*)(ctrl->getParent());
|
||||
LLPanelMainInventory* view = (LLPanelMainInventory*)(ctrl->getParent());
|
||||
if (!view->mActivePanel)
|
||||
{
|
||||
return;
|
||||
@@ -725,9 +663,9 @@ void LLInventoryView::refreshQuickFilter(LLUICtrl* ctrl)
|
||||
}
|
||||
}
|
||||
|
||||
void LLInventoryView::onResetAll(void* userdata)
|
||||
void LLPanelMainInventory::onResetAll(void* userdata)
|
||||
{
|
||||
LLInventoryView* self = (LLInventoryView*) userdata;
|
||||
LLPanelMainInventory* self = (LLPanelMainInventory*) userdata;
|
||||
self->mActivePanel = (LLInventoryPanel*)self->childGetVisibleTab("inventory filter tabs");
|
||||
|
||||
if (!self->mActivePanel)
|
||||
@@ -743,9 +681,9 @@ void LLInventoryView::onResetAll(void* userdata)
|
||||
}
|
||||
|
||||
//static
|
||||
void LLInventoryView::onExpandAll(void* userdata)
|
||||
void LLPanelMainInventory::onExpandAll(void* userdata)
|
||||
{
|
||||
LLInventoryView* self = (LLInventoryView*) userdata;
|
||||
LLPanelMainInventory* self = (LLPanelMainInventory*) userdata;
|
||||
self->mActivePanel = (LLInventoryPanel*)self->childGetVisibleTab("inventory filter tabs");
|
||||
|
||||
if (!self->mActivePanel)
|
||||
@@ -757,9 +695,9 @@ void LLInventoryView::onExpandAll(void* userdata)
|
||||
|
||||
|
||||
//static
|
||||
void LLInventoryView::onCollapseAll(void* userdata)
|
||||
void LLPanelMainInventory::onCollapseAll(void* userdata)
|
||||
{
|
||||
LLInventoryView* self = (LLInventoryView*) userdata;
|
||||
LLPanelMainInventory* self = (LLPanelMainInventory*) userdata;
|
||||
self->mActivePanel = (LLInventoryPanel*)self->childGetVisibleTab("inventory filter tabs");
|
||||
|
||||
if (!self->mActivePanel)
|
||||
@@ -769,7 +707,7 @@ void LLInventoryView::onCollapseAll(void* userdata)
|
||||
self->mActivePanel->closeAllFolders();
|
||||
}
|
||||
|
||||
void LLInventoryView::onFilterSelected()
|
||||
void LLPanelMainInventory::onFilterSelected()
|
||||
{
|
||||
// Find my index
|
||||
mActivePanel = (LLInventoryPanel*)childGetVisibleTab("inventory filter tabs");
|
||||
@@ -779,7 +717,6 @@ void LLInventoryView::onFilterSelected()
|
||||
return;
|
||||
}
|
||||
|
||||
//>setFilterSubString(self->mFilterSubString);
|
||||
LLInventoryFilter* filter = mActivePanel->getFilter();
|
||||
LLFloaterInventoryFinder *finder = getFinder();
|
||||
if (finder)
|
||||
@@ -795,18 +732,18 @@ void LLInventoryView::onFilterSelected()
|
||||
updateSortControls();
|
||||
}
|
||||
|
||||
const std::string LLInventoryView::getFilterSubString()
|
||||
const std::string LLPanelMainInventory::getFilterSubString()
|
||||
{
|
||||
return mActivePanel->getFilterSubString();
|
||||
}
|
||||
|
||||
void LLInventoryView::setFilterSubString(const std::string& string)
|
||||
void LLPanelMainInventory::setFilterSubString(const std::string& string)
|
||||
{
|
||||
mActivePanel->setFilterSubString(string);
|
||||
}
|
||||
|
||||
|
||||
BOOL LLInventoryView::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
||||
BOOL LLPanelMainInventory::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data,
|
||||
EAcceptance* accept,
|
||||
@@ -828,7 +765,7 @@ BOOL LLInventoryView::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
||||
return handled;
|
||||
}
|
||||
|
||||
void LLInventoryView::changed(U32 mask)
|
||||
void LLPanelMainInventory::changed(U32 mask)
|
||||
{
|
||||
// Singu note: only if there's a change we're interested in.
|
||||
if ((mask & (LLInventoryObserver::ADD | LLInventoryObserver::REMOVE)) != 0)
|
||||
@@ -837,7 +774,7 @@ void LLInventoryView::changed(U32 mask)
|
||||
}
|
||||
}
|
||||
|
||||
void LLInventoryView::draw()
|
||||
void LLPanelMainInventory::draw()
|
||||
{
|
||||
if (mActivePanel && mFilterEditor)
|
||||
{
|
||||
@@ -865,7 +802,7 @@ void LLInventoryView::draw()
|
||||
LLFloater::draw();
|
||||
}
|
||||
|
||||
void LLInventoryView::updateItemcountText()
|
||||
void LLPanelMainInventory::updateItemcountText()
|
||||
{
|
||||
std::ostringstream title;
|
||||
title << "Inventory";
|
||||
@@ -883,12 +820,12 @@ void LLInventoryView::updateItemcountText()
|
||||
setTitle(title.str());
|
||||
|
||||
}
|
||||
void LLInventoryView::setFilterTextFromFilter()
|
||||
void LLPanelMainInventory::setFilterTextFromFilter()
|
||||
{
|
||||
mFilterText = mActivePanel->getFilter()->getFilterText();
|
||||
}
|
||||
|
||||
void LLInventoryView::toggleFindOptions()
|
||||
void LLPanelMainInventory::toggleFindOptions()
|
||||
{
|
||||
LLFloater *floater = getFinder();
|
||||
if (!floater)
|
||||
@@ -913,19 +850,19 @@ void LLInventoryView::toggleFindOptions()
|
||||
}
|
||||
}
|
||||
|
||||
LLFolderView* LLInventoryView::getRootFolder() const
|
||||
LLFolderView* LLPanelMainInventory::getRootFolder() const
|
||||
{
|
||||
return mActivePanel ? (mActivePanel->getRootFolder()) : NULL;
|
||||
}
|
||||
|
||||
void LLInventoryView::setSelectCallback(const LLFolderView::signal_t::slot_type& cb)
|
||||
void LLPanelMainInventory::setSelectCallback(const LLFolderView::signal_t::slot_type& cb)
|
||||
{
|
||||
getChild<LLInventoryPanel>("All Items")->setSelectCallback(cb);
|
||||
getChild<LLInventoryPanel>("Recent Items")->setSelectCallback(cb);
|
||||
getChild<LLInventoryPanel>("Worn Items")->setSelectCallback(cb);
|
||||
}
|
||||
|
||||
void LLInventoryView::onSelectionChange(LLInventoryPanel *panel, const std::deque<LLFolderViewItem*>& items, BOOL user_action)
|
||||
void LLPanelMainInventory::onSelectionChange(LLInventoryPanel *panel, const std::deque<LLFolderViewItem*>& items, BOOL user_action)
|
||||
{
|
||||
panel->onSelectionChange(items, user_action);
|
||||
}
|
||||
@@ -934,7 +871,7 @@ void LLInventoryView::onSelectionChange(LLInventoryPanel *panel, const std::dequ
|
||||
/// LLFloaterInventoryFinder
|
||||
///----------------------------------------------------------------------------
|
||||
|
||||
LLFloaterInventoryFinder* LLInventoryView::getFinder()
|
||||
LLFloaterInventoryFinder* LLPanelMainInventory::getFinder()
|
||||
{
|
||||
return (LLFloaterInventoryFinder*)mFinderHandle.get();
|
||||
}
|
||||
@@ -942,11 +879,11 @@ LLFloaterInventoryFinder* LLInventoryView::getFinder()
|
||||
|
||||
LLFloaterInventoryFinder::LLFloaterInventoryFinder(const std::string& name,
|
||||
const LLRect& rect,
|
||||
LLInventoryView* inventory_view) :
|
||||
LLPanelMainInventory* inventory_view) :
|
||||
LLFloater(name, rect, std::string("Filters"), RESIZE_NO,
|
||||
INV_FINDER_WIDTH, INV_FINDER_HEIGHT, DRAG_ON_TOP,
|
||||
MINIMIZE_NO, CLOSE_YES),
|
||||
mInventoryView(inventory_view),
|
||||
mPanelMainInventory(inventory_view),
|
||||
mFilter(inventory_view->getPanel()->getFilter())
|
||||
{
|
||||
|
||||
@@ -956,7 +893,7 @@ LLFloaterInventoryFinder::LLFloaterInventoryFinder(const std::string& name,
|
||||
|
||||
BOOL LLFloaterInventoryFinder::postBuild()
|
||||
{
|
||||
const LLRect& viewrect = mInventoryView->getRect();
|
||||
const LLRect& viewrect = mPanelMainInventory->getRect();
|
||||
setRect(LLRect(viewrect.mLeft - getRect().getWidth(), viewrect.mTop, viewrect.mLeft, viewrect.mTop - getRect().getHeight()));
|
||||
|
||||
childSetAction("All", selectAllTypes, this);
|
||||
@@ -979,12 +916,34 @@ void LLFloaterInventoryFinder::onTimeAgo(LLUICtrl *ctrl, void *user_data)
|
||||
LLFloaterInventoryFinder *self = (LLFloaterInventoryFinder *)user_data;
|
||||
if (!self) return;
|
||||
|
||||
bool since_logoff=true;
|
||||
if ( self->mSpinSinceDays->get() || self->mSpinSinceHours->get() )
|
||||
{
|
||||
since_logoff = false;
|
||||
self->getChild<LLUICtrl>("check_since_logoff")->setValue(false);
|
||||
|
||||
U32 days = (U32)self->mSpinSinceDays->get();
|
||||
U32 hours = (U32)self->mSpinSinceHours->get();
|
||||
if (hours >= 24)
|
||||
{
|
||||
// Try to handle both cases of spinner clicking and text input in a sensible fashion as best as possible.
|
||||
// There is no way to tell if someone has clicked the spinner to get to 24 or input 24 manually, so in
|
||||
// this case add to days. Any value > 24 means they have input the hours manually, so do not add to the
|
||||
// current day value.
|
||||
if (24 == hours) // Got to 24 via spinner clicking or text input of 24
|
||||
{
|
||||
days = days + hours / 24;
|
||||
}
|
||||
else // Text input, so do not add to days
|
||||
{
|
||||
days = hours / 24;
|
||||
}
|
||||
hours = (U32)hours % 24;
|
||||
self->mSpinSinceHours->setFocus(false);
|
||||
self->mSpinSinceDays->setFocus(false);
|
||||
self->mSpinSinceDays->set((F32)days);
|
||||
self->mSpinSinceHours->set((F32)hours);
|
||||
self->mSpinSinceHours->setFocus(true);
|
||||
}
|
||||
}
|
||||
self->childSetValue("check_since_logoff", since_logoff);
|
||||
}
|
||||
|
||||
void LLFloaterInventoryFinder::changeFilter(LLInventoryFilter* filter)
|
||||
@@ -1108,9 +1067,9 @@ void LLFloaterInventoryFinder::draw()
|
||||
}
|
||||
|
||||
// update the panel, panel will update the filter
|
||||
mInventoryView->getPanel()->setShowFolderState(getCheckShowEmpty() ?
|
||||
mPanelMainInventory->getPanel()->setShowFolderState(getCheckShowEmpty() ?
|
||||
LLInventoryFilter::SHOW_ALL_FOLDERS : LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
|
||||
mInventoryView->getPanel()->setFilterTypes(filter);
|
||||
mPanelMainInventory->getPanel()->setFilterTypes(filter);
|
||||
if (getCheckSinceLogoff())
|
||||
{
|
||||
mSpinSinceDays->set(0);
|
||||
@@ -1126,22 +1085,22 @@ void LLFloaterInventoryFinder::draw()
|
||||
mSpinSinceHours->set((F32)hours);
|
||||
}
|
||||
hours += days * 24;
|
||||
mInventoryView->getPanel()->setHoursAgo(hours);
|
||||
mInventoryView->getPanel()->setSinceLogoff(getCheckSinceLogoff());
|
||||
mInventoryView->setFilterTextFromFilter();
|
||||
mPanelMainInventory->getPanel()->setHoursAgo(hours);
|
||||
mPanelMainInventory->getPanel()->setSinceLogoff(getCheckSinceLogoff());
|
||||
mPanelMainInventory->setFilterTextFromFilter();
|
||||
|
||||
LLFloater::draw();
|
||||
}
|
||||
|
||||
void LLFloaterInventoryFinder::onClose(bool app_quitting)
|
||||
{
|
||||
if (mInventoryView) mInventoryView->getControl("Inventory.ShowFilters")->setValue(FALSE);
|
||||
if (mPanelMainInventory) mPanelMainInventory->getControl("Inventory.ShowFilters")->setValue(FALSE);
|
||||
// If you want to reset the filter on close, do it here. This functionality was
|
||||
// hotly debated - Paulm
|
||||
#if 0
|
||||
if (mInventoryView)
|
||||
if (mPanelMainInventory)
|
||||
{
|
||||
LLInventoryView::onResetFilter((void *)mInventoryView);
|
||||
LLPanelMainInventory::onResetFilter((void *)mPanelMainInventory);
|
||||
}
|
||||
#endif
|
||||
destroy();
|
||||
@@ -1153,6 +1112,7 @@ BOOL LLFloaterInventoryFinder::getCheckShowEmpty()
|
||||
return getChild<LLUICtrl>("check_show_empty")->getValue();
|
||||
}
|
||||
|
||||
|
||||
BOOL LLFloaterInventoryFinder::getCheckSinceLogoff()
|
||||
{
|
||||
return getChild<LLUICtrl>("check_since_logoff")->getValue();
|
||||
|
||||
@@ -46,22 +46,22 @@ class LLFilterEditor;
|
||||
class LLComboBox;
|
||||
class LLFloaterInventoryFinder;
|
||||
|
||||
class LLInventoryView : public LLFloater, LLInventoryObserver
|
||||
class LLPanelMainInventory : public LLFloater, LLInventoryObserver
|
||||
{
|
||||
friend class LLFloaterInventoryFinder;
|
||||
|
||||
public:
|
||||
LLInventoryView(const std::string& name, const std::string& rect,
|
||||
LLPanelMainInventory(const std::string& name, const std::string& rect,
|
||||
LLInventoryModel* inventory);
|
||||
LLInventoryView(const std::string& name, const LLRect& rect,
|
||||
LLPanelMainInventory(const std::string& name, const LLRect& rect,
|
||||
LLInventoryModel* inventory);
|
||||
~LLInventoryView();
|
||||
~LLPanelMainInventory();
|
||||
|
||||
BOOL postBuild();
|
||||
|
||||
//TODO: Move these statics.
|
||||
static LLInventoryView* showAgentInventory(BOOL take_keyboard_focus=FALSE);
|
||||
static LLInventoryView* getActiveInventory();
|
||||
static LLPanelMainInventory* showAgentInventory(BOOL take_keyboard_focus=FALSE);
|
||||
static LLPanelMainInventory* getActiveInventory();
|
||||
static void toggleVisibility();
|
||||
static void toggleVisibility(void*) { toggleVisibility(); }
|
||||
// Final cleanup, destroy all open inventory views.
|
||||
@@ -103,7 +103,6 @@ public:
|
||||
void onSelectionChange(LLInventoryPanel *panel, const std::deque<LLFolderViewItem*>& items, BOOL user_action);
|
||||
|
||||
static BOOL filtersVisible(void* user_data);
|
||||
void onClearSearch();
|
||||
static void onFoldersByName(void *user_data);
|
||||
static BOOL checkFoldersByName(void *user_data);
|
||||
|
||||
@@ -132,7 +131,7 @@ public:
|
||||
{
|
||||
// If there are mulitple inventory floaters open then clicking the "Inventory" button will close
|
||||
// them one by one (see LLToolBar::onClickInventory() => toggleVisibility() ) until we get to the
|
||||
// last one which will just be hidden instead of closed/destroyed (see LLInventoryView::onClose)
|
||||
// last one which will just be hidden instead of closed/destroyed (see LLPanelMainInventory::onClose)
|
||||
//
|
||||
// However the view isn't removed from sActiveViews until its destructor is called and since
|
||||
// 'LLMortician::sDestroyImmediate == FALSE' while the viewer is running the destructor won't be
|
||||
@@ -143,7 +142,7 @@ public:
|
||||
//
|
||||
// Workaround: "fix" onClose() to count only views that aren't marked as "dead"
|
||||
|
||||
LLInventoryView* pView; U8 flagsSound;
|
||||
LLPanelMainInventory* pView; U8 flagsSound;
|
||||
for (S32 idx = sActiveViews.size() - 1; idx >= 0; idx--)
|
||||
{
|
||||
pView = sActiveViews.at(idx);
|
||||
@@ -168,14 +167,13 @@ protected:
|
||||
LLHandle<LLFloater> mFinderHandle;
|
||||
LLInventoryPanel* mActivePanel;
|
||||
bool mResortActivePanel;
|
||||
LLSaveFolderState* mSavedFolderState;
|
||||
std::string mFilterText;
|
||||
//std::string mFilterSubString;
|
||||
|
||||
|
||||
// This container is used to hold all active inventory views. This
|
||||
// is here to support the inventory toggle show button.
|
||||
static std::vector<LLInventoryView*> sActiveViews;
|
||||
static std::vector<LLPanelMainInventory*> sActiveViews;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -2280,13 +2280,13 @@ bool idle_startup()
|
||||
|
||||
// Create the inventory views
|
||||
LL_INFOS() << "Creating Inventory Views" << LL_ENDL;
|
||||
LLInventoryView::showAgentInventory();
|
||||
LLPanelMainInventory::showAgentInventory();
|
||||
display_startup();
|
||||
|
||||
// Hide the inventory if it wasn't shown at exit
|
||||
if(!shown_at_exit)
|
||||
{
|
||||
LLInventoryView::toggleVisibility(NULL);
|
||||
LLPanelMainInventory::toggleVisibility(NULL);
|
||||
}
|
||||
display_startup();
|
||||
|
||||
|
||||
@@ -222,7 +222,6 @@ protected:
|
||||
BOOL mCanApplyImmediately;
|
||||
BOOL mNoCopyTextureSelected;
|
||||
F32 mContextConeOpacity;
|
||||
LLSaveFolderState mSavedFolderState;
|
||||
BOOL mSelectedItemPinned;
|
||||
LLScrollListCtrl* mLocalScrollCtrl; // tag: vaa emerald local_asset_browser
|
||||
|
||||
@@ -273,8 +272,6 @@ LLFloaterTexturePicker::LLFloaterTexturePicker(
|
||||
|
||||
|
||||
setCanMinimize(FALSE);
|
||||
|
||||
mSavedFolderState.setApply(FALSE);
|
||||
}
|
||||
|
||||
LLFloaterTexturePicker::~LLFloaterTexturePicker()
|
||||
@@ -1059,36 +1056,14 @@ void LLFloaterTexturePicker::setCanApply(bool can_preview, bool can_apply)
|
||||
|
||||
void LLFloaterTexturePicker::onFilterEdit(const std::string& search_string )
|
||||
{
|
||||
std::string upper_case_search_string = search_string;
|
||||
LLStringUtil::toUpper(upper_case_search_string);
|
||||
|
||||
if (upper_case_search_string.empty())
|
||||
if (!mInventoryPanel)
|
||||
{
|
||||
if (mInventoryPanel->getFilterSubString().empty())
|
||||
{
|
||||
// current filter and new filter empty, do nothing
|
||||
return;
|
||||
}
|
||||
|
||||
mSavedFolderState.setApply(TRUE);
|
||||
mInventoryPanel->getRootFolder()->applyFunctorRecursively(mSavedFolderState);
|
||||
// add folder with current item to list of previously opened folders
|
||||
LLOpenFoldersWithSelection opener;
|
||||
mInventoryPanel->getRootFolder()->applyFunctorRecursively(opener);
|
||||
mInventoryPanel->getRootFolder()->scrollToShowSelection();
|
||||
|
||||
}
|
||||
else if (mInventoryPanel->getFilterSubString().empty())
|
||||
{
|
||||
// first letter in search term, save existing folder open state
|
||||
if (!mInventoryPanel->getRootFolder()->isFilterModified())
|
||||
{
|
||||
mSavedFolderState.setApply(FALSE);
|
||||
mInventoryPanel->getRootFolder()->applyFunctorRecursively(mSavedFolderState);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
mInventoryPanel->setFilterSubString(upper_case_search_string);
|
||||
// set new filter string
|
||||
// Internally handles saving/restoring folder states.
|
||||
mInventoryPanel->setFilterSubString(search_string);
|
||||
}
|
||||
|
||||
void LLFloaterTexturePicker::onTextureSelect( const LLTextureEntry& te )
|
||||
|
||||
@@ -161,7 +161,7 @@ BOOL LLToolBar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
||||
LLButton* inventory_btn = mInventoryBtn;
|
||||
if (!inventory_btn || !inventory_btn->getVisible()) return FALSE;
|
||||
|
||||
LLInventoryView* active_inventory = LLInventoryView::getActiveInventory();
|
||||
LLPanelMainInventory* active_inventory = LLPanelMainInventory::getActiveInventory();
|
||||
|
||||
if (active_inventory && active_inventory->getVisible())
|
||||
{
|
||||
@@ -174,7 +174,7 @@ BOOL LLToolBar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
||||
if (!(active_inventory && active_inventory->getVisible()) &&
|
||||
mInventoryAutoOpenTimer.getElapsedTimeF32() > sInventoryAutoOpenTime)
|
||||
{
|
||||
LLInventoryView::showAgentInventory();
|
||||
LLPanelMainInventory::showAgentInventory();
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -1254,7 +1254,7 @@ void open_inventory_offer(const uuid_vec_t& objects, const std::string& from_nam
|
||||
//highlight item, if it's not in the trash or lost+found
|
||||
|
||||
// Don't auto-open the inventory floater
|
||||
LLInventoryView* view = LLInventoryView::getActiveInventory();
|
||||
LLPanelMainInventory* view = LLPanelMainInventory::getActiveInventory();
|
||||
if(!view)
|
||||
{
|
||||
return;
|
||||
@@ -1274,7 +1274,7 @@ void open_inventory_offer(const uuid_vec_t& objects, const std::string& from_nam
|
||||
item->getInventoryType() != LLInventoryType::IT_ATTACHMENT &&
|
||||
!from_name.empty())
|
||||
{
|
||||
LLInventoryView::showAgentInventory(TRUE);
|
||||
LLPanelMainInventory::showAgentInventory(TRUE);
|
||||
}
|
||||
|
||||
if (!gSavedSettings.getBOOL("LiruHighlightNewInventory")) return;
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
#include "llfloatertools.h"
|
||||
#include "llhudeffectlookat.h"
|
||||
#include "llhudmanager.h"
|
||||
#include "llinventoryview.h"
|
||||
#include "llpanelmaininventory.h"
|
||||
#include "lljoystickbutton.h"
|
||||
#include "llmenugl.h"
|
||||
#include "llmorphview.h"
|
||||
|
||||
@@ -232,7 +232,7 @@ void RlvUIEnabler::onToggleShowInv(bool fQuitting)
|
||||
//
|
||||
if (!fEnable)
|
||||
{
|
||||
LLInventoryView::closeAll();
|
||||
LLPanelMainInventory::closeAll();
|
||||
LFFloaterInvPanel::closeAll();
|
||||
|
||||
// Singu Note: Hide our standalone inventory favorites floater if present
|
||||
|
||||
Reference in New Issue
Block a user