summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/CMakeLists.txt7
-rwxr-xr-xindra/newview/llavataractions.cpp29
-rw-r--r--indra/newview/llfavoritesbar.cpp308
-rw-r--r--indra/newview/llfavoritesbar.h111
-rw-r--r--indra/newview/llfloateroutbox.cpp13
-rw-r--r--indra/newview/llfolderview.cpp2611
-rw-r--r--indra/newview/llfolderview.h367
-rw-r--r--indra/newview/llfoldervieweventlistener.h103
-rw-r--r--indra/newview/llfolderviewitem.cpp2919
-rw-r--r--indra/newview/llfolderviewitem.h576
-rw-r--r--indra/newview/llfolderviewmodelinventory.cpp332
-rw-r--r--indra/newview/llfolderviewmodelinventory.h116
-rw-r--r--indra/newview/llfriendcard.cpp4
-rw-r--r--indra/newview/llimfloatercontainer.cpp36
-rw-r--r--indra/newview/llimfloatercontainer.h113
-rw-r--r--indra/newview/llinventorybridge.cpp541
-rw-r--r--indra/newview/llinventorybridge.h96
-rw-r--r--indra/newview/llinventoryfilter.cpp393
-rw-r--r--indra/newview/llinventoryfilter.h179
-rw-r--r--indra/newview/llinventoryfunctions.cpp100
-rw-r--r--indra/newview/llinventoryfunctions.h57
-rw-r--r--indra/newview/llinventorymodel.cpp61
-rw-r--r--indra/newview/llinventorymodel.h9
-rw-r--r--indra/newview/llinventorypanel.cpp392
-rw-r--r--indra/newview/llinventorypanel.h41
-rw-r--r--indra/newview/llpanellandmarks.cpp143
-rw-r--r--indra/newview/llpanellandmarks.h2
-rw-r--r--indra/newview/llpanelmaininventory.cpp72
-rw-r--r--indra/newview/llpanelmarketplaceinbox.cpp4
-rw-r--r--indra/newview/llpanelmarketplaceinboxinventory.cpp47
-rw-r--r--indra/newview/llpanelmarketplaceinboxinventory.h4
-rw-r--r--indra/newview/llpanelmarketplaceoutboxinventory.cpp21
-rw-r--r--indra/newview/llpanelobjectinventory.cpp77
-rw-r--r--indra/newview/llpanelobjectinventory.h2
-rw-r--r--indra/newview/llpaneloutfitedit.cpp30
-rw-r--r--indra/newview/llplacesinventorybridge.cpp48
-rw-r--r--indra/newview/llplacesinventorybridge.h1
-rw-r--r--indra/newview/llplacesinventorypanel.cpp8
-rw-r--r--indra/newview/llsidepanelappearance.cpp6
-rw-r--r--indra/newview/llsidepanelinventory.cpp17
-rw-r--r--indra/newview/llsidepanelinventory.h2
-rw-r--r--indra/newview/lltexturectrl.cpp31
-rw-r--r--indra/newview/llviewerinventory.cpp364
-rw-r--r--indra/newview/llviewerinventory.h27
-rwxr-xr-xindra/newview/llviewermessage.cpp20
45 files changed, 2322 insertions, 8118 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index e67089c4de..b31b99f47c 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -253,8 +253,7 @@ set(viewer_SOURCE_FILES
llfloaterwhitelistentry.cpp
llfloaterwindowsize.cpp
llfloaterworldmap.cpp
- llfolderview.cpp
- llfolderviewitem.cpp
+ llfolderviewmodelinventory.cpp
llfollowcam.cpp
llfriendcard.cpp
llgesturelistener.cpp
@@ -811,9 +810,7 @@ set(viewer_HEADER_FILES
llfloaterwhitelistentry.h
llfloaterwindowsize.h
llfloaterworldmap.h
- llfolderview.h
- llfoldervieweventlistener.h
- llfolderviewitem.h
+ llfolderviewmodelinventory.h
llfollowcam.h
llfriendcard.h
llgesturelistener.h
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 56c9533e11..6babdc1f44 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -710,23 +710,30 @@ void LLAvatarActions::buildResidentsString(const std::vector<LLAvatarName> avata
//static
std::set<LLUUID> LLAvatarActions::getInventorySelectedUUIDs()
{
- std::set<LLUUID> inventory_selected_uuids;
+ std::set<LLFolderViewItem*> inventory_selected;
LLInventoryPanel* active_panel = action_give_inventory::get_active_inventory_panel();
if (active_panel)
{
- inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList();
+ inventory_selected= active_panel->getRootFolder()->getSelectionList();
}
- if (inventory_selected_uuids.empty())
+ if (inventory_selected.empty())
{
LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
if (sidepanel_inventory)
{
- inventory_selected_uuids = sidepanel_inventory->getInboxSelectionList();
+ inventory_selected= sidepanel_inventory->getInboxSelectionList();
}
}
+ std::set<LLUUID> inventory_selected_uuids;
+ for (std::set<LLFolderViewItem*>::iterator it = inventory_selected.begin(), end_it = inventory_selected.end();
+ it != end_it;
+ ++it)
+ {
+ inventory_selected_uuids.insert(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID());
+ }
return inventory_selected_uuids;
}
@@ -762,15 +769,15 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL
// check selection in the panel
LLFolderView* root_folder = inv_panel->getRootFolder();
- const std::set<LLUUID> inventory_selected_uuids = root_folder->getSelectionList();
- if (inventory_selected_uuids.empty()) return false; // nothing selected
+ const std::set<LLFolderViewItem*> inventory_selected = root_folder->getSelectionList();
+ if (inventory_selected.empty()) return false; // nothing selected
bool can_share = true;
- std::set<LLUUID>::const_iterator it = inventory_selected_uuids.begin();
- const std::set<LLUUID>::const_iterator it_end = inventory_selected_uuids.end();
+ std::set<LLFolderViewItem*>::const_iterator it = inventory_selected.begin();
+ const std::set<LLFolderViewItem*>::const_iterator it_end = inventory_selected.end();
for (; it != it_end; ++it)
{
- LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it);
+ LLViewerInventoryCategory* inv_cat = gInventory.getCategory(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID());
// any category can be offered.
if (inv_cat)
{
@@ -778,9 +785,9 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL
}
// check if inventory item can be given
- LLFolderViewItem* item = root_folder->getItemByID(*it);
+ LLFolderViewItem* item = *it;
if (!item) return false;
- LLInvFVBridge* bridge = dynamic_cast<LLInvFVBridge*>(item->getListener());
+ LLInvFVBridge* bridge = dynamic_cast<LLInvFVBridge*>(item->getViewModelItem());
if (bridge && bridge->canShare())
{
continue;
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index 575b613ccf..4a96de942d 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -38,6 +38,7 @@
#include "lltooltip.h"
#include "llagent.h"
+#include "llavatarnamecache.h"
#include "llclipboard.h"
#include "llclipboard.h"
#include "llinventorybridge.h"
@@ -45,12 +46,14 @@
#include "llfloatersidepanelcontainer.h"
#include "llfloaterworldmap.h"
#include "lllandmarkactions.h"
+#include "lllogininstance.h"
#include "llnotificationsutil.h"
#include "lltoggleablemenu.h"
#include "llviewerinventory.h"
#include "llviewermenu.h"
#include "llviewermenu.h"
#include "lltooldraganddrop.h"
+#include "llsdserialize.h"
static LLDefaultChildRegistry::Register<LLFavoritesBarCtrl> r("favorites_bar");
@@ -317,7 +320,8 @@ public:
if (item)
{
- item->setSortField(mSortField);
+ LLFavoritesOrderStorage::instance().setSortIndex(item, mSortField);
+
item->setComplete(TRUE);
item->updateServer(FALSE);
@@ -339,8 +343,8 @@ struct LLFavoritesSort
// TODO - made it customizible using gSavedSettings
bool operator()(const LLViewerInventoryItem* const& a, const LLViewerInventoryItem* const& b)
{
- S32 sortField1 = a->getSortField();
- S32 sortField2 = b->getSortField();
+ S32 sortField1 = LLFavoritesOrderStorage::instance().getSortIndex(a->getUUID());
+ S32 sortField2 = LLFavoritesOrderStorage::instance().getSortIndex(b->getUUID());
if (!(sortField1 < 0 && sortField2 < 0))
{
@@ -528,7 +532,7 @@ void LLFavoritesBarCtrl::handleExistingFavoriteDragAndDrop(S32 x, S32 y)
mItems.push_back(gInventory.getItem(mDragItemId));
}
- gInventory.saveItemsOrder(mItems);
+ LLFavoritesOrderStorage::instance().saveItemsOrder(mItems);
LLToggleableMenu* menu = (LLToggleableMenu*) mOverflowMenuHandle.get();
@@ -587,7 +591,8 @@ void LLFavoritesBarCtrl::handleNewFavoriteDragAndDrop(LLInventoryItem *item, con
}
else
{
- currItem->setSortField(++sortField);
+ LLFavoritesOrderStorage::instance().setSortIndex(currItem, ++sortField);
+
currItem->setComplete(TRUE);
currItem->updateServer(FALSE);
@@ -640,7 +645,7 @@ void LLFavoritesBarCtrl::changed(U32 mask)
for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i)
{
- (*i)->getSLURL();
+ LLFavoritesOrderStorage::instance().getSLURL((*i)->getAssetUUID());
}
updateButtons();
}
@@ -909,7 +914,7 @@ BOOL LLFavoritesBarCtrl::collectFavoriteItems(LLInventoryModel::item_array_t &it
S32 sortField = 0;
for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i)
{
- (*i)->setSortField(++sortField);
+ LLFavoritesOrderStorage::instance().setSortIndex((*i), ++sortField);
}
}
@@ -1355,7 +1360,7 @@ BOOL LLFavoritesBarCtrl::needToSaveItemsOrder(const LLInventoryModel::item_array
// if there is an item without sort order field set, we need to save items order
for (LLInventoryModel::item_array_t::const_iterator i = items.begin(); i != items.end(); ++i)
{
- if ((*i)->getSortField() < 0)
+ if (LLFavoritesOrderStorage::instance().getSortIndex((*i)->getUUID()) < 0)
{
result = TRUE;
break;
@@ -1390,4 +1395,291 @@ void LLFavoritesBarCtrl::insertItem(LLInventoryModel::item_array_t& items, const
}
}
+const std::string LLFavoritesOrderStorage::SORTING_DATA_FILE_NAME = "landmarks_sorting.xml";
+const S32 LLFavoritesOrderStorage::NO_INDEX = -1;
+
+void LLFavoritesOrderStorage::setSortIndex(const LLViewerInventoryItem* inv_item, S32 sort_index)
+{
+ mSortIndexes[inv_item->getUUID()] = sort_index;
+ mIsDirty = true;
+ getSLURL(inv_item->getAssetUUID());
+}
+
+S32 LLFavoritesOrderStorage::getSortIndex(const LLUUID& inv_item_id)
+{
+ sort_index_map_t::const_iterator it = mSortIndexes.find(inv_item_id);
+ if (it != mSortIndexes.end())
+ {
+ return it->second;
+ }
+ return NO_INDEX;
+}
+
+void LLFavoritesOrderStorage::removeSortIndex(const LLUUID& inv_item_id)
+{
+ mSortIndexes.erase(inv_item_id);
+ mIsDirty = true;
+}
+
+void LLFavoritesOrderStorage::getSLURL(const LLUUID& asset_id)
+{
+ slurls_map_t::iterator slurl_iter = mSLURLs.find(asset_id);
+ if (slurl_iter != mSLURLs.end()) return; // SLURL for current landmark is already cached
+
+ LLLandmark* lm = gLandmarkList.getAsset(asset_id,
+ boost::bind(&LLFavoritesOrderStorage::onLandmarkLoaded, this, asset_id, _1));
+ if (lm)
+ {
+ onLandmarkLoaded(asset_id, lm);
+ }
+}
+
+// static
+void LLFavoritesOrderStorage::destroyClass()
+{
+ LLFavoritesOrderStorage::instance().cleanup();
+ if (gSavedPerAccountSettings.getBOOL("ShowFavoritesOnLogin"))
+ {
+ LLFavoritesOrderStorage::instance().saveFavoritesSLURLs();
+ }
+ else
+ {
+ LLFavoritesOrderStorage::instance().removeFavoritesRecordOfUser();
+ }
+}
+
+void LLFavoritesOrderStorage::load()
+{
+ // load per-resident sorting information
+ std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SORTING_DATA_FILE_NAME);
+
+ LLSD settings_llsd;
+ llifstream file;
+ file.open(filename);
+ if (file.is_open())
+ {
+ LLSDSerialize::fromXML(settings_llsd, file);
+ }
+
+ for (LLSD::map_const_iterator iter = settings_llsd.beginMap();
+ iter != settings_llsd.endMap(); ++iter)
+ {
+ mSortIndexes.insert(std::make_pair(LLUUID(iter->first), (S32)iter->second.asInteger()));
+ }
+}
+
+void LLFavoritesOrderStorage::saveFavoritesSLURLs()
+{
+ // Do not change the file if we are not logged in yet.
+ if (!LLLoginInstance::getInstance()->authSuccess())
+ {
+ llwarns << "Cannot save favorites: not logged in" << llendl;
+ return;
+ }
+
+ std::string user_dir = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "");
+ if (user_dir.empty())
+ {
+ llwarns << "Cannot save favorites: empty user dir name" << llendl;
+ return;
+ }
+
+ std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
+ llifstream in_file;
+ in_file.open(filename);
+ LLSD fav_llsd;
+ if (in_file.is_open())
+ {
+ LLSDSerialize::fromXML(fav_llsd, in_file);
+ }
+
+ const LLUUID fav_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+ LLInventoryModel::cat_array_t cats;
+ LLInventoryModel::item_array_t items;
+ gInventory.collectDescendents(fav_id, cats, items, LLInventoryModel::EXCLUDE_TRASH);
+
+ LLSD user_llsd;
+ for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); it++)
+ {
+ LLSD value;
+ value["name"] = (*it)->getName();
+ value["asset_id"] = (*it)->getAssetUUID();
+
+ slurls_map_t::iterator slurl_iter = mSLURLs.find(value["asset_id"]);
+ if (slurl_iter != mSLURLs.end())
+ {
+ lldebugs << "Saving favorite: idx=" << LLFavoritesOrderStorage::instance().getSortIndex((*it)->getUUID()) << ", SLURL=" << slurl_iter->second << ", value=" << value << llendl;
+ value["slurl"] = slurl_iter->second;
+ user_llsd[LLFavoritesOrderStorage::instance().getSortIndex((*it)->getUUID())] = value;
+ }
+ else
+ {
+ llwarns << "Not saving favorite " << value["name"] << ": no matching SLURL" << llendl;
+ }
+ }
+
+ LLAvatarName av_name;
+ LLAvatarNameCache::get( gAgentID, &av_name );
+ lldebugs << "Saved favorites for " << av_name.getLegacyName() << llendl;
+ fav_llsd[av_name.getLegacyName()] = user_llsd;
+
+ llofstream file;
+ file.open(filename);
+ LLSDSerialize::toPrettyXML(fav_llsd, file);
+}
+
+void LLFavoritesOrderStorage::removeFavoritesRecordOfUser()
+{
+ std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
+ LLSD fav_llsd;
+ llifstream file;
+ file.open(filename);
+ if (!file.is_open()) return;
+ LLSDSerialize::fromXML(fav_llsd, file);
+
+ LLAvatarName av_name;
+ LLAvatarNameCache::get( gAgentID, &av_name );
+ lldebugs << "Removed favorites for " << av_name.getLegacyName() << llendl;
+ if (fav_llsd.has(av_name.getLegacyName()))
+ {
+ fav_llsd.erase(av_name.getLegacyName());
+ }
+
+ llofstream out_file;
+ out_file.open(filename);
+ LLSDSerialize::toPrettyXML(fav_llsd, out_file);
+
+}
+
+void LLFavoritesOrderStorage::onLandmarkLoaded(const LLUUID& asset_id, LLLandmark* landmark)
+{
+ if (!landmark) return;
+
+ LLVector3d pos_global;
+ if (!landmark->getGlobalPos(pos_global))
+ {
+ // If global position was unknown on first getGlobalPos() call
+ // it should be set for the subsequent calls.
+ landmark->getGlobalPos(pos_global);
+ }
+
+ if (!pos_global.isExactlyZero())
+ {
+ LLLandmarkActions::getSLURLfromPosGlobal(pos_global,
+ boost::bind(&LLFavoritesOrderStorage::storeFavoriteSLURL, this, asset_id, _1));
+ }
+}
+
+void LLFavoritesOrderStorage::storeFavoriteSLURL(const LLUUID& asset_id, std::string& slurl)
+{
+ lldebugs << "Saving landmark SLURL: " << slurl << llendl;
+ mSLURLs[asset_id] = slurl;
+}
+
+void LLFavoritesOrderStorage::save()
+{
+ // nothing to save if clean
+ if (!mIsDirty) return;
+
+ // If we quit from the login screen we will not have an SL account
+ // name. Don't try to save, otherwise we'll dump a file in
+ // C:\Program Files\SecondLife\ or similar. JC
+ std::string user_dir = gDirUtilp->getLindenUserDir();
+ if (!user_dir.empty())
+ {
+ std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SORTING_DATA_FILE_NAME);
+ LLSD settings_llsd;
+
+ for(sort_index_map_t::const_iterator iter = mSortIndexes.begin(); iter != mSortIndexes.end(); ++iter)
+ {
+ settings_llsd[iter->first.asString()] = iter->second;
+ }
+
+ llofstream file;
+ file.open(filename);
+ LLSDSerialize::toPrettyXML(settings_llsd, file);
+ }
+}
+
+void LLFavoritesOrderStorage::cleanup()
+{
+ // nothing to clean
+ if (!mIsDirty) return;
+
+ const LLUUID fav_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+ LLInventoryModel::cat_array_t cats;
+ LLInventoryModel::item_array_t items;
+ gInventory.collectDescendents(fav_id, cats, items, LLInventoryModel::EXCLUDE_TRASH);
+
+ IsNotInFavorites is_not_in_fav(items);
+
+ sort_index_map_t aTempMap;
+ //copy unremoved values from mSortIndexes to aTempMap
+ std::remove_copy_if(mSortIndexes.begin(), mSortIndexes.end(),
+ inserter(aTempMap, aTempMap.begin()),
+ is_not_in_fav);
+
+ //Swap the contents of mSortIndexes and aTempMap
+ mSortIndexes.swap(aTempMap);
+}
+
+void LLFavoritesOrderStorage::saveItemsOrder( const LLInventoryModel::item_array_t& items )
+{
+ int sortField = 0;
+
+ // current order is saved by setting incremental values (1, 2, 3, ...) for the sort field
+ for (LLInventoryModel::item_array_t::const_iterator i = items.begin(); i != items.end(); ++i)
+ {
+ LLViewerInventoryItem* item = *i;
+
+ setSortIndex(item, ++sortField);
+
+ item->setComplete(TRUE);
+ item->updateServer(FALSE);
+
+ gInventory.updateItem(item);
+
+ // Tell the parent folder to refresh its sort order.
+ gInventory.addChangedMask(LLInventoryObserver::SORT, item->getParentUUID());
+ }
+
+ gInventory.notifyObservers();
+}
+
+// See also LLInventorySort where landmarks in the Favorites folder are sorted.
+class LLViewerInventoryItemSort
+{
+public:
+ bool operator()(const LLPointer<LLViewerInventoryItem>& a, const LLPointer<LLViewerInventoryItem>& b)
+ {
+ return LLFavoritesOrderStorage::instance().getSortIndex(a->getUUID())
+ < LLFavoritesOrderStorage::instance().getSortIndex(b->getUUID());
+ }
+};
+
+// * @param source_item_id - LLUUID of the source item to be moved into new position
+// * @param target_item_id - LLUUID of the target item before which source item should be placed.
+void LLFavoritesOrderStorage::rearrangeFavoriteLandmarks(const LLUUID& source_item_id, const LLUUID& target_item_id)
+{
+ LLInventoryModel::cat_array_t cats;
+ LLInventoryModel::item_array_t items;
+ LLIsType is_type(LLAssetType::AT_LANDMARK);
+ LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+ gInventory.collectDescendentsIf(favorites_id, cats, items, LLInventoryModel::EXCLUDE_TRASH, is_type);
+
+ // ensure items are sorted properly before changing order. EXT-3498
+ std::sort(items.begin(), items.end(), LLViewerInventoryItemSort());
+
+ // update order
+ gInventory.updateItemsOrder(items, source_item_id, target_item_id);
+
+ saveItemsOrder(items);
+}
+
+void AddFavoriteLandmarkCallback::fire(const LLUUID& inv_item_id)
+{
+ if (mTargetLandmarkId.isNull()) return;
+
+ LLFavoritesOrderStorage::instance().rearrangeFavoriteLandmarks(inv_item_id, mTargetLandmarkId);
+}
// EOF
diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h
index 2f75b3bb0e..60e02b661e 100644
--- a/indra/newview/llfavoritesbar.h
+++ b/indra/newview/llfavoritesbar.h
@@ -33,6 +33,7 @@
#include "llinventoryobserver.h"
#include "llinventorymodel.h"
+#include "llviewerinventory.h"
class LLMenuItemCallGL;
class LLToggleableMenu;
@@ -161,5 +162,115 @@ private:
boost::signals2::connection mEndDragConnection;
};
+class AddFavoriteLandmarkCallback : public LLInventoryCallback
+{
+public:
+ AddFavoriteLandmarkCallback() : mTargetLandmarkId(LLUUID::null) {}
+ void setTargetLandmarkId(const LLUUID& target_uuid) { mTargetLandmarkId = target_uuid; }
+
+private:
+ void fire(const LLUUID& inv_item);
+
+ LLUUID mTargetLandmarkId;
+};
+
+/**
+ * Class to store sorting order of favorites landmarks in a local file. EXT-3985.
+ * It replaced previously implemented solution to store sort index in landmark's name as a "<N>@" prefix.
+ * Data are stored in user home directory.
+ */
+class LLFavoritesOrderStorage : public LLSingleton<LLFavoritesOrderStorage>
+ , public LLDestroyClass<LLFavoritesOrderStorage>
+{
+ LOG_CLASS(LLFavoritesOrderStorage);
+public:
+ /**
+ * Sets sort index for specified with LLUUID favorite landmark
+ */
+ void setSortIndex(const LLViewerInventoryItem* inv_item, S32 sort_index);
+
+ /**
+ * Gets sort index for specified with LLUUID favorite landmark
+ */
+ S32 getSortIndex(const LLUUID& inv_item_id);
+ void removeSortIndex(const LLUUID& inv_item_id);
+
+ void getSLURL(const LLUUID& asset_id);
+
+ // Saves current order of the passed items using inventory item sort field.
+ // Resets 'items' sort fields and saves them on server.
+ // Is used to save order for Favorites folder.
+ void saveItemsOrder(const LLInventoryModel::item_array_t& items);
+
+ void rearrangeFavoriteLandmarks(const LLUUID& source_item_id, const LLUUID& target_item_id);
+
+ /**
+ * Implementation of LLDestroyClass. Calls cleanup() instance method.
+ *
+ * It is important this callback is called before gInventory is cleaned.
+ * For now it is called from LLAppViewer::cleanup() -> LLAppViewer::disconnectViewer(),
+ * Inventory is cleaned later from LLAppViewer::cleanup() after LLAppViewer::disconnectViewer() is called.
+ * @see cleanup()
+ */
+ static void destroyClass();
+
+ const static S32 NO_INDEX;
+private:
+ friend class LLSingleton<LLFavoritesOrderStorage>;
+ LLFavoritesOrderStorage() : mIsDirty(false) { load(); }
+ ~LLFavoritesOrderStorage() { save(); }
+
+ /**
+ * Removes sort indexes for items which are not in Favorites bar for now.
+ */
+ void cleanup();
+
+ const static std::string SORTING_DATA_FILE_NAME;
+
+ void load();
+ void save();
+
+ void saveFavoritesSLURLs();
+
+ // Remove record of current user's favorites from file on disk.
+ void removeFavoritesRecordOfUser();
+
+ void onLandmarkLoaded(const LLUUID& asset_id, class LLLandmark* landmark);
+ void storeFavoriteSLURL(const LLUUID& asset_id, std::string& slurl);
+
+ typedef std::map<LLUUID, S32> sort_index_map_t;
+ sort_index_map_t mSortIndexes;
+
+ typedef std::map<LLUUID, std::string> slurls_map_t;
+ slurls_map_t mSLURLs;
+
+ bool mIsDirty;
+
+ struct IsNotInFavorites
+ {
+ IsNotInFavorites(const LLInventoryModel::item_array_t& items)
+ : mFavoriteItems(items)
+ {
+
+ }
+
+ /**
+ * Returns true if specified item is not found among inventory items
+ */
+ bool operator()(const sort_index_map_t::value_type& id_index_pair) const
+ {
+ LLPointer<LLViewerInventoryItem> item = gInventory.getItem(id_index_pair.first);
+ if (item.isNull()) return true;
+
+ LLInventoryModel::item_array_t::const_iterator found_it =
+ std::find(mFavoriteItems.begin(), mFavoriteItems.end(), item);
+
+ return found_it == mFavoriteItems.end();
+ }
+ private:
+ LLInventoryModel::item_array_t mFavoriteItems;
+ };
+
+};
#endif // LL_LLFAVORITESBARCTRL_H
diff --git a/indra/newview/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp
index c55970ad69..04a55b261c 100644
--- a/indra/newview/llfloateroutbox.cpp
+++ b/indra/newview/llfloateroutbox.cpp
@@ -250,7 +250,8 @@ void LLFloaterOutbox::setupOutbox(const LLUUID& outboxId)
mOutboxInventoryPanel->setShape(inventory_placeholder_rect);
// Set the sort order newest to oldest
- mOutboxInventoryPanel->setSortOrder(LLInventoryFilter::SO_FOLDERS_BY_NAME);
+
+ mOutboxInventoryPanel->getFolderViewModel()->setSorter(LLInventoryFilter::SO_FOLDERS_BY_NAME);
mOutboxInventoryPanel->getFilter()->markDefault();
fetchOutboxContents();
@@ -386,7 +387,7 @@ BOOL LLFloaterOutbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
// Determine if the mouse is inside the inventory panel itself or just within the floater
bool pointInInventoryPanel = false;
bool pointInInventoryPanelChild = false;
- LLFolderView * root_folder = mOutboxInventoryPanel->getRootFolder();
+ LLFolderView* root_folder = mOutboxInventoryPanel->getRootFolder();
if (mOutboxInventoryPanel->getVisible())
{
S32 inv_x, inv_y;
@@ -443,10 +444,10 @@ void LLFloaterOutbox::onOutboxChanged()
{
llassert(!mOutboxId.isNull());
- if (mOutboxInventoryPanel)
- {
- mOutboxInventoryPanel->requestSort();
- }
+ //if (mOutboxInventoryPanel)
+ //{
+ // mOutboxInventoryPanel->requestSort();
+ //}
fetchOutboxContents();
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
deleted file mode 100644
index 57fc3f7efd..0000000000
--- a/indra/newview/llfolderview.cpp
+++ /dev/null
@@ -1,2611 +0,0 @@
-/**
- * @file llfolderview.cpp
- * @brief Implementation of the folder view collection of classes.
- *
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llfolderview.h"
-
-#include "llcallbacklist.h"
-#include "llinventorybridge.h"
-#include "llclipboard.h" // *TODO: remove this once hack below gone.
-#include "llinventoryfilter.h"
-#include "llinventoryfunctions.h"
-#include "llinventorymodelbackgroundfetch.h"
-#include "llinventorypanel.h"
-#include "llfoldertype.h"
-#include "llfloaterinventory.h"// hacked in for the bonus context menu items.
-#include "llkeyboard.h"
-#include "lllineeditor.h"
-#include "llmenugl.h"
-#include "llpanel.h"
-#include "llpreview.h"
-#include "llscrollcontainer.h" // hack to allow scrolling
-#include "lltooldraganddrop.h"
-#include "lltrans.h"
-#include "llui.h"
-#include "llviewertexture.h"
-#include "llviewertexturelist.h"
-#include "llviewerjointattachment.h"
-#include "llviewermenu.h"
-#include "lluictrlfactory.h"
-#include "llviewercontrol.h"
-#include "llviewerfoldertype.h"
-#include "llviewerwindow.h"
-#include "llvoavatar.h"
-#include "llfloaterproperties.h"
-#include "llnotificationsutil.h"
-
-// Linden library includes
-#include "lldbstrings.h"
-#include "llfocusmgr.h"
-#include "llfontgl.h"
-#include "llgl.h"
-#include "llrender.h"
-#include "llinventory.h"
-
-// Third-party library includes
-#include <algorithm>
-
-///----------------------------------------------------------------------------
-/// Local function declarations, constants, enums, and typedefs
-///----------------------------------------------------------------------------
-
-const S32 RENAME_WIDTH_PAD = 4;
-const S32 RENAME_HEIGHT_PAD = 1;
-const S32 AUTO_OPEN_STACK_DEPTH = 16;
-const S32 MIN_ITEM_WIDTH_VISIBLE = LLFolderViewItem::ICON_WIDTH
- + LLFolderViewItem::ICON_PAD
- + LLFolderViewItem::ARROW_SIZE
- + LLFolderViewItem::TEXT_PAD
- + /*first few characters*/ 40;
-const S32 MINIMUM_RENAMER_WIDTH = 80;
-
-// *TODO: move in params in xml if necessary. Requires modification of LLFolderView & LLInventoryPanel Params.
-const S32 STATUS_TEXT_HPAD = 6;
-const S32 STATUS_TEXT_VPAD = 8;
-
-enum {
- SIGNAL_NO_KEYBOARD_FOCUS = 1,
- SIGNAL_KEYBOARD_FOCUS = 2
-};
-
-F32 LLFolderView::sAutoOpenTime = 1.f;
-
-void delete_selected_item(void* user_data);
-void copy_selected_item(void* user_data);
-void open_selected_items(void* user_data);
-void properties_selected_items(void* user_data);
-void paste_items(void* user_data);
-
-
-//---------------------------------------------------------------------------
-
-// Tells all folders in a folderview to sort their items
-// (and only their items, not folders) by a certain function.
-class LLSetItemSortFunction : public LLFolderViewFunctor
-{
-public:
- LLSetItemSortFunction(U32 ordering)
- : mSortOrder(ordering) {}
- virtual ~LLSetItemSortFunction() {}
- virtual void doFolder(LLFolderViewFolder* folder);
- virtual void doItem(LLFolderViewItem* item);
-
- U32 mSortOrder;
-};
-
-
-// Set the sort order.
-void LLSetItemSortFunction::doFolder(LLFolderViewFolder* folder)
-{
- folder->setItemSortOrder(mSortOrder);
-}
-
-// Do nothing.
-void LLSetItemSortFunction::doItem(LLFolderViewItem* item)
-{
- return;
-}
-
-//---------------------------------------------------------------------------
-
-// Tells all folders in a folderview to close themselves
-// For efficiency, calls setOpenArrangeRecursively().
-// The calling function must then call:
-// LLFolderView* root = getRoot();
-// if( root )
-// {
-// root->arrange( NULL, NULL );
-// root->scrollToShowSelection();
-// }
-// to patch things up.
-class LLCloseAllFoldersFunctor : public LLFolderViewFunctor
-{
-public:
- LLCloseAllFoldersFunctor(BOOL close) { mOpen = !close; }
- virtual ~LLCloseAllFoldersFunctor() {}
- virtual void doFolder(LLFolderViewFolder* folder);
- virtual void doItem(LLFolderViewItem* item);
-
- BOOL mOpen;
-};
-
-
-// Set the sort order.
-void LLCloseAllFoldersFunctor::doFolder(LLFolderViewFolder* folder)
-{
- folder->setOpenArrangeRecursively(mOpen);
-}
-
-// Do nothing.
-void LLCloseAllFoldersFunctor::doItem(LLFolderViewItem* item)
-{ }
-
-///----------------------------------------------------------------------------
-/// Class LLFolderViewScrollContainer
-///----------------------------------------------------------------------------
-
-// virtual
-const LLRect LLFolderViewScrollContainer::getScrolledViewRect() const
-{
- LLRect rect = LLRect::null;
- if (mScrolledView)
- {
- LLFolderView* folder_view = dynamic_cast<LLFolderView*>(mScrolledView);
- if (folder_view)
- {
- S32 height = folder_view->mRunningHeight;
-
- rect = mScrolledView->getRect();
- rect.setLeftTopAndSize(rect.mLeft, rect.mTop, rect.getWidth(), height);
- }
- }
-
- return rect;
-}
-
-LLFolderViewScrollContainer::LLFolderViewScrollContainer(const LLScrollContainer::Params& p)
-: LLScrollContainer(p)
-{}
-
-///----------------------------------------------------------------------------
-/// Class LLFolderView
-///----------------------------------------------------------------------------
-LLFolderView::Params::Params()
-: task_id("task_id"),
- title("title"),
- use_label_suffix("use_label_suffix"),
- allow_multiselect("allow_multiselect", true),
- show_empty_message("show_empty_message", true),
- show_load_status("show_load_status", true),
- use_ellipses("use_ellipses", false)
-{
- folder_indentation = -4;
-}
-
-
-// Default constructor
-LLFolderView::LLFolderView(const Params& p)
-: LLFolderViewFolder(p),
- mRunningHeight(0),
- mScrollContainer( NULL ),
- mPopupMenuHandle(),
- mAllowMultiSelect(p.allow_multiselect),
- mShowEmptyMessage(p.show_empty_message),
- mShowFolderHierarchy(FALSE),
- mSourceID(p.task_id),
- mRenameItem( NULL ),
- mNeedsScroll( FALSE ),
- mUseLabelSuffix(p.use_label_suffix),
- mPinningSelectedItem(FALSE),
- mNeedsAutoSelect( FALSE ),
- mAutoSelectOverride(FALSE),
- mNeedsAutoRename(FALSE),
- mDebugFilters(FALSE),
- mSortOrder(LLInventoryFilter::SO_FOLDERS_BY_NAME), // This gets overridden by a pref immediately
- mFilter( new LLInventoryFilter(p.title) ),
- mShowSelectionContext(FALSE),
- mShowSingleSelection(FALSE),
- mArrangeGeneration(0),
- mSignalSelectCallback(0),
- mMinWidth(0),
- mDragAndDropThisFrame(FALSE),
- mCallbackRegistrar(NULL),
- mParentPanel(p.parent_panel),
- mUseEllipses(p.use_ellipses),
- mDraggingOverItem(NULL),
- mStatusTextBox(NULL)
-{
- mRoot = this;
-
- mShowLoadStatus = p.show_load_status();
-
- LLRect rect = p.rect;
- LLRect new_rect(rect.mLeft, rect.mBottom + getRect().getHeight(), rect.mLeft + getRect().getWidth(), rect.mBottom);
- setRect( rect );
- reshape(rect.getWidth(), rect.getHeight());
- mIsOpen = TRUE; // this view is always open.
- mAutoOpenItems.setDepth(AUTO_OPEN_STACK_DEPTH);
- mAutoOpenCandidate = NULL;
- mAutoOpenTimer.stop();
- mKeyboardSelection = FALSE;
- mIndentation = p.folder_indentation;
- gIdleCallbacks.addFunction(idle, this);
-
- //clear label
- // go ahead and render root folder as usual
- // just make sure the label ("Inventory Folder") never shows up
- mLabel = LLStringUtil::null;
-
- // Escape is handled by reverting the rename, not commiting it (default behavior)
- LLLineEditor::Params params;
- params.name("ren");
- params.rect(rect);
- params.font(getLabelFontForStyle(LLFontGL::NORMAL));
- params.max_length.bytes(DB_INV_ITEM_NAME_STR_LEN);
- params.commit_callback.function(boost::bind(&LLFolderView::commitRename, this, _2));
- params.prevalidate_callback(&LLTextValidate::validateASCIIPrintableNoPipe);
- params.commit_on_focus_lost(true);
- params.visible(false);
- mRenamer = LLUICtrlFactory::create<LLLineEditor> (params);
- addChild(mRenamer);
-
- // Textbox
- LLTextBox::Params text_p;
- LLFontGL* font = getLabelFontForStyle(mLabelStyle);
- LLRect new_r = LLRect(rect.mLeft + ICON_PAD,
- rect.mTop - TEXT_PAD,
- rect.mRight,
- rect.mTop - TEXT_PAD - font->getLineHeight());
- text_p.rect(new_r);
- text_p.name(std::string(p.name));
- text_p.font(font);
- text_p.visible(false);
- text_p.parse_urls(true);
- text_p.wrap(true); // allow multiline text. See EXT-7564, EXT-7047
- // set text padding the same as in People panel. EXT-7047, EXT-4837
- text_p.h_pad(STATUS_TEXT_HPAD);
- text_p.v_pad(STATUS_TEXT_VPAD);
- mStatusTextBox = LLUICtrlFactory::create<LLTextBox> (text_p);
- mStatusTextBox->setFollowsLeft();
- mStatusTextBox->setFollowsTop();
- //addChild(mStatusTextBox);
-
-
- // make the popup menu available
- LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- if (!menu)
- {
- menu = LLUICtrlFactory::getDefaultWidget<LLMenuGL>("inventory_menu");
- }
- menu->setBackgroundColor(LLUIColorTable::instance().getColor("MenuPopupBgColor"));
- mPopupMenuHandle = menu->getHandle();
-
- mListener->openItem();
-}
-
-// Destroys the object
-LLFolderView::~LLFolderView( void )
-{
- closeRenamer();
-
- // The release focus call can potentially call the
- // scrollcontainer, which can potentially be called with a partly
- // destroyed scollcontainer. Just null it out here, and no worries
- // about calling into the invalid scroll container.
- // Same with the renamer.
- mScrollContainer = NULL;
- mRenameItem = NULL;
- mRenamer = NULL;
- mStatusTextBox = NULL;
-
- mAutoOpenItems.removeAllNodes();
- gIdleCallbacks.deleteFunction(idle, this);
-
- if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die();
-
- mAutoOpenItems.removeAllNodes();
- clearSelection();
- mItems.clear();
- mFolders.clear();
-
- mItemMap.clear();
-
- delete mFilter;
- mFilter = NULL;
-}
-
-BOOL LLFolderView::canFocusChildren() const
-{
- return FALSE;
-}
-
-static LLFastTimer::DeclareTimer FTM_SORT("Sort Inventory");
-
-void LLFolderView::setSortOrder(U32 order)
-{
- if (order != mSortOrder)
- {
- LLFastTimer t(FTM_SORT);
-
- mSortOrder = order;
-
- sortBy(order);
- arrangeAll();
- }
-}
-
-
-U32 LLFolderView::getSortOrder() const
-{
- return mSortOrder;
-}
-
-BOOL LLFolderView::addFolder( LLFolderViewFolder* folder)
-{
- // enforce sort order of My Inventory followed by Library
- if (folder->getListener()->getUUID() == gInventory.getLibraryRootFolderID())
- {
- mFolders.push_back(folder);
- }
- else
- {
- mFolders.insert(mFolders.begin(), folder);
- }
- folder->setShowLoadStatus(mShowLoadStatus);
- folder->setOrigin(0, 0);
- folder->reshape(getRect().getWidth(), 0);
- folder->setVisible(FALSE);
- addChild( folder );
- folder->dirtyFilter();
- folder->requestArrange();
- return TRUE;
-}
-
-void LLFolderView::closeAllFolders()
-{
- // Close all the folders
- setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_DOWN);
- arrangeAll();
-}
-
-void LLFolderView::openTopLevelFolders()
-{
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- (*fit)->setOpen(TRUE);
- }
-}
-
-void LLFolderView::setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse)
-{
- // call base class to do proper recursion
- LLFolderViewFolder::setOpenArrangeRecursively(openitem, recurse);
- // make sure root folder is always open
- mIsOpen = TRUE;
-}
-
-static LLFastTimer::DeclareTimer FTM_ARRANGE("Arrange");
-
-// This view grows and shrinks to enclose all of its children items and folders.
-S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_generation )
-{
- if (getListener()->getUUID().notNull())
- {
- if (mNeedsSort)
- {
- mFolders.sort(mSortFunction);
- mItems.sort(mSortFunction);
- mNeedsSort = false;
- }
- }
-
- LLFastTimer t2(FTM_ARRANGE);
-
- filter_generation = mFilter->getMinRequiredGeneration();
- mMinWidth = 0;
-
- mHasVisibleChildren = hasFilteredDescendants(filter_generation);
- // arrange always finishes, so optimistically set the arrange generation to the most current
- mLastArrangeGeneration = getRoot()->getArrangeGeneration();
-
- LLInventoryFilter::EFolderShow show_folder_state =
- getRoot()->getFilter()->getShowFolderState();
-
- S32 total_width = LEFT_PAD;
- S32 running_height = mDebugFilters ? LLFontGL::getFontMonospace()->getLineHeight() : 0;
- S32 target_height = running_height;
- S32 parent_item_height = getRect().getHeight();
-
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- LLFolderViewFolder* folderp = (*fit);
- if (getDebugFilters())
- {
- folderp->setVisible(TRUE);
- }
- else
- {
- folderp->setVisible((show_folder_state == LLInventoryFilter::SHOW_ALL_FOLDERS || // always show folders?
- (folderp->getFiltered(filter_generation) || folderp->hasFilteredDescendants(filter_generation))));
- }
-
- if (folderp->getVisible())
- {
- S32 child_height = 0;
- S32 child_width = 0;
- S32 child_top = parent_item_height - running_height;
-
- target_height += folderp->arrange( &child_width, &child_height, filter_generation );
-
- mMinWidth = llmax(mMinWidth, child_width);
- total_width = llmax( total_width, child_width );
- running_height += child_height;
- folderp->setOrigin( ICON_PAD, child_top - (*fit)->getRect().getHeight() );
- }
- }
-
- for (items_t::iterator iter = mItems.begin();
- iter != mItems.end();)
- {
- items_t::iterator iit = iter++;
- LLFolderViewItem* itemp = (*iit);
- itemp->setVisible(itemp->getFiltered(filter_generation));
-
- if (itemp->getVisible())
- {
- S32 child_width = 0;
- S32 child_height = 0;
- S32 child_top = parent_item_height - running_height;
-
- target_height += itemp->arrange( &child_width, &child_height, filter_generation );
- itemp->reshape(itemp->getRect().getWidth(), child_height);
-
- mMinWidth = llmax(mMinWidth, child_width);
- total_width = llmax( total_width, child_width );
- running_height += child_height;
- itemp->setOrigin( ICON_PAD, child_top - itemp->getRect().getHeight() );
- }
- }
-
- if(!mHasVisibleChildren)// is there any filtered items ?
- {
- //Nope. We need to display status textbox, let's reserve some place for it
- running_height = mStatusTextBox->getTextPixelHeight();
- target_height = running_height;
- }
-
- mRunningHeight = running_height;
- LLRect scroll_rect = mScrollContainer->getContentWindowRect();
- reshape( llmax(scroll_rect.getWidth(), total_width), running_height );
-
- LLRect new_scroll_rect = mScrollContainer->getContentWindowRect();
- if (new_scroll_rect.getWidth() != scroll_rect.getWidth())
- {
- reshape( llmax(scroll_rect.getWidth(), total_width), running_height );
- }
-
- // move item renamer text field to item's new position
- updateRenamerPosition();
-
- mTargetHeight = (F32)target_height;
- return llround(mTargetHeight);
-}
-
-const std::string LLFolderView::getFilterSubString(BOOL trim)
-{
- return mFilter->getFilterSubString(trim);
-}
-
-static LLFastTimer::DeclareTimer FTM_FILTER("Filter Inventory");
-
-void LLFolderView::filter( LLInventoryFilter& filter )
-{
- LLFastTimer t2(FTM_FILTER);
- filter.setFilterCount(llclamp(gSavedSettings.getS32("FilterItemsPerFrame"), 1, 5000));
-
- if (getCompletedFilterGeneration() < filter.getCurrentGeneration())
- {
- mPassedFilter = FALSE;
- mMinWidth = 0;
- LLFolderViewFolder::filter(filter);
- }
- else
- {
- mPassedFilter = TRUE;
- }
-}
-
-void LLFolderView::reshape(S32 width, S32 height, BOOL called_from_parent)
-{
- LLRect scroll_rect;
- if (mScrollContainer)
- {
- LLView::reshape(width, height, called_from_parent);
- scroll_rect = mScrollContainer->getContentWindowRect();
- }
- width = llmax(mMinWidth, scroll_rect.getWidth());
- height = llmax(mRunningHeight, scroll_rect.getHeight());
-
- // Restrict width within scroll container's width
- if (mUseEllipses && mScrollContainer)
- {
- width = scroll_rect.getWidth();
- }
-
- LLView::reshape(width, height, called_from_parent);
- mReshapeSignal(mSelectedItems, FALSE);
-}
-
-void LLFolderView::addToSelectionList(LLFolderViewItem* item)
-{
- if (item->isSelected())
- {
- removeFromSelectionList(item);
- }
- if (mSelectedItems.size())
- {
- mSelectedItems.back()->setIsCurSelection(FALSE);
- }
- item->setIsCurSelection(TRUE);
- mSelectedItems.push_back(item);
-}
-
-void LLFolderView::removeFromSelectionList(LLFolderViewItem* item)
-{
- if (mSelectedItems.size())
- {
- mSelectedItems.back()->setIsCurSelection(FALSE);
- }
-
- selected_items_t::iterator item_iter;
- for (item_iter = mSelectedItems.begin(); item_iter != mSelectedItems.end();)
- {
- if (*item_iter == item)
- {
- item_iter = mSelectedItems.erase(item_iter);
- }
- else
- {
- ++item_iter;
- }
- }
- if (mSelectedItems.size())
- {
- mSelectedItems.back()->setIsCurSelection(TRUE);
- }
-}
-
-LLFolderViewItem* LLFolderView::getCurSelectedItem( void )
-{
- if(mSelectedItems.size())
- {
- LLFolderViewItem* itemp = mSelectedItems.back();
- llassert(itemp->getIsCurSelection());
- return itemp;
- }
- return NULL;
-}
-
-
-// Record the selected item and pass it down the hierachy.
-BOOL LLFolderView::setSelection(LLFolderViewItem* selection, BOOL openitem,
- BOOL take_keyboard_focus)
-{
- mSignalSelectCallback = take_keyboard_focus ? SIGNAL_KEYBOARD_FOCUS : SIGNAL_NO_KEYBOARD_FOCUS;
-
- if( selection == this )
- {
- return FALSE;
- }
-
- if( selection && take_keyboard_focus)
- {
- mParentPanel->setFocus(TRUE);
- }
-
- // clear selection down here because change of keyboard focus can potentially
- // affect selection
- clearSelection();
-
- if(selection)
- {
- addToSelectionList(selection);
- }
-
- BOOL rv = LLFolderViewFolder::setSelection(selection, openitem, take_keyboard_focus);
- if(openitem && selection)
- {
- selection->getParentFolder()->requestArrange();
- }
-
- llassert(mSelectedItems.size() <= 1);
-
- return rv;
-}
-
-void LLFolderView::setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus)
-{
- LLFolderViewItem* itemp = getItemByID(obj_id);
- if(itemp && itemp->getListener())
- {
- itemp->arrangeAndSet(TRUE, take_keyboard_focus);
- mSelectThisID.setNull();
- return;
- }
- else
- {
- // save the desired item to be selected later (if/when ready)
- mSelectThisID = obj_id;
- }
-}
-
-void LLFolderView::updateSelection()
-{
- if (mSelectThisID.notNull())
- {
- setSelectionByID(mSelectThisID, false);
- }
-}
-
-BOOL LLFolderView::changeSelection(LLFolderViewItem* selection, BOOL selected)
-{
- BOOL rv = FALSE;
-
- // can't select root folder
- if(!selection || selection == this)
- {
- return FALSE;
- }
-
- if (!mAllowMultiSelect)
- {
- clearSelection();
- }
-
- selected_items_t::iterator item_iter;
- for (item_iter = mSelectedItems.begin(); item_iter != mSelectedItems.end(); ++item_iter)
- {
- if (*item_iter == selection)
- {
- break;
- }
- }
-
- BOOL on_list = (item_iter != mSelectedItems.end());
-
- if(selected && !on_list)
- {
- addToSelectionList(selection);
- }
- if(!selected && on_list)
- {
- removeFromSelectionList(selection);
- }
-
- rv = LLFolderViewFolder::changeSelection(selection, selected);
-
- mSignalSelectCallback = SIGNAL_KEYBOARD_FOCUS;
-
- return rv;
-}
-
-static LLFastTimer::DeclareTimer FTM_SANITIZE_SELECTION("Sanitize Selection");
-void LLFolderView::sanitizeSelection()
-{
- LLFastTimer _(FTM_SANITIZE_SELECTION);
- // store off current item in case it is automatically deselected
- // and we want to preserve context
- LLFolderViewItem* original_selected_item = getCurSelectedItem();
-
- // Cache "Show all folders" filter setting
- BOOL show_all_folders = (getRoot()->getFilter()->getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS);
-
- std::vector<LLFolderViewItem*> items_to_remove;
- selected_items_t::iterator item_iter;
- for (item_iter = mSelectedItems.begin(); item_iter != mSelectedItems.end(); ++item_iter)
- {
- LLFolderViewItem* item = *item_iter;
-
- // ensure that each ancestor is open and potentially passes filtering
- BOOL visible = item->potentiallyVisible(); // initialize from filter state for this item
- // modify with parent open and filters states
- LLFolderViewFolder* parent_folder = item->getParentFolder();
- if ( parent_folder )
- {
- if ( show_all_folders )
- { // "Show all folders" is on, so this folder is visible
- visible = TRUE;
- }
- else
- { // Move up through parent folders and see what's visible
- while(parent_folder)
- {
- visible = visible && parent_folder->isOpen() && parent_folder->potentiallyVisible();
- parent_folder = parent_folder->getParentFolder();
- }
- }
- }
-
- // deselect item if any ancestor is closed or didn't pass filter requirements.
- if (!visible)
- {
- items_to_remove.push_back(item);
- }
-
- // disallow nested selections (i.e. folder items plus one or more ancestors)
- // could check cached mum selections count and only iterate if there are any
- // but that may be a premature optimization.
- selected_items_t::iterator other_item_iter;
- for (other_item_iter = mSelectedItems.begin(); other_item_iter != mSelectedItems.end(); ++other_item_iter)
- {
- LLFolderViewItem* other_item = *other_item_iter;
- for( parent_folder = other_item->getParentFolder(); parent_folder; parent_folder = parent_folder->getParentFolder())
- {
- if (parent_folder == item)
- {
- // this is a descendent of the current folder, remove from list
- items_to_remove.push_back(other_item);
- break;
- }
- }
- }
-
- // Don't allow invisible items (such as root folders) to be selected.
- if (item == getRoot())
- {
- items_to_remove.push_back(item);
- }
- }
-
- std::vector<LLFolderViewItem*>::iterator item_it;
- for (item_it = items_to_remove.begin(); item_it != items_to_remove.end(); ++item_it )
- {
- changeSelection(*item_it, FALSE); // toggle selection (also removes from list)
- }
-
- // if nothing selected after prior constraints...
- if (mSelectedItems.empty())
- {
- // ...select first available parent of original selection
- LLFolderViewItem* new_selection = NULL;
- if (original_selected_item)
- {
- for(LLFolderViewFolder* parent_folder = original_selected_item->getParentFolder();
- parent_folder;
- parent_folder = parent_folder->getParentFolder())
- {
- if (parent_folder->potentiallyVisible())
- {
- // give initial selection to first ancestor folder that potentially passes the filter
- if (!new_selection)
- {
- new_selection = parent_folder;
- }
-
- // if any ancestor folder of original item is closed, move the selection up
- // to the highest closed
- if (!parent_folder->isOpen())
- {
- new_selection = parent_folder;
- }
- }
- }
- }
- else
- {
- new_selection = NULL;
- }
-
- if (new_selection)
- {
- setSelection(new_selection, FALSE, FALSE);
- }
- }
-}
-
-void LLFolderView::clearSelection()
-{
- for (selected_items_t::const_iterator item_it = mSelectedItems.begin();
- item_it != mSelectedItems.end();
- ++item_it)
- {
- (*item_it)->setUnselected();
- }
-
- mSelectedItems.clear();
- mSelectThisID.setNull();
-}
-
-std::set<LLUUID> LLFolderView::getSelectionList() const
-{
- std::set<LLUUID> selection;
- for (selected_items_t::const_iterator item_it = mSelectedItems.begin();
- item_it != mSelectedItems.end();
- ++item_it)
- {
- selection.insert((*item_it)->getListener()->getUUID());
- }
- return selection;
-}
-
-BOOL LLFolderView::startDrag(LLToolDragAndDrop::ESource source)
-{
- std::vector<EDragAndDropType> types;
- uuid_vec_t cargo_ids;
- selected_items_t::iterator item_it;
- BOOL can_drag = TRUE;
- if (!mSelectedItems.empty())
- {
- for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
- {
- EDragAndDropType type = DAD_NONE;
- LLUUID id = LLUUID::null;
- can_drag = can_drag && (*item_it)->getListener()->startDrag(&type, &id);
-
- types.push_back(type);
- cargo_ids.push_back(id);
- }
-
- LLToolDragAndDrop::getInstance()->beginMultiDrag(types, cargo_ids, source, mSourceID);
- }
- return can_drag;
-}
-
-void LLFolderView::commitRename( const LLSD& data )
-{
- finishRenamingItem();
-}
-
-void LLFolderView::draw()
-{
- static LLUIColor sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", LLColor4::white);
- if (mDebugFilters)
- {
- std::string current_filter_string = llformat("Current Filter: %d, Least Filter: %d, Auto-accept Filter: %d",
- mFilter->getCurrentGeneration(), mFilter->getMinRequiredGeneration(), mFilter->getMustPassGeneration());
- 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 );
- }
-
- //LLFontGL* font = getLabelFontForStyle(mLabelStyle);
-
- // if cursor has moved off of me during drag and drop
- // close all auto opened folders
- if (!mDragAndDropThisFrame)
- {
- closeAutoOpenedFolders();
- }
-
- // while dragging, update selection rendering to reflect single/multi drag status
- if (LLToolDragAndDrop::getInstance()->hasMouseCapture())
- {
- EAcceptance last_accept = LLToolDragAndDrop::getInstance()->getLastAccept();
- if (last_accept == ACCEPT_YES_SINGLE || last_accept == ACCEPT_YES_COPY_SINGLE)
- {
- setShowSingleSelection(TRUE);
- }
- else
- {
- setShowSingleSelection(FALSE);
- }
- }
- else
- {
- setShowSingleSelection(FALSE);
- }
-
-
- if (mSearchTimer.getElapsedTimeF32() > gSavedSettings.getF32("TypeAheadTimeout") || !mSearchString.size())
- {
- mSearchString.clear();
- }
-
- if (hasVisibleChildren()
- || mFilter->getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS)
- {
- mStatusText.clear();
- mStatusTextBox->setVisible( FALSE );
- }
- else if (mShowEmptyMessage)
- {
- if (LLInventoryModelBackgroundFetch::instance().folderFetchActive() || mCompletedFilterGeneration < mFilter->getMinRequiredGeneration())
- {
- mStatusText = LLTrans::getString("Searching");
- }
- else
- {
- if (getFilter())
- {
- LLStringUtil::format_map_t args;
- args["[SEARCH_TERM]"] = LLURI::escape(getFilter()->getFilterSubStringOrig());
- mStatusText = LLTrans::getString(getFilter()->getEmptyLookupMessage(), args);
- }
- }
- mStatusTextBox->setValue(mStatusText);
- mStatusTextBox->setVisible( TRUE );
-
- // firstly reshape message textbox with current size. This is necessary to
- // LLTextBox::getTextPixelHeight works properly
- const LLRect local_rect = getLocalRect();
- mStatusTextBox->setShape(local_rect);
-
- // get preferable text height...
- S32 pixel_height = mStatusTextBox->getTextPixelHeight();
- bool height_changed = local_rect.getHeight() != pixel_height;
- if (height_changed)
- {
- // ... if it does not match current height, lets rearrange current view.
- // This will indirectly call ::arrange and reshape of the status textbox.
- // We should call this method to also notify parent about required rect.
- // See EXT-7564, EXT-7047.
- arrangeFromRoot();
- LLUI::popMatrix();
- LLUI::pushMatrix();
- LLUI::translate((F32)getRect().mLeft, (F32)getRect().mBottom);
- }
- }
-
- // skip over LLFolderViewFolder::draw since we don't want the folder icon, label,
- // and arrow for the root folder
- LLView::draw();
-
- mDragAndDropThisFrame = FALSE;
-}
-
-void LLFolderView::finishRenamingItem( void )
-{
- if(!mRenamer)
- {
- return;
- }
- if( mRenameItem )
- {
- mRenameItem->rename( mRenamer->getText() );
- }
-
- closeRenamer();
-
- // List is re-sorted alphabeticly, so scroll to make sure the selected item is visible.
- scrollToShowSelection();
-}
-
-void LLFolderView::closeRenamer( void )
-{
- if (mRenamer && mRenamer->getVisible())
- {
- // Triggers onRenamerLost() that actually closes the renamer.
- gViewerWindow->removePopup(mRenamer);
- }
-}
-
-void LLFolderView::removeSelectedItems( void )
-{
- if (mSelectedItems.empty()) return;
- LLSD args;
- args["QUESTION"] = LLTrans::getString(mSelectedItems.size() > 1 ? "DeleteItems" : "DeleteItem");
- LLNotificationsUtil::add("DeleteItems", args, LLSD(), boost::bind(&LLFolderView::onItemsRemovalConfirmation, this, _1, _2));
-}
-
-bool isDescendantOfASelectedItem(LLFolderViewItem* item, const std::vector<LLFolderViewItem*>& selectedItems)
-{
- LLFolderViewItem* item_parent = dynamic_cast<LLFolderViewItem*>(item->getParent());
-
- if (item_parent)
- {
- for(std::vector<LLFolderViewItem*>::const_iterator it = selectedItems.begin(); it != selectedItems.end(); ++it)
- {
- const LLFolderViewItem* const selected_item = (*it);
-
- LLFolderViewItem* parent = item_parent;
-
- while (parent)
- {
- if (selected_item == parent)
- {
- return true;
- }
-
- parent = dynamic_cast<LLFolderViewItem*>(parent->getParent());
- }
- }
- }
-
- return false;
-}
-
-// static
-void LLFolderView::removeCutItems()
-{
- // There's no item in "cut" mode on the clipboard -> exit
- if (!LLClipboard::instance().isCutMode())
- return;
-
- // Get the list of clipboard item uuids and iterate through them
- LLDynamicArray<LLUUID> objects;
- LLClipboard::instance().pasteFromClipboard(objects);
- for (LLDynamicArray<LLUUID>::const_iterator iter = objects.begin();
- iter != objects.end();
- ++iter)
- {
- gInventory.removeObject(*iter);
- }
-}
-
-void LLFolderView::onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if (option != 0) return; // canceled
-
- if(getVisible() && getEnabled())
- {
- // just in case we're removing the renaming item.
- mRenameItem = NULL;
-
- // create a temporary structure which we will use to remove
- // items, since the removal will futz with internal data
- // structures.
- std::vector<LLFolderViewItem*> items;
- S32 count = mSelectedItems.size();
- if(count == 0) return;
- LLFolderViewItem* item = NULL;
- selected_items_t::iterator item_it;
- for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
- {
- item = *item_it;
- if (item && item->isRemovable())
- {
- items.push_back(item);
- }
- else
- {
- llinfos << "Cannot delete " << item->getName() << llendl;
- return;
- }
- }
-
- // iterate through the new container.
- count = items.size();
- LLUUID new_selection_id;
- if(count == 1)
- {
- LLFolderViewItem* item_to_delete = items[0];
- LLFolderViewFolder* parent = item_to_delete->getParentFolder();
- LLFolderViewItem* new_selection = item_to_delete->getNextOpenNode(FALSE);
- if (!new_selection)
- {
- new_selection = item_to_delete->getPreviousOpenNode(FALSE);
- }
- if(parent)
- {
- if (parent->removeItem(item_to_delete))
- {
- // change selection on successful delete
- if (new_selection)
- {
- setSelectionFromRoot(new_selection, new_selection->isOpen(), mParentPanel->hasFocus());
- }
- else
- {
- setSelectionFromRoot(NULL, mParentPanel->hasFocus());
- }
- }
- }
- arrangeAll();
- }
- else if (count > 1)
- {
- LLDynamicArray<LLFolderViewEventListener*> listeners;
- LLFolderViewEventListener* listener;
- LLFolderViewItem* last_item = items[count - 1];
- LLFolderViewItem* new_selection = last_item->getNextOpenNode(FALSE);
- while(new_selection && new_selection->isSelected())
- {
- new_selection = new_selection->getNextOpenNode(FALSE);
- }
- if (!new_selection)
- {
- new_selection = last_item->getPreviousOpenNode(FALSE);
- while (new_selection && (new_selection->isSelected() || isDescendantOfASelectedItem(new_selection, items)))
- {
- new_selection = new_selection->getPreviousOpenNode(FALSE);
- }
- }
- if (new_selection)
- {
- setSelectionFromRoot(new_selection, new_selection->isOpen(), mParentPanel->hasFocus());
- }
- else
- {
- setSelectionFromRoot(NULL, mParentPanel->hasFocus());
- }
-
- for(S32 i = 0; i < count; ++i)
- {
- listener = items[i]->getListener();
- if(listener && (listeners.find(listener) == LLDynamicArray<LLFolderViewEventListener*>::FAIL))
- {
- listeners.put(listener);
- }
- }
- listener = listeners.get(0);
- if(listener)
- {
- listener->removeBatch(listeners);
- }
- }
- arrangeAll();
- scrollToShowSelection();
- }
-}
-
-// open the selected item.
-void LLFolderView::openSelectedItems( void )
-{
- if(getVisible() && getEnabled())
- {
- if (mSelectedItems.size() == 1)
- {
- mSelectedItems.front()->openItem();
- }
- else
- {
- LLMultiPreview* multi_previewp = new LLMultiPreview();
- LLMultiProperties* multi_propertiesp = new LLMultiProperties();
-
- selected_items_t::iterator item_it;
- for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
- {
- // IT_{OBJECT,ATTACHMENT} creates LLProperties
- // floaters; others create LLPreviews. Put
- // each one in the right type of container.
- LLFolderViewEventListener* listener = (*item_it)->getListener();
- bool is_prop = listener && (listener->getInventoryType() == LLInventoryType::IT_OBJECT || listener->getInventoryType() == LLInventoryType::IT_ATTACHMENT);
- if (is_prop)
- LLFloater::setFloaterHost(multi_propertiesp);
- else
- LLFloater::setFloaterHost(multi_previewp);
- (*item_it)->openItem();
- }
-
- LLFloater::setFloaterHost(NULL);
- // *NOTE: LLMulti* will safely auto-delete when open'd
- // without any children.
- multi_previewp->openFloater(LLSD());
- multi_propertiesp->openFloater(LLSD());
- }
- }
-}
-
-void LLFolderView::propertiesSelectedItems( void )
-{
- if(getVisible() && getEnabled())
- {
- if (mSelectedItems.size() == 1)
- {
- LLFolderViewItem* folder_item = mSelectedItems.front();
- if(!folder_item) return;
- folder_item->getListener()->showProperties();
- }
- else
- {
- LLMultiProperties* multi_propertiesp = new LLMultiProperties();
-
- LLFloater::setFloaterHost(multi_propertiesp);
-
- selected_items_t::iterator item_it;
- for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
- {
- (*item_it)->getListener()->showProperties();
- }
-
- LLFloater::setFloaterHost(NULL);
- multi_propertiesp->openFloater(LLSD());
- }
- }
-}
-
-void LLFolderView::changeType(LLInventoryModel *model, LLFolderType::EType new_folder_type)
-{
- LLFolderBridge *folder_bridge = LLFolderBridge::sSelf.get();
-
- if (!folder_bridge) return;
- LLViewerInventoryCategory *cat = folder_bridge->getCategory();
- if (!cat) return;
- cat->changeType(new_folder_type);
-}
-
-void LLFolderView::autoOpenItem( LLFolderViewFolder* item )
-{
- if ((mAutoOpenItems.check() == item) ||
- (mAutoOpenItems.getDepth() >= (U32)AUTO_OPEN_STACK_DEPTH) ||
- item->isOpen())
- {
- return;
- }
-
- // close auto-opened folders
- LLFolderViewFolder* close_item = mAutoOpenItems.check();
- while (close_item && close_item != item->getParentFolder())
- {
- mAutoOpenItems.pop();
- close_item->setOpenArrangeRecursively(FALSE);
- close_item = mAutoOpenItems.check();
- }
-
- item->requestArrange();
-
- mAutoOpenItems.push(item);
-
- item->setOpen(TRUE);
- LLRect content_rect = mScrollContainer->getContentWindowRect();
- LLRect constraint_rect(0,content_rect.getHeight(), content_rect.getWidth(), 0);
- scrollToShowItem(item, constraint_rect);
-}
-
-void LLFolderView::closeAutoOpenedFolders()
-{
- while (mAutoOpenItems.check())
- {
- LLFolderViewFolder* close_item = mAutoOpenItems.pop();
- close_item->setOpen(FALSE);
- }
-
- if (mAutoOpenCandidate)
- {
- mAutoOpenCandidate->setAutoOpenCountdown(0.f);
- }
- mAutoOpenCandidate = NULL;
- mAutoOpenTimer.stop();
-}
-
-BOOL LLFolderView::autoOpenTest(LLFolderViewFolder* folder)
-{
- if (folder && mAutoOpenCandidate == folder)
- {
- if (mAutoOpenTimer.getStarted())
- {
- if (!mAutoOpenCandidate->isOpen())
- {
- mAutoOpenCandidate->setAutoOpenCountdown(clamp_rescale(mAutoOpenTimer.getElapsedTimeF32(), 0.f, sAutoOpenTime, 0.f, 1.f));
- }
- if (mAutoOpenTimer.getElapsedTimeF32() > sAutoOpenTime)
- {
- autoOpenItem(folder);
- mAutoOpenTimer.stop();
- return TRUE;
- }
- }
- return FALSE;
- }
-
- // otherwise new candidate, restart timer
- if (mAutoOpenCandidate)
- {
- mAutoOpenCandidate->setAutoOpenCountdown(0.f);
- }
- mAutoOpenCandidate = folder;
- mAutoOpenTimer.start();
- return FALSE;
-}
-
-BOOL LLFolderView::canCopy() const
-{
- if (!(getVisible() && getEnabled() && (mSelectedItems.size() > 0)))
- {
- return FALSE;
- }
-
- for (selected_items_t::const_iterator selected_it = mSelectedItems.begin(); selected_it != mSelectedItems.end(); ++selected_it)
- {
- const LLFolderViewItem* item = *selected_it;
- if (!item->getListener()->isItemCopyable())
- {
- return FALSE;
- }
- }
- return TRUE;
-}
-
-// copy selected item
-void LLFolderView::copy()
-{
- // *NOTE: total hack to clear the inventory clipboard
- LLClipboard::instance().reset();
- S32 count = mSelectedItems.size();
- if(getVisible() && getEnabled() && (count > 0))
- {
- LLFolderViewEventListener* listener = NULL;
- selected_items_t::iterator item_it;
- for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
- {
- listener = (*item_it)->getListener();
- if(listener)
- {
- listener->copyToClipboard();
- }
- }
- }
- mSearchString.clear();
-}
-
-BOOL LLFolderView::canCut() const
-{
- if (!(getVisible() && getEnabled() && (mSelectedItems.size() > 0)))
- {
- return FALSE;
- }
-
- for (selected_items_t::const_iterator selected_it = mSelectedItems.begin(); selected_it != mSelectedItems.end(); ++selected_it)
- {
- const LLFolderViewItem* item = *selected_it;
- const LLFolderViewEventListener* listener = item->getListener();
-
- if (!listener || !listener->isItemRemovable())
- {
- return FALSE;
- }
- }
- return TRUE;
-}
-
-void LLFolderView::cut()
-{
- // clear the inventory clipboard
- LLClipboard::instance().reset();
- S32 count = mSelectedItems.size();
- if(getVisible() && getEnabled() && (count > 0))
- {
- LLFolderViewEventListener* listener = NULL;
- selected_items_t::iterator item_it;
- for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
- {
- listener = (*item_it)->getListener();
- if(listener)
- {
- listener->cutToClipboard();
- }
- }
- LLFolderView::removeCutItems();
- }
- mSearchString.clear();
-}
-
-BOOL LLFolderView::canPaste() const
-{
- if (mSelectedItems.empty())
- {
- return FALSE;
- }
-
- if(getVisible() && getEnabled())
- {
- for (selected_items_t::const_iterator item_it = mSelectedItems.begin();
- item_it != mSelectedItems.end(); ++item_it)
- {
- // *TODO: only check folders and parent folders of items
- const LLFolderViewItem* item = (*item_it);
- const LLFolderViewEventListener* listener = item->getListener();
- if(!listener || !listener->isClipboardPasteable())
- {
- const LLFolderViewFolder* folderp = item->getParentFolder();
- listener = folderp->getListener();
- if (!listener || !listener->isClipboardPasteable())
- {
- return FALSE;
- }
- }
- }
- return TRUE;
- }
- return FALSE;
-}
-
-// paste selected item
-void LLFolderView::paste()
-{
- if(getVisible() && getEnabled())
- {
- // find set of unique folders to paste into
- std::set<LLFolderViewItem*> folder_set;
-
- selected_items_t::iterator selected_it;
- for (selected_it = mSelectedItems.begin(); selected_it != mSelectedItems.end(); ++selected_it)
- {
- LLFolderViewItem* item = *selected_it;
- LLFolderViewEventListener* listener = item->getListener();
- if (listener->getInventoryType() != LLInventoryType::IT_CATEGORY)
- {
- item = item->getParentFolder();
- }
- folder_set.insert(item);
- }
-
- std::set<LLFolderViewItem*>::iterator set_iter;
- for(set_iter = folder_set.begin(); set_iter != folder_set.end(); ++set_iter)
- {
- LLFolderViewEventListener* listener = (*set_iter)->getListener();
- if(listener && listener->isClipboardPasteable())
- {
- listener->pasteFromClipboard();
- }
- }
- }
- mSearchString.clear();
-}
-
-// public rename functionality - can only start the process
-void LLFolderView::startRenamingSelectedItem( void )
-{
- // make sure selection is visible
- scrollToShowSelection();
-
- S32 count = mSelectedItems.size();
- LLFolderViewItem* item = NULL;
- if(count > 0)
- {
- item = mSelectedItems.front();
- }
- if(getVisible() && getEnabled() && (count == 1) && item && item->getListener() &&
- item->getListener()->isItemRenameable())
- {
- mRenameItem = item;
-
- updateRenamerPosition();
-
-
- mRenamer->setText(item->getName());
- mRenamer->selectAll();
- mRenamer->setVisible( TRUE );
- // set focus will fail unless item is visible
- mRenamer->setFocus( TRUE );
- mRenamer->setTopLostCallback(boost::bind(&LLFolderView::onRenamerLost, this));
- gViewerWindow->addPopup(mRenamer);
- }
-}
-
-BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
-{
- BOOL handled = FALSE;
-
- // SL-51858: Key presses are not being passed to the Popup menu.
- // A proper fix is non-trivial so instead just close the menu.
- LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
- if (menu && menu->isOpen())
- {
- LLMenuGL::sMenuContainer->hideMenus();
- }
-
- LLView *item = NULL;
- if (getChildCount() > 0)
- {
- item = *(getChildList()->begin());
- }
-
- switch( key )
- {
- case KEY_F2:
- mSearchString.clear();
- startRenamingSelectedItem();
- handled = TRUE;
- break;
-
- case KEY_RETURN:
- if (mask == MASK_NONE)
- {
- if( mRenameItem && mRenamer->getVisible() )
- {
- finishRenamingItem();
- mSearchString.clear();
- handled = TRUE;
- }
- else
- {
- LLFolderView::openSelectedItems();
- handled = TRUE;
- }
- }
- break;
-
- case KEY_ESCAPE:
- if( mRenameItem && mRenamer->getVisible() )
- {
- closeRenamer();
- handled = TRUE;
- }
- mSearchString.clear();
- break;
-
- case KEY_PAGE_UP:
- mSearchString.clear();
- mScrollContainer->pageUp(30);
- handled = TRUE;
- break;
-
- case KEY_PAGE_DOWN:
- mSearchString.clear();
- mScrollContainer->pageDown(30);
- handled = TRUE;
- break;
-
- case KEY_HOME:
- mSearchString.clear();
- mScrollContainer->goToTop();
- handled = TRUE;
- break;
-
- case KEY_END:
- mSearchString.clear();
- mScrollContainer->goToBottom();
- break;
-
- case KEY_DOWN:
- if((mSelectedItems.size() > 0) && mScrollContainer)
- {
- LLFolderViewItem* last_selected = getCurSelectedItem();
-
- if (!mKeyboardSelection)
- {
- setSelection(last_selected, FALSE, TRUE);
- mKeyboardSelection = TRUE;
- }
-
- LLFolderViewItem* next = NULL;
- if (mask & MASK_SHIFT)
- {
- // don't shift select down to children of folders (they are implicitly selected through parent)
- next = last_selected->getNextOpenNode(FALSE);
- if (next)
- {
- if (next->isSelected())
- {
- // shrink selection
- changeSelectionFromRoot(last_selected, FALSE);
- }
- else if (last_selected->getParentFolder() == next->getParentFolder())
- {
- // grow selection
- changeSelectionFromRoot(next, TRUE);
- }
- }
- }
- else
- {
- next = last_selected->getNextOpenNode();
- if( next )
- {
- if (next == last_selected)
- {
- //special case for LLAccordionCtrl
- if(notifyParent(LLSD().with("action","select_next")) > 0 )//message was processed
- {
- clearSelection();
- return TRUE;
- }
- return FALSE;
- }
- setSelection( next, FALSE, TRUE );
- }
- else
- {
- //special case for LLAccordionCtrl
- if(notifyParent(LLSD().with("action","select_next")) > 0 )//message was processed
- {
- clearSelection();
- return TRUE;
- }
- return FALSE;
- }
- }
- scrollToShowSelection();
- mSearchString.clear();
- handled = TRUE;
- }
- break;
-
- case KEY_UP:
- if((mSelectedItems.size() > 0) && mScrollContainer)
- {
- LLFolderViewItem* last_selected = mSelectedItems.back();
-
- if (!mKeyboardSelection)
- {
- setSelection(last_selected, FALSE, TRUE);
- mKeyboardSelection = TRUE;
- }
-
- LLFolderViewItem* prev = NULL;
- if (mask & MASK_SHIFT)
- {
- // don't shift select down to children of folders (they are implicitly selected through parent)
- prev = last_selected->getPreviousOpenNode(FALSE);
- if (prev)
- {
- if (prev->isSelected())
- {
- // shrink selection
- changeSelectionFromRoot(last_selected, FALSE);
- }
- else if (last_selected->getParentFolder() == prev->getParentFolder())
- {
- // grow selection
- changeSelectionFromRoot(prev, TRUE);
- }
- }
- }
- else
- {
- prev = last_selected->getPreviousOpenNode();
- if( prev )
- {
- if (prev == this)
- {
- // If case we are in accordion tab notify parent to go to the previous accordion
- if(notifyParent(LLSD().with("action","select_prev")) > 0 )//message was processed
- {
- clearSelection();
- return TRUE;
- }
-
- return FALSE;
- }
- setSelection( prev, FALSE, TRUE );
- }
- }
- scrollToShowSelection();
- mSearchString.clear();
-
- handled = TRUE;
- }
- break;
-
- case KEY_RIGHT:
- if(mSelectedItems.size())
- {
- LLFolderViewItem* last_selected = getCurSelectedItem();
- last_selected->setOpen( TRUE );
- mSearchString.clear();
- handled = TRUE;
- }
- break;
-
- case KEY_LEFT:
- if(mSelectedItems.size())
- {
- LLFolderViewItem* last_selected = getCurSelectedItem();
- LLFolderViewItem* parent_folder = last_selected->getParentFolder();
- if (!last_selected->isOpen() && parent_folder && parent_folder->getParentFolder())
- {
- setSelection(parent_folder, FALSE, TRUE);
- }
- else
- {
- last_selected->setOpen( FALSE );
- }
- mSearchString.clear();
- scrollToShowSelection();
- handled = TRUE;
- }
- break;
- }
-
- if (!handled && mParentPanel->hasFocus())
- {
- if (key == KEY_BACKSPACE)
- {
- mSearchTimer.reset();
- if (mSearchString.size())
- {
- mSearchString.erase(mSearchString.size() - 1, 1);
- }
- search(getCurSelectedItem(), mSearchString, FALSE);
- handled = TRUE;
- }
- }
-
- return handled;
-}
-
-
-BOOL LLFolderView::handleUnicodeCharHere(llwchar uni_char)
-{
- if ((uni_char < 0x20) || (uni_char == 0x7F)) // Control character or DEL
- {
- return FALSE;
- }
-
- if (uni_char > 0x7f)
- {
- llwarns << "LLFolderView::handleUnicodeCharHere - Don't handle non-ascii yet, aborting" << llendl;
- return FALSE;
- }
-
- BOOL handled = FALSE;
- if (mParentPanel->hasFocus())
- {
- // SL-51858: Key presses are not being passed to the Popup menu.
- // A proper fix is non-trivial so instead just close the menu.
- LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
- if (menu && menu->isOpen())
- {
- LLMenuGL::sMenuContainer->hideMenus();
- }
-
- //do text search
- if (mSearchTimer.getElapsedTimeF32() > gSavedSettings.getF32("TypeAheadTimeout"))
- {
- mSearchString.clear();
- }
- mSearchTimer.reset();
- if (mSearchString.size() < 128)
- {
- mSearchString += uni_char;
- }
- search(getCurSelectedItem(), mSearchString, FALSE);
-
- handled = TRUE;
- }
-
- return handled;
-}
-
-
-BOOL LLFolderView::canDoDelete() const
-{
- if (mSelectedItems.size() == 0) return FALSE;
-
- for (selected_items_t::const_iterator item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
- {
- if (!(*item_it)->getListener()->isItemRemovable())
- {
- return FALSE;
- }
- }
- return TRUE;
-}
-
-void LLFolderView::doDelete()
-{
- if(mSelectedItems.size() > 0)
- {
- removeSelectedItems();
- }
-}
-
-
-BOOL LLFolderView::handleMouseDown( S32 x, S32 y, MASK mask )
-{
- mKeyboardSelection = FALSE;
- mSearchString.clear();
-
- mParentPanel->setFocus(TRUE);
-
- LLEditMenuHandler::gEditMenuHandler = this;
-
- return LLView::handleMouseDown( x, y, mask );
-}
-
-BOOL LLFolderView::search(LLFolderViewItem* first_item, const std::string &search_string, BOOL backward)
-{
- // get first selected item
- LLFolderViewItem* search_item = first_item;
-
- // make sure search string is upper case
- std::string upper_case_string = search_string;
- LLStringUtil::toUpper(upper_case_string);
-
- // if nothing selected, select first item in folder
- if (!search_item)
- {
- // start from first item
- search_item = getNextFromChild(NULL);
- }
-
- // search over all open nodes for first substring match (with wrapping)
- BOOL found = FALSE;
- LLFolderViewItem* original_search_item = search_item;
- do
- {
- // wrap at end
- if (!search_item)
- {
- if (backward)
- {
- search_item = getPreviousFromChild(NULL);
- }
- else
- {
- search_item = getNextFromChild(NULL);
- }
- if (!search_item || search_item == original_search_item)
- {
- break;
- }
- }
-
- const std::string current_item_label(search_item->getSearchableLabel());
- S32 search_string_length = llmin(upper_case_string.size(), current_item_label.size());
- if (!current_item_label.compare(0, search_string_length, upper_case_string))
- {
- found = TRUE;
- break;
- }
- if (backward)
- {
- search_item = search_item->getPreviousOpenNode();
- }
- else
- {
- search_item = search_item->getNextOpenNode();
- }
-
- } while(search_item != original_search_item);
-
-
- if (found)
- {
- setSelection(search_item, FALSE, TRUE);
- scrollToShowSelection();
- }
-
- return found;
-}
-
-BOOL LLFolderView::handleDoubleClick( S32 x, S32 y, MASK mask )
-{
- // skip LLFolderViewFolder::handleDoubleClick()
- return LLView::handleDoubleClick( x, y, mask );
-}
-
-BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask )
-{
- // all user operations move keyboard focus to inventory
- // this way, we know when to stop auto-updating a search
- mParentPanel->setFocus(TRUE);
-
- BOOL handled = childrenHandleRightMouseDown(x, y, mask) != NULL;
- S32 count = mSelectedItems.size();
- LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
- if ( handled
- && ( count > 0 && (hasVisibleChildren() || mFilter->getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS) ) // show menu only if selected items are visible
- && menu )
- {
- if (mCallbackRegistrar)
- mCallbackRegistrar->pushScope();
-
- updateMenuOptions(menu);
-
- menu->updateParent(LLMenuGL::sMenuContainer);
- LLMenuGL::showPopup(this, menu, x, y);
- if (mCallbackRegistrar)
- mCallbackRegistrar->popScope();
- }
- else
- {
- if (menu && menu->getVisible())
- {
- menu->setVisible(FALSE);
- }
- setSelection(NULL, FALSE, TRUE);
- }
- return handled;
-}
-
-// Add "--no options--" if the menu is completely blank.
-BOOL LLFolderView::addNoOptions(LLMenuGL* menu) const
-{
- const std::string nooptions_str = "--no options--";
- LLView *nooptions_item = NULL;
-
- const LLView::child_list_t *list = menu->getChildList();
- for (LLView::child_list_t::const_iterator itor = list->begin();
- itor != list->end();
- ++itor)
- {
- LLView *menu_item = (*itor);
- if (menu_item->getVisible())
- {
- return FALSE;
- }
- std::string name = menu_item->getName();
- if (menu_item->getName() == nooptions_str)
- {
- nooptions_item = menu_item;
- }
- }
- if (nooptions_item)
- {
- nooptions_item->setVisible(TRUE);
- nooptions_item->setEnabled(FALSE);
- return TRUE;
- }
- return FALSE;
-}
-
-BOOL LLFolderView::handleHover( S32 x, S32 y, MASK mask )
-{
- return LLView::handleHover( x, y, mask );
-}
-
-BOOL LLFolderView::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg)
-{
- mDragAndDropThisFrame = TRUE;
- // have children handle it first
- BOOL handled = LLView::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data,
- accept, tooltip_msg);
-
- // when drop is not handled by child, it should be handled
- // by the folder which is the hierarchy root.
- if (!handled
- && getListener()->getUUID().notNull())
- {
- handled = LLFolderViewFolder::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
- }
-
- if (handled)
- {
- lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderView" << llendl;
- }
-
- return handled;
-}
-
-void LLFolderView::deleteAllChildren()
-{
- closeRenamer();
- if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die();
- mPopupMenuHandle = LLHandle<LLView>();
- mScrollContainer = NULL;
- mRenameItem = NULL;
- mRenamer = NULL;
- mStatusTextBox = NULL;
-
- clearSelection();
- LLView::deleteAllChildren();
-}
-
-void LLFolderView::scrollToShowSelection()
-{
- if ( mSelectedItems.size() )
- {
- mNeedsScroll = TRUE;
- }
-}
-
-// If the parent is scroll container, scroll it to make the selection
-// is maximally visible.
-void LLFolderView::scrollToShowItem(LLFolderViewItem* item, const LLRect& constraint_rect)
-{
- if (!mScrollContainer) return;
-
- // don't scroll to items when mouse is being used to scroll/drag and drop
- if (gFocusMgr.childHasMouseCapture(mScrollContainer))
- {
- mNeedsScroll = FALSE;
- return;
- }
-
- // if item exists and is in visible portion of parent folder...
- if(item)
- {
- LLRect local_rect = item->getLocalRect();
- LLRect item_scrolled_rect; // item position relative to display area of scroller
- LLRect visible_doc_rect = mScrollContainer->getVisibleContentRect();
-
- S32 icon_height = mIcon.isNull() ? 0 : mIcon->getHeight();
- S32 label_height = getLabelFontForStyle(mLabelStyle)->getLineHeight();
- // when navigating with keyboard, only move top of opened folder on screen, otherwise show whole folder
- S32 max_height_to_show = item->isOpen() && mScrollContainer->hasFocus() ? (llmax( icon_height, label_height ) + ICON_PAD) : local_rect.getHeight();
-
- // get portion of item that we want to see...
- LLRect item_local_rect = LLRect(item->getIndentation(),
- local_rect.getHeight(),
- llmin(MIN_ITEM_WIDTH_VISIBLE, local_rect.getWidth()),
- llmax(0, local_rect.getHeight() - max_height_to_show));
-
- LLRect item_doc_rect;
-
- item->localRectToOtherView(item_local_rect, &item_doc_rect, this);
-
- mScrollContainer->scrollToShowRect( item_doc_rect, constraint_rect );
-
- }
-}
-
-LLRect LLFolderView::getVisibleRect()
-{
- S32 visible_height = mScrollContainer->getRect().getHeight();
- S32 visible_width = mScrollContainer->getRect().getWidth();
- LLRect visible_rect;
- visible_rect.setLeftTopAndSize(-getRect().mLeft, visible_height - getRect().mBottom, visible_width, visible_height);
- return visible_rect;
-}
-
-BOOL LLFolderView::getShowSelectionContext()
-{
- if (mShowSelectionContext)
- {
- return TRUE;
- }
- LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
- if (menu && menu->getVisible())
- {
- return TRUE;
- }
- return FALSE;
-}
-
-void LLFolderView::setShowSingleSelection(BOOL show)
-{
- if (show != mShowSingleSelection)
- {
- mMultiSelectionFadeTimer.reset();
- mShowSingleSelection = show;
- }
-}
-
-void LLFolderView::addItemID(const LLUUID& id, LLFolderViewItem* itemp)
-{
- mItemMap[id] = itemp;
-}
-
-void LLFolderView::removeItemID(const LLUUID& id)
-{
- mItemMap.erase(id);
-}
-
-LLFastTimer::DeclareTimer FTM_GET_ITEM_BY_ID("Get FolderViewItem by ID");
-LLFolderViewItem* LLFolderView::getItemByID(const LLUUID& id)
-{
- LLFastTimer _(FTM_GET_ITEM_BY_ID);
- if (id == getListener()->getUUID())
- {
- return this;
- }
-
- std::map<LLUUID, LLFolderViewItem*>::iterator map_it;
- map_it = mItemMap.find(id);
- if (map_it != mItemMap.end())
- {
- return map_it->second;
- }
-
- return NULL;
-}
-
-LLFolderViewFolder* LLFolderView::getFolderByID(const LLUUID& id)
-{
- if (id == getListener()->getUUID())
- {
- return this;
- }
-
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();
- ++iter)
- {
- LLFolderViewFolder *folder = (*iter);
- if (folder->getListener()->getUUID() == id)
- {
- return folder;
- }
- }
- return NULL;
-}
-
-bool LLFolderView::doToSelected(LLInventoryModel* model, const LLSD& userdata)
-{
- std::string action = userdata.asString();
-
- if ("rename" == action)
- {
- startRenamingSelectedItem();
- return true;
- }
- if ("delete" == action)
- {
- removeSelectedItems();
- return true;
- }
- if (("copy" == action) || ("cut" == action))
- {
- // Clear the clipboard before we start adding things on it
- LLClipboard::instance().reset();
- }
-
- static const std::string change_folder_string = "change_folder_type_";
- if (action.length() > change_folder_string.length() &&
- (action.compare(0,change_folder_string.length(),"change_folder_type_") == 0))
- {
- LLFolderType::EType new_folder_type = LLViewerFolderType::lookupTypeFromXUIName(action.substr(change_folder_string.length()));
- changeType(model, new_folder_type);
- return true;
- }
-
-
- std::set<LLUUID> selected_items = getSelectionList();
-
- LLMultiPreview* multi_previewp = NULL;
- LLMultiProperties* multi_propertiesp = NULL;
-
- if (("task_open" == action || "open" == action) && selected_items.size() > 1)
- {
- multi_previewp = new LLMultiPreview();
- gFloaterView->addChild(multi_previewp);
-
- LLFloater::setFloaterHost(multi_previewp);
-
- }
- else if (("task_properties" == action || "properties" == action) && selected_items.size() > 1)
- {
- multi_propertiesp = new LLMultiProperties();
- gFloaterView->addChild(multi_propertiesp);
-
- LLFloater::setFloaterHost(multi_propertiesp);
- }
-
- std::set<LLUUID>::iterator set_iter;
-
- for (set_iter = selected_items.begin(); set_iter != selected_items.end(); ++set_iter)
- {
- LLFolderViewItem* folder_item = getItemByID(*set_iter);
- if(!folder_item) continue;
- LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getListener();
- if(!bridge) continue;
- bridge->performAction(model, action);
- }
-
- LLFloater::setFloaterHost(NULL);
- if (multi_previewp)
- {
- multi_previewp->openFloater(LLSD());
- }
- else if (multi_propertiesp)
- {
- multi_propertiesp->openFloater(LLSD());
- }
-
- return true;
-}
-
-static LLFastTimer::DeclareTimer FTM_AUTO_SELECT("Open and Select");
-static LLFastTimer::DeclareTimer FTM_INVENTORY("Inventory");
-
-// Main idle routine
-void LLFolderView::doIdle()
-{
- // If this is associated with the user's inventory, don't do anything
- // until that inventory is loaded up.
- const LLInventoryPanel *inventory_panel = dynamic_cast<LLInventoryPanel*>(mParentPanel);
- if (inventory_panel && !inventory_panel->getIsViewsInitialized())
- {
- return;
- }
-
- LLFastTimer t2(FTM_INVENTORY);
-
- BOOL debug_filters = gSavedSettings.getBOOL("DebugInventoryFilters");
- if (debug_filters != getDebugFilters())
- {
- mDebugFilters = debug_filters;
- arrangeAll();
- }
-
- if (mFilter->isModified() && mFilter->isNotDefault())
- {
- mNeedsAutoSelect = TRUE;
- }
- mFilter->clearModified();
-
- // filter to determine visibility before arranging
- filterFromRoot();
-
- // automatically show matching items, and select first one if we had a selection
- if (mNeedsAutoSelect)
- {
- LLFastTimer t3(FTM_AUTO_SELECT);
- // select new item only if a filtered item not currently selected
- LLFolderViewItem* selected_itemp = mSelectedItems.empty() ? NULL : mSelectedItems.back();
- if (!mAutoSelectOverride && (!selected_itemp || !selected_itemp->potentiallyFiltered()))
- {
- // these are named variables to get around gcc not binding non-const references to rvalues
- // and functor application is inherently non-const to allow for stateful functors
- LLSelectFirstFilteredItem functor;
- applyFunctorRecursively(functor);
- }
-
- // Open filtered folders for folder views with mAutoSelectOverride=TRUE.
- // Used by LLPlacesFolderView.
- if (mAutoSelectOverride && !mFilter->getFilterSubString().empty())
- {
- // these are named variables to get around gcc not binding non-const references to rvalues
- // and functor application is inherently non-const to allow for stateful functors
- LLOpenFilteredFolders functor;
- applyFunctorRecursively(functor);
- }
-
- scrollToShowSelection();
- }
-
- BOOL filter_finished = mCompletedFilterGeneration >= mFilter->getCurrentGeneration()
- && !LLInventoryModelBackgroundFetch::instance().folderFetchActive();
- if (filter_finished
- || gFocusMgr.childHasKeyboardFocus(inventory_panel)
- || gFocusMgr.childHasMouseCapture(inventory_panel))
- {
- // finishing the filter process, giving focus to the folder view, or dragging the scrollbar all stop the auto select process
- mNeedsAutoSelect = FALSE;
- }
-
-
- // during filtering process, try to pin selected item's location on screen
- // this will happen when searching your inventory and when new items arrive
- if (!filter_finished)
- {
- // calculate rectangle to pin item to at start of animated rearrange
- if (!mPinningSelectedItem && !mSelectedItems.empty())
- {
- // lets pin it!
- mPinningSelectedItem = TRUE;
-
- LLRect visible_content_rect = mScrollContainer->getVisibleContentRect();
- LLFolderViewItem* selected_item = mSelectedItems.back();
-
- LLRect item_rect;
- selected_item->localRectToOtherView(selected_item->getLocalRect(), &item_rect, this);
- // if item is visible in scrolled region
- if (visible_content_rect.overlaps(item_rect))
- {
- // then attempt to keep it in same place on screen
- mScrollConstraintRect = item_rect;
- mScrollConstraintRect.translate(-visible_content_rect.mLeft, -visible_content_rect.mBottom);
- }
- else
- {
- // otherwise we just want it onscreen somewhere
- LLRect content_rect = mScrollContainer->getContentWindowRect();
- mScrollConstraintRect.setOriginAndSize(0, 0, content_rect.getWidth(), content_rect.getHeight());
- }
- }
- }
- else
- {
- // stop pinning selected item after folders stop rearranging
- if (!needsArrange())
- {
- mPinningSelectedItem = FALSE;
- }
- }
-
- LLRect constraint_rect;
- if (mPinningSelectedItem)
- {
- // use last known constraint rect for pinned item
- constraint_rect = mScrollConstraintRect;
- }
- else
- {
- // during normal use (page up/page down, etc), just try to fit item on screen
- LLRect content_rect = mScrollContainer->getContentWindowRect();
- constraint_rect.setOriginAndSize(0, 0, content_rect.getWidth(), content_rect.getHeight());
- }
-
-
- BOOL is_visible = isInVisibleChain();
-
- if ( is_visible )
- {
- sanitizeSelection();
- if( needsArrange() )
- {
- arrangeFromRoot();
- }
- }
-
- if (mSelectedItems.size() && mNeedsScroll)
- {
- scrollToShowItem(mSelectedItems.back(), constraint_rect);
- // continue scrolling until animated layout change is done
- if (filter_finished
- && (!needsArrange() || !is_visible))
- {
- mNeedsScroll = FALSE;
- }
- }
-
- if (mSignalSelectCallback)
- {
- //RN: we use keyboard focus as a proxy for user-explicit actions
- BOOL take_keyboard_focus = (mSignalSelectCallback == SIGNAL_KEYBOARD_FOCUS);
- mSelectSignal(mSelectedItems, take_keyboard_focus);
- }
- mSignalSelectCallback = FALSE;
-}
-
-
-//static
-void LLFolderView::idle(void* user_data)
-{
- LLFolderView* self = (LLFolderView*)user_data;
- if ( self )
- { // Do the real idle
- self->doIdle();
- }
-}
-
-void LLFolderView::dumpSelectionInformation()
-{
- llinfos << "LLFolderView::dumpSelectionInformation()" << llendl;
- llinfos << "****************************************" << llendl;
- selected_items_t::iterator item_it;
- for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
- {
- llinfos << " " << (*item_it)->getName() << llendl;
- }
- llinfos << "****************************************" << llendl;
-}
-
-void LLFolderView::updateRenamerPosition()
-{
- if(mRenameItem)
- {
- // See also LLFolderViewItem::draw()
- S32 x = ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + mRenameItem->getIndentation();
- S32 y = mRenameItem->getRect().getHeight() - mRenameItem->getItemHeight() - RENAME_HEIGHT_PAD;
- mRenameItem->localPointToScreen( x, y, &x, &y );
- screenPointToLocal( x, y, &x, &y );
- mRenamer->setOrigin( x, y );
-
- LLRect scroller_rect(0, 0, gViewerWindow->getWindowWidthScaled(), 0);
- if (mScrollContainer)
- {
- scroller_rect = mScrollContainer->getContentWindowRect();
- }
-
- S32 width = llmax(llmin(mRenameItem->getRect().getWidth() - x, scroller_rect.getWidth() - x - getRect().mLeft), MINIMUM_RENAMER_WIDTH);
- S32 height = mRenameItem->getItemHeight() - RENAME_HEIGHT_PAD;
- mRenamer->reshape( width, height, TRUE );
- }
-}
-
-// Update visibility and availability (i.e. enabled/disabled) of context menu items.
-void LLFolderView::updateMenuOptions(LLMenuGL* menu)
-{
- const LLView::child_list_t *list = menu->getChildList();
-
- LLView::child_list_t::const_iterator menu_itor;
- for (menu_itor = list->begin(); menu_itor != list->end(); ++menu_itor)
- {
- (*menu_itor)->setVisible(FALSE);
- (*menu_itor)->pushVisible(TRUE);
- (*menu_itor)->setEnabled(TRUE);
- }
-
- // Successively filter out invalid options
-
- U32 flags = FIRST_SELECTED_ITEM;
- for (selected_items_t::iterator item_itor = mSelectedItems.begin();
- item_itor != mSelectedItems.end();
- ++item_itor)
- {
- LLFolderViewItem* selected_item = (*item_itor);
- selected_item->buildContextMenu(*menu, flags);
- flags = 0x0;
- }
-
- addNoOptions(menu);
-}
-
-// Refresh the context menu (that is already shown).
-void LLFolderView::updateMenu()
-{
- LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
- if (menu && menu->getVisible())
- {
- updateMenuOptions(menu);
- menu->needsArrange(); // update menu height if needed
- }
-}
-
-bool LLFolderView::selectFirstItem()
-{
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();++iter)
- {
- LLFolderViewFolder* folder = (*iter );
- if (folder->getVisible())
- {
- LLFolderViewItem* itemp = folder->getNextFromChild(0,true);
- if(itemp)
- setSelection(itemp,FALSE,TRUE);
- return true;
- }
-
- }
- for(items_t::iterator iit = mItems.begin();
- iit != mItems.end(); ++iit)
- {
- LLFolderViewItem* itemp = (*iit);
- if (itemp->getVisible())
- {
- setSelection(itemp,FALSE,TRUE);
- return true;
- }
- }
- return false;
-}
-bool LLFolderView::selectLastItem()
-{
- for(items_t::reverse_iterator iit = mItems.rbegin();
- iit != mItems.rend(); ++iit)
- {
- LLFolderViewItem* itemp = (*iit);
- if (itemp->getVisible())
- {
- setSelection(itemp,FALSE,TRUE);
- return true;
- }
- }
- for (folders_t::reverse_iterator iter = mFolders.rbegin();
- iter != mFolders.rend();++iter)
- {
- LLFolderViewFolder* folder = (*iter);
- if (folder->getVisible())
- {
- LLFolderViewItem* itemp = folder->getPreviousFromChild(0,true);
- if(itemp)
- setSelection(itemp,FALSE,TRUE);
- return true;
- }
- }
- return false;
-}
-
-
-S32 LLFolderView::notify(const LLSD& info)
-{
- if(info.has("action"))
- {
- std::string str_action = info["action"];
- if(str_action == "select_first")
- {
- setFocus(true);
- selectFirstItem();
- scrollToShowSelection();
- return 1;
-
- }
- else if(str_action == "select_last")
- {
- setFocus(true);
- selectLastItem();
- scrollToShowSelection();
- return 1;
- }
- }
- return 0;
-}
-
-
-///----------------------------------------------------------------------------
-/// Local function definitions
-///----------------------------------------------------------------------------
-
-void LLFolderView::onRenamerLost()
-{
- if (mRenamer && mRenamer->getVisible())
- {
- mRenamer->setVisible(FALSE);
-
- // will commit current name (which could be same as original name)
- mRenamer->setFocus(FALSE);
- }
-
- if( mRenameItem )
- {
- setSelectionFromRoot( mRenameItem, TRUE );
- mRenameItem = NULL;
- }
-}
-
-LLInventoryFilter* LLFolderView::getFilter()
-{
- return mFilter;
-}
-
-void LLFolderView::setFilterPermMask( PermissionMask filter_perm_mask )
-{
- mFilter->setFilterPermissions(filter_perm_mask);
-}
-
-U32 LLFolderView::getFilterObjectTypes() const
-{
- return mFilter->getFilterObjectTypes();
-}
-
-PermissionMask LLFolderView::getFilterPermissions() const
-{
- return mFilter->getFilterPermissions();
-}
-
-BOOL LLFolderView::isFilterModified()
-{
- return mFilter->isNotDefault();
-}
-
-void delete_selected_item(void* user_data)
-{
- if(user_data)
- {
- LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data);
- fv->removeSelectedItems();
- }
-}
-
-void copy_selected_item(void* user_data)
-{
- if(user_data)
- {
- LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data);
- fv->copy();
- }
-}
-
-void paste_items(void* user_data)
-{
- if(user_data)
- {
- LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data);
- fv->paste();
- }
-}
-
-void open_selected_items(void* user_data)
-{
- if(user_data)
- {
- LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data);
- fv->openSelectedItems();
- }
-}
-
-void properties_selected_items(void* user_data)
-{
- if(user_data)
- {
- LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data);
- fv->propertiesSelectedItems();
- }
-}
diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h
deleted file mode 100644
index dc3d02eac6..0000000000
--- a/indra/newview/llfolderview.h
+++ /dev/null
@@ -1,367 +0,0 @@
-/**
- * @file llfolderview.h
- * @brief Definition of the folder view collection of classes.
- *
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-/**
- *
- * The folder view collection of classes provides an interface for
- * making a 'folder view' similar to the way the a single pane file
- * folder interface works.
- *
- */
-
-#ifndef LL_LLFOLDERVIEW_H
-#define LL_LLFOLDERVIEW_H
-
-#include "llfolderviewitem.h" // because LLFolderView is-a LLFolderViewFolder
-
-#include "lluictrl.h"
-#include "v4color.h"
-#include "lldarray.h"
-#include "stdenums.h"
-#include "lldepthstack.h"
-#include "lleditmenuhandler.h"
-#include "llfontgl.h"
-#include "llscrollcontainer.h"
-#include "lltooldraganddrop.h"
-#include "llviewertexture.h"
-
-class LLFolderViewEventListener;
-class LLFolderViewFolder;
-class LLFolderViewItem;
-class LLInventoryModel;
-class LLPanel;
-class LLLineEditor;
-class LLMenuGL;
-class LLUICtrl;
-class LLTextBox;
-
-/**
- * Class LLFolderViewScrollContainer
- *
- * A scroll container which provides the information about the height
- * of currently displayed folder view contents.
- * Used for updating vertical scroll bar visibility in inventory panel.
- * See LLScrollContainer::calcVisibleSize().
- */
-class LLFolderViewScrollContainer : public LLScrollContainer
-{
-public:
- /*virtual*/ ~LLFolderViewScrollContainer() {};
- /*virtual*/ const LLRect getScrolledViewRect() const;
-
-protected:
- LLFolderViewScrollContainer(const LLScrollContainer::Params& p);
- friend class LLUICtrlFactory;
-};
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLFolderView
-//
-// The LLFolderView represents the root level folder view object.
-// It manages the screen region of the folder view.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler
-{
-public:
- struct Params : public LLInitParam::Block<Params, LLFolderViewFolder::Params>
- {
- Mandatory<LLPanel*> parent_panel;
- Optional<LLUUID> task_id;
- Optional<std::string> title;
- Optional<bool> use_label_suffix,
- allow_multiselect,
- show_empty_message,
- show_load_status,
- use_ellipses;
-
- Params();
- };
-
- friend class LLFolderViewScrollContainer;
-
- LLFolderView(const Params&);
- virtual ~LLFolderView( void );
-
- virtual BOOL canFocusChildren() const;
-
- virtual LLFolderView* getRoot() { return this; }
-
- // FolderViews default to sort by name. This will change that,
- // and resort the items if necessary.
- void setSortOrder(U32 order);
- void setFilterPermMask(PermissionMask filter_perm_mask);
-
- typedef boost::signals2::signal<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)> signal_t;
- void setSelectCallback(const signal_t::slot_type& cb) { mSelectSignal.connect(cb); }
- void setReshapeCallback(const signal_t::slot_type& cb) { mReshapeSignal.connect(cb); }
-
- // filter is never null
- LLInventoryFilter* getFilter();
- const std::string getFilterSubString(BOOL trim = FALSE);
- U32 getFilterObjectTypes() const;
- PermissionMask getFilterPermissions() const;
- // *NOTE: use getFilter()->getShowFolderState();
- //LLInventoryFilter::EFolderShow getShowFolderState();
- U32 getSortOrder() const;
- BOOL isFilterModified();
-
- bool getAllowMultiSelect() { return mAllowMultiSelect; }
-
- // Close all folders in the view
- void closeAllFolders();
- void openTopLevelFolders();
-
- virtual void toggleOpen() {};
- virtual void setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse);
- virtual BOOL addFolder( LLFolderViewFolder* folder);
-
- // Find width and height of this object and its children. Also
- // makes sure that this view and its children are the right size.
- virtual S32 arrange( S32* width, S32* height, S32 filter_generation );
-
- void arrangeAll() { mArrangeGeneration++; }
- S32 getArrangeGeneration() { return mArrangeGeneration; }
-
- // Apply filters to control visibility of inventory items
- virtual void filter( LLInventoryFilter& filter);
-
- // Get the last selected item
- virtual LLFolderViewItem* getCurSelectedItem( void );
-
- // Record the selected item and pass it down the hierarchy.
- virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem,
- BOOL take_keyboard_focus);
-
- // Used by menu callbacks
- void setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus);
-
- // Called once a frame to update the selection if mSelectThisID has been set
- void updateSelection();
-
- // This method is used to toggle the selection of an item.
- // Walks children and keeps track of selected objects.
- virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
-
- virtual std::set<LLUUID> getSelectionList() const;
-
- // Make sure if ancestor is selected, descendents are not
- void sanitizeSelection();
- void clearSelection();
- void addToSelectionList(LLFolderViewItem* item);
- void removeFromSelectionList(LLFolderViewItem* item);
-
- BOOL startDrag(LLToolDragAndDrop::ESource source);
- void setDragAndDropThisFrame() { mDragAndDropThisFrame = TRUE; }
- void setDraggingOverItem(LLFolderViewItem* item) { mDraggingOverItem = item; }
- LLFolderViewItem* getDraggingOverItem() { return mDraggingOverItem; }
-
- // Deletion functionality
- void removeSelectedItems();
- static void removeCutItems();
-
- // Open the selected item
- void openSelectedItems( void );
- void propertiesSelectedItems( void );
-
- // Change the folder type
- void changeType(LLInventoryModel *model, LLFolderType::EType new_folder_type);
-
- void autoOpenItem(LLFolderViewFolder* item);
- void closeAutoOpenedFolders();
- BOOL autoOpenTest(LLFolderViewFolder* item);
-
- // Copy & paste
- virtual void copy();
- virtual BOOL canCopy() const;
-
- virtual void cut();
- virtual BOOL canCut() const;
-
- virtual void paste();
- virtual BOOL canPaste() const;
-
- virtual void doDelete();
- virtual BOOL canDoDelete() const;
-
- // Public rename functionality - can only start the process
- void startRenamingSelectedItem( void );
-
- // LLView functionality
- ///*virtual*/ BOOL handleKey( KEY key, MASK mask, BOOL called_from_parent );
- /*virtual*/ BOOL handleKeyHere( KEY key, MASK mask );
- /*virtual*/ BOOL handleUnicodeCharHere(llwchar uni_char);
- /*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask );
- /*virtual*/ BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
- /*virtual*/ BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
- /*virtual*/ BOOL handleHover( S32 x, S32 y, MASK mask );
- /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg);
- /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
- /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask) { setShowSelectionContext(FALSE); }
- virtual void draw();
- virtual void deleteAllChildren();
-
- void scrollToShowSelection();
- void scrollToShowItem(LLFolderViewItem* item, const LLRect& constraint_rect);
- void setScrollContainer( LLScrollContainer* parent ) { mScrollContainer = parent; }
- LLRect getVisibleRect();
-
- BOOL search(LLFolderViewItem* first_item, const std::string &search_string, BOOL backward);
- void setShowSelectionContext(BOOL show) { mShowSelectionContext = show; }
- BOOL getShowSelectionContext();
- void setShowSingleSelection(BOOL show);
- BOOL getShowSingleSelection() { return mShowSingleSelection; }
- F32 getSelectionFadeElapsedTime() { return mMultiSelectionFadeTimer.getElapsedTimeF32(); }
- bool getUseEllipses() { return mUseEllipses; }
-
- void addItemID(const LLUUID& id, LLFolderViewItem* itemp);
- void removeItemID(const LLUUID& id);
- LLFolderViewItem* getItemByID(const LLUUID& id);
- LLFolderViewFolder* getFolderByID(const LLUUID& id);
-
- bool doToSelected(LLInventoryModel* model, const LLSD& userdata);
-
- void doIdle(); // Real idle routine
- static void idle(void* user_data); // static glue to doIdle()
-
- BOOL needsAutoSelect() { return mNeedsAutoSelect && !mAutoSelectOverride; }
- BOOL needsAutoRename() { return mNeedsAutoRename; }
- void setNeedsAutoRename(BOOL val) { mNeedsAutoRename = val; }
- void setPinningSelectedItem(BOOL val) { mPinningSelectedItem = val; }
- void setAutoSelectOverride(BOOL val) { mAutoSelectOverride = val; }
-
- void setCallbackRegistrar(LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* registrar) { mCallbackRegistrar = registrar; }
-
- BOOL getDebugFilters() { return mDebugFilters; }
-
- LLPanel* getParentPanel() { return mParentPanel; }
- // DEBUG only
- void dumpSelectionInformation();
-
- virtual S32 notify(const LLSD& info) ;
-
- bool useLabelSuffix() { return mUseLabelSuffix; }
- void updateMenu();
-
-private:
- void updateMenuOptions(LLMenuGL* menu);
- void updateRenamerPosition();
-
-protected:
- LLScrollContainer* mScrollContainer; // NULL if this is not a child of a scroll container.
-
- void commitRename( const LLSD& data );
- void onRenamerLost();
-
- void finishRenamingItem( void );
- void closeRenamer( void );
-
- bool selectFirstItem();
- bool selectLastItem();
-
- BOOL addNoOptions(LLMenuGL* menu) const;
-
- void onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response);
-
-protected:
- LLHandle<LLView> mPopupMenuHandle;
-
- typedef std::deque<LLFolderViewItem*> selected_items_t;
- selected_items_t mSelectedItems;
- BOOL mKeyboardSelection;
- BOOL mAllowMultiSelect;
- BOOL mShowEmptyMessage;
- BOOL mShowFolderHierarchy;
- LLUUID mSourceID;
-
- // Renaming variables and methods
- LLFolderViewItem* mRenameItem; // The item currently being renamed
- LLLineEditor* mRenamer;
-
- BOOL mNeedsScroll;
- BOOL mPinningSelectedItem;
- LLRect mScrollConstraintRect;
- BOOL mNeedsAutoSelect;
- BOOL mAutoSelectOverride;
- BOOL mNeedsAutoRename;
- bool mUseLabelSuffix;
-
- BOOL mDebugFilters;
- U32 mSortOrder;
- LLDepthStack<LLFolderViewFolder> mAutoOpenItems;
- LLFolderViewFolder* mAutoOpenCandidate;
- LLFrameTimer mAutoOpenTimer;
- LLFrameTimer mSearchTimer;
- std::string mSearchString;
- LLInventoryFilter* mFilter;
- BOOL mShowSelectionContext;
- BOOL mShowSingleSelection;
- LLFrameTimer mMultiSelectionFadeTimer;
- S32 mArrangeGeneration;
-
- signal_t mSelectSignal;
- signal_t mReshapeSignal;
- S32 mSignalSelectCallback;
- S32 mMinWidth;
- S32 mRunningHeight;
- std::map<LLUUID, LLFolderViewItem*> mItemMap;
- BOOL mDragAndDropThisFrame;
-
- LLUUID mSelectThisID; // if non null, select this item
-
- LLPanel* mParentPanel;
-
- /**
- * Is used to determine if we need to cut text In LLFolderViewItem to avoid horizontal scroll.
- * NOTE: For now it's used only to cut LLFolderViewItem::mLabel text for Landmarks in Places Panel.
- */
- bool mUseEllipses; // See EXT-719
-
- /**
- * Contains item under mouse pointer while dragging
- */
- LLFolderViewItem* mDraggingOverItem; // See EXT-719
-
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* mCallbackRegistrar;
-
-public:
- static F32 sAutoOpenTime;
- LLTextBox* mStatusTextBox;
-
-};
-
-bool sort_item_name(LLFolderViewItem* a, LLFolderViewItem* b);
-bool sort_item_date(LLFolderViewItem* a, LLFolderViewItem* b);
-
-// Flags for buildContextMenu()
-const U32 SUPPRESS_OPEN_ITEM = 0x1;
-const U32 FIRST_SELECTED_ITEM = 0x2;
-
-#endif // LL_LLFOLDERVIEW_H
diff --git a/indra/newview/llfoldervieweventlistener.h b/indra/newview/llfoldervieweventlistener.h
deleted file mode 100644
index 06682dcbf1..0000000000
--- a/indra/newview/llfoldervieweventlistener.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/**
- * @file llfoldervieweventlistener.h
- *
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-#ifndef LLFOLDERVIEWEVENTLISTENER_H
-#define LLFOLDERVIEWEVENTLISTENER_H
-
-#include "lldarray.h" // *TODO: convert to std::vector
-#include "llfoldertype.h"
-#include "llfontgl.h" // just for StyleFlags enum
-#include "llinventorytype.h"
-#include "llpermissionsflags.h"
-#include "llpointer.h"
-#include "llwearabletype.h"
-
-
-class LLFolderViewItem;
-class LLFolderView;
-class LLFontGL;
-class LLInventoryModel;
-class LLMenuGL;
-class LLScrollContainer;
-class LLUIImage;
-class LLUUID;
-
-// This is an abstract base class that users of the folderview classes
-// would use to catch the useful events emitted from the folder
-// views.
-class LLFolderViewEventListener
-{
-public:
- virtual ~LLFolderViewEventListener( void ) {}
- virtual const std::string& getName() const = 0;
- virtual const std::string& getDisplayName() const = 0;
- virtual const LLUUID& getUUID() const = 0;
- virtual time_t getCreationDate() const = 0; // UTC seconds
- virtual PermissionMask getPermissionMask() const = 0;
- virtual LLFolderType::EType getPreferredType() const = 0;
- virtual LLPointer<LLUIImage> getIcon() const = 0;
- virtual LLPointer<LLUIImage> getOpenIcon() const { return getIcon(); }
- virtual LLFontGL::StyleFlags getLabelStyle() const = 0;
- virtual std::string getLabelSuffix() const = 0;
- virtual void openItem( void ) = 0;
- virtual void closeItem( void ) = 0;
- virtual void previewItem( void ) = 0;
- virtual void selectItem(void) = 0;
- virtual void showProperties(void) = 0;
- virtual BOOL isItemRenameable() const = 0;
- virtual BOOL renameItem(const std::string& new_name) = 0;
- virtual BOOL isItemMovable( void ) const = 0; // Can be moved to another folder
- virtual BOOL isItemRemovable( void ) const = 0; // Can be destroyed
- virtual BOOL isItemInTrash( void) const { return FALSE; } // TODO: make into pure virtual.
- virtual BOOL removeItem() = 0;
- virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch) = 0;
- virtual void move( LLFolderViewEventListener* parent_listener ) = 0;
- virtual BOOL isItemCopyable() const = 0;
- virtual BOOL copyToClipboard() const = 0;
- virtual BOOL cutToClipboard() const = 0;
- virtual BOOL isClipboardPasteable() const = 0;
- virtual void pasteFromClipboard() = 0;
- virtual void pasteLinkFromClipboard() = 0;
- virtual void buildContextMenu(LLMenuGL& menu, U32 flags) = 0;
- virtual BOOL isUpToDate() const = 0;
- virtual BOOL hasChildren() const = 0;
- virtual LLInventoryType::EType getInventoryType() const = 0;
- virtual void performAction(LLInventoryModel* model, std::string action) = 0;
- virtual LLWearableType::EType getWearableType() const = 0;
-
- // This method should be called when a drag begins. returns TRUE
- // if the drag can begin, otherwise FALSE.
- virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const = 0;
-
- // This method will be called to determine if a drop can be
- // performed, and will set drop to TRUE if a drop is
- // requested. Returns TRUE if a drop is possible/happened,
- // otherwise FALSE.
- virtual BOOL dragOrDrop(MASK mask, BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- std::string& tooltip_msg) = 0;
-};
-
-#endif
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
deleted file mode 100644
index 8ae779326c..0000000000
--- a/indra/newview/llfolderviewitem.cpp
+++ /dev/null
@@ -1,2919 +0,0 @@
-/**
-* @file llfolderviewitem.cpp
-* @brief Items and folders that can appear in a hierarchical folder view
-*
-* $LicenseInfo:firstyear=2001&license=viewerlgpl$
-* Second Life Viewer Source Code
-* Copyright (C) 2010, Linden Research, Inc.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation;
-* version 2.1 of the License only.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
-* $/LicenseInfo$
-*/
-#include "llviewerprecompiledheaders.h"
-
-#include "llfolderviewitem.h"
-
-// viewer includes
-#include "llfolderview.h" // Items depend extensively on LLFolderViews
-#include "llfoldervieweventlistener.h"
-#include "llviewerfoldertype.h"
-#include "llinventorybridge.h" // for LLItemBridge in LLInventorySort::operator()
-#include "llinventoryfilter.h"
-#include "llinventoryfunctions.h"
-#include "llinventorymodelbackgroundfetch.h"
-#include "llpanel.h"
-#include "llviewercontrol.h" // gSavedSettings
-#include "llviewerwindow.h" // Argh, only for setCursor()
-
-// linden library includes
-#include "llclipboard.h"
-#include "llfocusmgr.h" // gFocusMgr
-#include "lltrans.h"
-
-///----------------------------------------------------------------------------
-/// Class LLFolderViewItem
-///----------------------------------------------------------------------------
-
-static LLDefaultChildRegistry::Register<LLFolderViewItem> r("folder_view_item");
-
-// statics
-std::map<U8, LLFontGL*> LLFolderViewItem::sFonts; // map of styles to fonts
-
-// only integers can be initialized in header
-const F32 LLFolderViewItem::FOLDER_CLOSE_TIME_CONSTANT = 0.02f;
-const F32 LLFolderViewItem::FOLDER_OPEN_TIME_CONSTANT = 0.03f;
-
-const LLColor4U DEFAULT_WHITE(255, 255, 255);
-
-
-//static
-LLFontGL* LLFolderViewItem::getLabelFontForStyle(U8 style)
-{
- LLFontGL* rtn = sFonts[style];
- if (!rtn) // grab label font with this style, lazily
- {
- LLFontDescriptor labelfontdesc("SansSerif", "Small", style);
- rtn = LLFontGL::getFont(labelfontdesc);
- if (!rtn)
- {
- rtn = LLFontGL::getFontDefault();
- }
- sFonts[style] = rtn;
- }
- return rtn;
-}
-
-//static
-void LLFolderViewItem::initClass()
-{
-}
-
-//static
-void LLFolderViewItem::cleanupClass()
-{
- sFonts.clear();
-}
-
-
-// NOTE: Optimize this, we call it a *lot* when opening a large inventory
-LLFolderViewItem::Params::Params()
-: icon(),
- icon_open(),
- icon_overlay(),
- root(),
- listener(),
- folder_arrow_image("folder_arrow_image"),
- folder_indentation("folder_indentation"),
- selection_image("selection_image"),
- item_height("item_height"),
- item_top_pad("item_top_pad"),
- creation_date()
-{}
-
-// Default constructor
-LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
-: LLView(p),
- mLabelWidth(0),
- mLabelWidthDirty(false),
- mParentFolder( NULL ),
- mIsSelected( FALSE ),
- mIsCurSelection( FALSE ),
- mSelectPending(FALSE),
- mLabelStyle( LLFontGL::NORMAL ),
- mHasVisibleChildren(FALSE),
- mIndentation(0),
- mItemHeight(p.item_height),
- mPassedFilter(FALSE),
- mLastFilterGeneration(-1),
- mStringMatchOffset(std::string::npos),
- mControlLabelRotation(0.f),
- mDragAndDropTarget(FALSE),
- mIsLoading(FALSE),
- mLabel(p.name),
- mRoot(p.root),
- mCreationDate(p.creation_date),
- mIcon(p.icon),
- mIconOpen(p.icon_open),
- mIconOverlay(p.icon_overlay),
- mListener(p.listener),
- mShowLoadStatus(false),
- mIsMouseOverTitle(false)
-{
-}
-
-BOOL LLFolderViewItem::postBuild()
-{
- refresh();
- return TRUE;
-}
-
-// Destroys the object
-LLFolderViewItem::~LLFolderViewItem( void )
-{
- delete mListener;
- mListener = NULL;
-}
-
-LLFolderView* LLFolderViewItem::getRoot()
-{
- return mRoot;
-}
-
-// Returns true if this object is a child (or grandchild, etc.) of potential_ancestor.
-BOOL LLFolderViewItem::isDescendantOf( const LLFolderViewFolder* potential_ancestor )
-{
- LLFolderViewItem* root = this;
- while( root->mParentFolder )
- {
- if( root->mParentFolder == potential_ancestor )
- {
- return TRUE;
- }
- root = root->mParentFolder;
- }
- return FALSE;
-}
-
-LLFolderViewItem* LLFolderViewItem::getNextOpenNode(BOOL include_children)
-{
- if (!mParentFolder)
- {
- return NULL;
- }
-
- LLFolderViewItem* itemp = mParentFolder->getNextFromChild( this, include_children );
- while(itemp && !itemp->getVisible())
- {
- LLFolderViewItem* next_itemp = itemp->mParentFolder->getNextFromChild( itemp, include_children );
- if (itemp == next_itemp)
- {
- // hit last item
- return itemp->getVisible() ? itemp : this;
- }
- itemp = next_itemp;
- }
-
- return itemp;
-}
-
-LLFolderViewItem* LLFolderViewItem::getPreviousOpenNode(BOOL include_children)
-{
- if (!mParentFolder)
- {
- return NULL;
- }
-
- LLFolderViewItem* itemp = mParentFolder->getPreviousFromChild( this, include_children );
-
- // Skip over items that are invisible or are hidden from the UI.
- while(itemp && !itemp->getVisible())
- {
- LLFolderViewItem* next_itemp = itemp->mParentFolder->getPreviousFromChild( itemp, include_children );
- if (itemp == next_itemp)
- {
- // hit first item
- return itemp->getVisible() ? itemp : this;
- }
- itemp = next_itemp;
- }
-
- return itemp;
-}
-
-// is this item something we think we should be showing?
-// for example, if we haven't gotten around to filtering it yet, then the answer is yes
-// until we find out otherwise
-BOOL LLFolderViewItem::potentiallyVisible()
-{
- // we haven't been checked against min required filter
- // or we have and we passed
- return potentiallyFiltered();
-}
-
-BOOL LLFolderViewItem::potentiallyFiltered()
-{
- return getLastFilterGeneration() < getRoot()->getFilter()->getMinRequiredGeneration() || getFiltered();
-}
-
-BOOL LLFolderViewItem::getFiltered()
-{
- return mPassedFilter && mLastFilterGeneration >= getRoot()->getFilter()->getMinRequiredGeneration();
-}
-
-BOOL LLFolderViewItem::getFiltered(S32 filter_generation)
-{
- return mPassedFilter && mLastFilterGeneration >= filter_generation;
-}
-
-void LLFolderViewItem::setFiltered(BOOL filtered, S32 filter_generation)
-{
- mPassedFilter = filtered;
- mLastFilterGeneration = filter_generation;
-}
-
-void LLFolderViewItem::setIcon(LLUIImagePtr icon)
-{
- mIcon = icon;
-}
-
-// refresh information from the listener
-void LLFolderViewItem::refreshFromListener()
-{
- if(mListener)
- {
- mLabel = mListener->getDisplayName();
- LLFolderType::EType preferred_type = mListener->getPreferredType();
-
- // *TODO: to be removed when database supports multi language. This is a
- // temporary attempt to display the inventory folder in the user locale.
- // mantipov: *NOTE: be sure this code is synchronized with LLFriendCardsManager::findChildFolderUUID
- // it uses the same way to find localized string
-
- // HACK: EXT - 6028 ([HARD CODED]? Inventory > Library > "Accessories" folder)
- // Translation of Accessories folder in Library inventory folder
- bool accessories = false;
- if(mLabel == std::string("Accessories"))
- {
- //To ensure that Accessories folder is in Library we have to check its parent folder.
- //Due to parent LLFolderViewFloder is not set to this item yet we have to check its parent via Inventory Model
- LLInventoryCategory* cat = gInventory.getCategory(mListener->getUUID());
- if(cat)
- {
- const LLUUID& parent_folder_id = cat->getParentUUID();
- accessories = (parent_folder_id == gInventory.getLibraryRootFolderID());
- }
- }
-
- //"Accessories" inventory category has folder type FT_NONE. So, this folder
- //can not be detected as protected with LLFolderType::lookupIsProtectedType
- if (accessories || LLFolderType::lookupIsProtectedType(preferred_type))
- {
- LLTrans::findString(mLabel, "InvFolder " + mLabel);
- };
-
- setToolTip(mLabel);
- setIcon(mListener->getIcon());
- time_t creation_date = mListener->getCreationDate();
- if ((creation_date > 0) && (mCreationDate != creation_date))
- {
- setCreationDate(creation_date);
- dirtyFilter();
- }
- if (mRoot && mRoot->useLabelSuffix())
- {
- mLabelStyle = mListener->getLabelStyle();
- mLabelSuffix = mListener->getLabelSuffix();
- }
- }
-}
-
-void LLFolderViewItem::refresh()
-{
- refreshFromListener();
-
- std::string searchable_label(mLabel);
- searchable_label.append(mLabelSuffix);
- LLStringUtil::toUpper(searchable_label);
-
- if (mSearchableLabel.compare(searchable_label))
- {
- mSearchableLabel.assign(searchable_label);
- dirtyFilter();
- // some part of label has changed, so overall width has potentially changed, and sort order too
- if (mParentFolder)
- {
- mParentFolder->requestSort();
- mParentFolder->requestArrange();
- }
- }
-
- mLabelWidthDirty = true;
-}
-
-void LLFolderViewItem::applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor)
-{
- functor(mListener);
-}
-
-// This function is called when items are added or view filters change. It's
-// implemented here but called by derived classes when folding the
-// views.
-void LLFolderViewItem::filterFromRoot( void )
-{
- LLFolderViewItem* root = getRoot();
-
- root->filter(*((LLFolderView*)root)->getFilter());
-}
-
-// This function is called when the folder view is dirty. It's
-// implemented here but called by derived classes when folding the
-// views.
-void LLFolderViewItem::arrangeFromRoot()
-{
- LLFolderViewItem* root = getRoot();
-
- S32 height = 0;
- S32 width = 0;
- S32 total_height = root->arrange( &width, &height, 0 );
-
- LLSD params;
- params["action"] = "size_changes";
- params["height"] = total_height;
- getParent()->notifyParent(params);
-}
-
-// Utility function for LLFolderView
-void LLFolderViewItem::arrangeAndSet(BOOL set_selection,
- BOOL take_keyboard_focus)
-{
- LLFolderView* root = getRoot();
- if (getParentFolder())
- {
- getParentFolder()->requestArrange();
- }
- if(set_selection)
- {
- setSelectionFromRoot(this, TRUE, take_keyboard_focus);
- if(root)
- {
- root->scrollToShowSelection();
- }
- }
-}
-
-// This function clears the currently selected item, and records the
-// specified selected item appropriately for display and use in the
-// UI. If open is TRUE, then folders are opened up along the way to
-// the selection.
-void LLFolderViewItem::setSelectionFromRoot(LLFolderViewItem* selection,
- BOOL openitem,
- BOOL take_keyboard_focus)
-{
- if (getRoot())
- {
- getRoot()->setSelection(selection, openitem, take_keyboard_focus);
- }
- else if (mListener)
- {
- mListener->selectItem();
- }
-}
-
-// helper function to change the selection from the root.
-void LLFolderViewItem::changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected)
-{
- getRoot()->changeSelection(selection, selected);
-}
-
-std::set<LLUUID> LLFolderViewItem::getSelectionList() const
-{
- std::set<LLUUID> selection;
- return selection;
-}
-
-EInventorySortGroup LLFolderViewItem::getSortGroup() const
-{
- return SG_ITEM;
-}
-
-// addToFolder() returns TRUE if it succeeds. FALSE otherwise
-BOOL LLFolderViewItem::addToFolder(LLFolderViewFolder* folder, LLFolderView* root)
-{
- if (!folder)
- {
- return FALSE;
- }
- mParentFolder = folder;
- root->addItemID(getListener()->getUUID(), this);
- return folder->addItem(this);
-}
-
-
-// Finds width and height of this object and its children. Also
-// makes sure that this view and its children are the right size.
-S32 LLFolderViewItem::arrange( S32* width, S32* height, S32 filter_generation)
-{
- const Params& p = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
- S32 indentation = p.folder_indentation();
- // Only indent deeper items in hierarchy
- mIndentation = (getParentFolder())
- ? getParentFolder()->getIndentation() + indentation
- : 0;
- if (mLabelWidthDirty)
- {
- mLabelWidth = ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + getLabelFontForStyle(mLabelStyle)->getWidth(mLabel) + getLabelFontForStyle(mLabelStyle)->getWidth(mLabelSuffix) + TEXT_PAD_RIGHT;
- mLabelWidthDirty = false;
- }
-
- *width = llmax(*width, mLabelWidth + mIndentation);
-
- // determine if we need to use ellipses to avoid horizontal scroll. EXT-719
- bool use_ellipses = getRoot()->getUseEllipses();
- if (use_ellipses)
- {
- // limit to set rect to avoid horizontal scrollbar
- *width = llmin(*width, getRoot()->getRect().getWidth());
- }
- *height = getItemHeight();
- return *height;
-}
-
-S32 LLFolderViewItem::getItemHeight()
-{
- return mItemHeight;
-}
-
-void LLFolderViewItem::filter( LLInventoryFilter& filter)
-{
- const BOOL previous_passed_filter = mPassedFilter;
- const BOOL passed_filter = filter.check(this);
-
- // If our visibility will change as a result of this filter, then
- // we need to be rearranged in our parent folder
- if (mParentFolder)
- {
- if (getVisible() != passed_filter
- || previous_passed_filter != passed_filter )
- mParentFolder->requestArrange();
- }
-
- setFiltered(passed_filter, filter.getCurrentGeneration());
- mStringMatchOffset = filter.getStringMatchOffset();
- filter.decrementFilterCount();
-
- if (getRoot()->getDebugFilters())
- {
- mStatusText = llformat("%d", mLastFilterGeneration);
- }
-}
-
-void LLFolderViewItem::dirtyFilter()
-{
- mLastFilterGeneration = -1;
- // bubble up dirty flag all the way to root
- if (getParentFolder())
- {
- getParentFolder()->setCompletedFilterGeneration(-1, TRUE);
- }
-}
-
-// *TODO: This can be optimized a lot by simply recording that it is
-// selected in the appropriate places, and assuming that set selection
-// means 'deselect' for a leaf item. Do this optimization after
-// multiple selection is implemented to make sure it all plays nice
-// together.
-BOOL LLFolderViewItem::setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus)
-{
- if (selection == this && !mIsSelected)
- {
- selectItem();
- }
- else if (mIsSelected) // Deselect everything else.
- {
- deselectItem();
- }
- return mIsSelected;
-}
-
-BOOL LLFolderViewItem::changeSelection(LLFolderViewItem* selection, BOOL selected)
-{
- if (selection == this)
- {
- if (mIsSelected)
- {
- deselectItem();
- }
- else
- {
- selectItem();
- }
- return TRUE;
- }
- return FALSE;
-}
-
-void LLFolderViewItem::deselectItem(void)
-{
- mIsSelected = FALSE;
-}
-
-void LLFolderViewItem::selectItem(void)
-{
- if (mIsSelected == FALSE)
- {
- if (mListener)
- {
- mListener->selectItem();
- }
- mIsSelected = TRUE;
- }
-}
-
-BOOL LLFolderViewItem::isMovable()
-{
- if( mListener )
- {
- return mListener->isItemMovable();
- }
- else
- {
- return TRUE;
- }
-}
-
-BOOL LLFolderViewItem::isRemovable()
-{
- if( mListener )
- {
- return mListener->isItemRemovable();
- }
- else
- {
- return TRUE;
- }
-}
-
-void LLFolderViewItem::destroyView()
-{
- if (mParentFolder)
- {
- // removeView deletes me
- mParentFolder->removeView(this);
- }
-}
-
-// Call through to the viewed object and return true if it can be
-// removed.
-//BOOL LLFolderViewItem::removeRecursively(BOOL single_item)
-BOOL LLFolderViewItem::remove()
-{
- if(!isRemovable())
- {
- return FALSE;
- }
- if(mListener)
- {
- return mListener->removeItem();
- }
- return TRUE;
-}
-
-// Build an appropriate context menu for the item.
-void LLFolderViewItem::buildContextMenu(LLMenuGL& menu, U32 flags)
-{
- if(mListener)
- {
- mListener->buildContextMenu(menu, flags);
- }
-}
-
-void LLFolderViewItem::openItem( void )
-{
- if( mListener )
- {
- mListener->openItem();
- }
-}
-
-void LLFolderViewItem::preview( void )
-{
- if (mListener)
- {
- mListener->previewItem();
- }
-}
-
-void LLFolderViewItem::rename(const std::string& new_name)
-{
- if( !new_name.empty() )
- {
- if( mListener )
- {
- mListener->renameItem(new_name);
-
- if(mParentFolder)
- {
- mParentFolder->requestSort();
- }
- }
- }
-}
-
-const std::string& LLFolderViewItem::getSearchableLabel() const
-{
- return mSearchableLabel;
-}
-
-LLViewerInventoryItem * LLFolderViewItem::getInventoryItem(void)
-{
- if (!getListener()) return NULL;
- return gInventory.getItem(getListener()->getUUID());
-}
-
-const std::string& LLFolderViewItem::getName( void ) const
-{
- if(mListener)
- {
- return mListener->getName();
- }
- return mLabel;
-}
-
-// LLView functionality
-BOOL LLFolderViewItem::handleRightMouseDown( S32 x, S32 y, MASK mask )
-{
- if(!mIsSelected)
- {
- setSelectionFromRoot(this, FALSE);
- }
- make_ui_sound("UISndClick");
- return TRUE;
-}
-
-BOOL LLFolderViewItem::handleMouseDown( S32 x, S32 y, MASK mask )
-{
- if (LLView::childrenHandleMouseDown(x, y, mask))
- {
- return TRUE;
- }
-
- // No handler needed for focus lost since this class has no
- // state that depends on it.
- gFocusMgr.setMouseCapture( this );
-
- if (!mIsSelected)
- {
- if(mask & MASK_CONTROL)
- {
- changeSelectionFromRoot(this, !mIsSelected);
- }
- else if (mask & MASK_SHIFT)
- {
- getParentFolder()->extendSelectionTo(this);
- }
- else
- {
- setSelectionFromRoot(this, FALSE);
- }
- make_ui_sound("UISndClick");
- }
- else
- {
- mSelectPending = TRUE;
- }
-
- if( isMovable() )
- {
- S32 screen_x;
- S32 screen_y;
- localPointToScreen(x, y, &screen_x, &screen_y );
- LLToolDragAndDrop::getInstance()->setDragStart( screen_x, screen_y );
- }
- return TRUE;
-}
-
-BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask )
-{
- mIsMouseOverTitle = (y > (getRect().getHeight() - mItemHeight));
-
- if( hasMouseCapture() && isMovable() )
- {
- S32 screen_x;
- S32 screen_y;
- localPointToScreen(x, y, &screen_x, &screen_y );
- BOOL can_drag = TRUE;
- if( LLToolDragAndDrop::getInstance()->isOverThreshold( screen_x, screen_y ) )
- {
- LLFolderView* root = getRoot();
-
- if(root->getCurSelectedItem())
- {
- LLToolDragAndDrop::ESource src = LLToolDragAndDrop::SOURCE_WORLD;
-
- // *TODO: push this into listener and remove
- // dependency on llagent
- if (mListener
- && gInventory.isObjectDescendentOf(mListener->getUUID(), gInventory.getRootFolderID()))
- {
- src = LLToolDragAndDrop::SOURCE_AGENT;
- }
- else if (mListener
- && gInventory.isObjectDescendentOf(mListener->getUUID(), gInventory.getLibraryRootFolderID()))
- {
- src = LLToolDragAndDrop::SOURCE_LIBRARY;
- }
-
- can_drag = root->startDrag(src);
- if (can_drag)
- {
- // if (mListener) mListener->startDrag();
- // RN: when starting drag and drop, clear out last auto-open
- root->autoOpenTest(NULL);
- root->setShowSelectionContext(TRUE);
-
- // Release keyboard focus, so that if stuff is dropped into the
- // world, pressing the delete key won't blow away the inventory
- // item.
- gFocusMgr.setKeyboardFocus(NULL);
-
- return LLToolDragAndDrop::getInstance()->handleHover( x, y, mask );
- }
- }
- }
-
- if (can_drag)
- {
- gViewerWindow->setCursor(UI_CURSOR_ARROW);
- }
- else
- {
- gViewerWindow->setCursor(UI_CURSOR_NOLOCKED);
- }
- return TRUE;
- }
- else
- {
- if (getRoot())
- {
- getRoot()->setShowSelectionContext(FALSE);
- }
- gViewerWindow->setCursor(UI_CURSOR_ARROW);
- // let parent handle this then...
- return FALSE;
- }
-}
-
-
-BOOL LLFolderViewItem::handleDoubleClick( S32 x, S32 y, MASK mask )
-{
- preview();
- return TRUE;
-}
-
-BOOL LLFolderViewItem::handleMouseUp( S32 x, S32 y, MASK mask )
-{
- if (LLView::childrenHandleMouseUp(x, y, mask))
- {
- return TRUE;
- }
-
- // if mouse hasn't moved since mouse down...
- if ( pointInView(x, y) && mSelectPending )
- {
- //...then select
- if(mask & MASK_CONTROL)
- {
- changeSelectionFromRoot(this, !mIsSelected);
- }
- else if (mask & MASK_SHIFT)
- {
- getParentFolder()->extendSelectionTo(this);
- }
- else
- {
- setSelectionFromRoot(this, FALSE);
- }
- }
-
- mSelectPending = FALSE;
-
- if( hasMouseCapture() )
- {
- if (getRoot())
- {
- getRoot()->setShowSelectionContext(FALSE);
- }
- gFocusMgr.setMouseCapture( NULL );
- }
- return TRUE;
-}
-
-void LLFolderViewItem::onMouseLeave(S32 x, S32 y, MASK mask)
-{
- mIsMouseOverTitle = false;
-}
-
-BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg)
-{
- BOOL accepted = FALSE;
- BOOL handled = FALSE;
- if(mListener)
- {
- accepted = mListener->dragOrDrop(mask,drop,cargo_type,cargo_data, tooltip_msg);
- handled = accepted;
- if (accepted)
- {
- mDragAndDropTarget = TRUE;
- *accept = ACCEPT_YES_MULTI;
- }
- else
- {
- *accept = ACCEPT_NO;
- }
- }
- if(mParentFolder && !handled)
- {
- // store this item to get it in LLFolderBridge::dragItemIntoFolder on drop event.
- mRoot->setDraggingOverItem(this);
- handled = mParentFolder->handleDragAndDropFromChild(mask,drop,cargo_type,cargo_data,accept,tooltip_msg);
- mRoot->setDraggingOverItem(NULL);
- }
- if (handled)
- {
- lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderViewItem" << llendl;
- }
-
- return handled;
-}
-
-void LLFolderViewItem::draw()
-{
- static LLUIColor sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
- static LLUIColor sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
- static LLUIColor sHighlightFgColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE);
- static LLUIColor sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE);
- static LLUIColor sFilterBGColor = LLUIColorTable::instance().getColor("FilterBackgroundColor", DEFAULT_WHITE);
- static LLUIColor sFilterTextColor = LLUIColorTable::instance().getColor("FilterTextColor", DEFAULT_WHITE);
- static LLUIColor sSuffixColor = LLUIColorTable::instance().getColor("InventoryItemColor", DEFAULT_WHITE);
- static LLUIColor sLibraryColor = LLUIColorTable::instance().getColor("InventoryItemLibraryColor", DEFAULT_WHITE);
- static LLUIColor sLinkColor = LLUIColorTable::instance().getColor("InventoryItemLinkColor", DEFAULT_WHITE);
- static LLUIColor sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", DEFAULT_WHITE);
- static LLUIColor sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);
-
- const Params& default_params = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
- const S32 TOP_PAD = default_params.item_top_pad;
- const S32 FOCUS_LEFT = 1;
- const LLFontGL* font = getLabelFontForStyle(mLabelStyle);
-
- const LLUUID uuid = (getListener() ? getListener()->getUUID() : LLUUID::null);
- const BOOL in_inventory = (uuid.notNull() ? gInventory.isObjectDescendentOf(uuid, gInventory.getRootFolderID()) : FALSE);
- const BOOL in_library = (uuid.notNull() ? gInventory.isObjectDescendentOf(uuid, gInventory.getLibraryRootFolderID()) : FALSE);
-
- //--------------------------------------------------------------------------------//
- // Draw open folder arrow
- //
- const bool up_to_date = mListener && mListener->isUpToDate();
- const bool possibly_has_children = ((up_to_date && hasVisibleChildren()) // we fetched our children and some of them have passed the filter...
- || (!up_to_date && mListener && mListener->hasChildren())); // ...or we know we have children but haven't fetched them (doesn't obey filter)
- if (possibly_has_children)
- {
- LLUIImage* arrow_image = default_params.folder_arrow_image;
- gl_draw_scaled_rotated_image(
- mIndentation, getRect().getHeight() - ARROW_SIZE - TEXT_PAD - TOP_PAD,
- ARROW_SIZE, ARROW_SIZE, mControlLabelRotation, arrow_image->getImage(), sFgColor);
- }
-
-
- //--------------------------------------------------------------------------------//
- // Draw highlight for selected items
- //
- const BOOL show_context = (getRoot() ? getRoot()->getShowSelectionContext() : FALSE);
- const BOOL filled = show_context || (getRoot() ? getRoot()->getParentPanel()->hasFocus() : FALSE); // If we have keyboard focus, draw selection filled
- const S32 focus_top = getRect().getHeight();
- const S32 focus_bottom = getRect().getHeight() - mItemHeight;
- const bool folder_open = (getRect().getHeight() > mItemHeight + 4);
- if (mIsSelected) // always render "current" item. Only render other selected items if mShowSingleSelection is FALSE
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLColor4 bg_color = sHighlightBgColor;
- if (!mIsCurSelection)
- {
- // do time-based fade of extra objects
- F32 fade_time = (getRoot() ? getRoot()->getSelectionFadeElapsedTime() : 0.0f);
- if (getRoot() && getRoot()->getShowSingleSelection())
- {
- // fading out
- bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, bg_color.mV[VALPHA], 0.f);
- }
- else
- {
- // fading in
- bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, 0.f, bg_color.mV[VALPHA]);
- }
- }
- gl_rect_2d(FOCUS_LEFT,
- focus_top,
- getRect().getWidth() - 2,
- focus_bottom,
- bg_color, filled);
- if (mIsCurSelection)
- {
- gl_rect_2d(FOCUS_LEFT,
- focus_top,
- getRect().getWidth() - 2,
- focus_bottom,
- sFocusOutlineColor, FALSE);
- }
- if (folder_open)
- {
- gl_rect_2d(FOCUS_LEFT,
- focus_bottom + 1, // overlap with bottom edge of above rect
- getRect().getWidth() - 2,
- 0,
- sFocusOutlineColor, FALSE);
- if (show_context)
- {
- gl_rect_2d(FOCUS_LEFT,
- focus_bottom + 1,
- getRect().getWidth() - 2,
- 0,
- sHighlightBgColor, TRUE);
- }
- }
- }
- else if (mIsMouseOverTitle)
- {
- gl_rect_2d(FOCUS_LEFT,
- focus_top,
- getRect().getWidth() - 2,
- focus_bottom,
- sMouseOverColor, FALSE);
- }
-
- //--------------------------------------------------------------------------------//
- // Draw DragNDrop highlight
- //
- if (mDragAndDropTarget)
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gl_rect_2d(FOCUS_LEFT,
- focus_top,
- getRect().getWidth() - 2,
- focus_bottom,
- sHighlightBgColor, FALSE);
- if (folder_open)
- {
- gl_rect_2d(FOCUS_LEFT,
- focus_bottom + 1, // overlap with bottom edge of above rect
- getRect().getWidth() - 2,
- 0,
- sHighlightBgColor, FALSE);
- }
- mDragAndDropTarget = FALSE;
- }
-
- const LLViewerInventoryItem *item = getInventoryItem();
- const BOOL highlight_link = mIconOverlay && item && item->getIsLinkType();
- //--------------------------------------------------------------------------------//
- // Draw open icon
- //
- const S32 icon_x = mIndentation + ARROW_SIZE + TEXT_PAD;
- if (!mIconOpen.isNull() && (llabs(mControlLabelRotation) > 80)) // For open folders
- {
- mIconOpen->draw(icon_x, getRect().getHeight() - mIconOpen->getHeight() - TOP_PAD + 1);
- }
- else if (mIcon)
- {
- mIcon->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1);
- }
-
- if (highlight_link)
- {
- mIconOverlay->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1);
- }
-
- //--------------------------------------------------------------------------------//
- // Exit if no label to draw
- //
- if (mLabel.empty())
- {
- return;
- }
-
- LLColor4 color = (mIsSelected && filled) ? sHighlightFgColor : sFgColor;
- if (highlight_link) color = sLinkColor;
- if (in_library) color = sLibraryColor;
-
- F32 right_x = 0;
- F32 y = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD;
- F32 text_left = (F32)(ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + mIndentation);
-
- //--------------------------------------------------------------------------------//
- // Highlight filtered text
- //
- if (getRoot() && getRoot()->getDebugFilters())
- {
- if (!getFiltered() && !possibly_has_children)
- {
- color.mV[VALPHA] *= 0.5f;
- }
- LLColor4 filter_color = mLastFilterGeneration >= getRoot()->getFilter()->getCurrentGeneration() ?
- LLColor4(0.5f, 0.8f, 0.5f, 1.f) :
- LLColor4(0.8f, 0.5f, 0.5f, 1.f);
- LLFontGL::getFontMonospace()->renderUTF8(mStatusText, 0, text_left, y, filter_color,
- LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
- S32_MAX, S32_MAX, &right_x, FALSE );
- text_left = right_x;
- }
- //--------------------------------------------------------------------------------//
- // Draw the actual label text
- //
- font->renderUTF8(mLabel, 0, text_left, y, color,
- LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
- S32_MAX, getRect().getWidth() - (S32) text_left, &right_x, TRUE);
-
- //--------------------------------------------------------------------------------//
- // Draw "Loading..." text
- //
- bool root_is_loading = false;
- if (in_inventory)
- {
- root_is_loading = LLInventoryModelBackgroundFetch::instance().inventoryFetchInProgress();
- }
- if (in_library)
- {
- root_is_loading = LLInventoryModelBackgroundFetch::instance().libraryFetchInProgress();
- }
- if ((mIsLoading
- && mTimeSinceRequestStart.getElapsedTimeF32() >= gSavedSettings.getF32("FolderLoadingMessageWaitTime"))
- || (LLInventoryModelBackgroundFetch::instance().folderFetchActive()
- && root_is_loading
- && mShowLoadStatus))
- {
- std::string load_string = " ( " + LLTrans::getString("LoadingData") + " ) ";
- font->renderUTF8(load_string, 0, right_x, y, sSearchStatusColor,
- LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
- S32_MAX, S32_MAX, &right_x, FALSE);
- }
-
- //--------------------------------------------------------------------------------//
- // Draw label suffix
- //
- if (!mLabelSuffix.empty())
- {
- font->renderUTF8( mLabelSuffix, 0, right_x, y, sSuffixColor,
- LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
- S32_MAX, S32_MAX, &right_x, FALSE );
- }
-
- //--------------------------------------------------------------------------------//
- // Highlight string match
- //
- if (mStringMatchOffset != std::string::npos)
- {
- // don't draw backgrounds for zero-length strings
- S32 filter_string_length = (getRoot() ? getRoot()->getFilterSubString().size() : 0);
- if (filter_string_length > 0)
- {
- std::string combined_string = mLabel + mLabelSuffix;
- S32 left = llround(text_left) + font->getWidth(combined_string, 0, mStringMatchOffset) - 1;
- S32 right = left + font->getWidth(combined_string, mStringMatchOffset, filter_string_length) + 2;
- S32 bottom = llfloor(getRect().getHeight() - font->getLineHeight() - 3 - TOP_PAD);
- S32 top = getRect().getHeight() - TOP_PAD;
-
- LLUIImage* box_image = default_params.selection_image;
- LLRect box_rect(left, top, right, bottom);
- box_image->draw(box_rect, sFilterBGColor);
- F32 match_string_left = text_left + font->getWidthF32(combined_string, 0, mStringMatchOffset);
- F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD;
- font->renderUTF8( combined_string, mStringMatchOffset, match_string_left, yy,
- sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
- filter_string_length, S32_MAX, &right_x, FALSE );
- }
- }
-}
-
-
-///----------------------------------------------------------------------------
-/// Class LLFolderViewFolder
-///----------------------------------------------------------------------------
-
-LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ):
- LLFolderViewItem( p ), // 0 = no create time
- mIsOpen(FALSE),
- mExpanderHighlighted(FALSE),
- mCurHeight(0.f),
- mTargetHeight(0.f),
- mAutoOpenCountdown(0.f),
- mSubtreeCreationDate(0),
- mAmTrash(LLFolderViewFolder::UNKNOWN),
- mLastArrangeGeneration( -1 ),
- mLastCalculatedWidth(0),
- mCompletedFilterGeneration(-1),
- mMostFilteredDescendantGeneration(-1),
- mNeedsSort(false),
- mPassedFolderFilter(FALSE)
-{
-}
-
-// Destroys the object
-LLFolderViewFolder::~LLFolderViewFolder( void )
-{
- // The LLView base class takes care of object destruction. make sure that we
- // don't have mouse or keyboard focus
- gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit()
-}
-
-void LLFolderViewFolder::setFilteredFolder(bool filtered, S32 filter_generation)
-{
- mPassedFolderFilter = filtered;
- mLastFilterGeneration = filter_generation;
-}
-
-bool LLFolderViewFolder::getFilteredFolder(S32 filter_generation)
-{
- return mPassedFolderFilter && mLastFilterGeneration >= getRoot()->getFilter()->getMinRequiredGeneration();
-}
-
-// addToFolder() returns TRUE if it succeeds. FALSE otherwise
-BOOL LLFolderViewFolder::addToFolder(LLFolderViewFolder* folder, LLFolderView* root)
-{
- if (!folder)
- {
- return FALSE;
- }
- mParentFolder = folder;
- root->addItemID(getListener()->getUUID(), this);
- return folder->addFolder(this);
-}
-
-// Finds width and height of this object and its children. Also
-// makes sure that this view and its children are the right size.
-S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)
-{
- // sort before laying out contents
- if (mNeedsSort)
- {
- mFolders.sort(mSortFunction);
- mItems.sort(mSortFunction);
- mNeedsSort = false;
- }
-
- // evaluate mHasVisibleChildren
- mHasVisibleChildren = false;
- if (hasFilteredDescendants(filter_generation))
- {
- // We have to verify that there's at least one child that's not filtered out
- bool found = false;
- // Try the items first
- for (items_t::iterator iit = mItems.begin(); iit != mItems.end(); ++iit)
- {
- LLFolderViewItem* itemp = (*iit);
- found = (itemp->getFiltered(filter_generation));
- if (found)
- break;
- }
- if (!found)
- {
- // If no item found, try the folders
- for (folders_t::iterator fit = mFolders.begin(); fit != mFolders.end(); ++fit)
- {
- LLFolderViewFolder* folderp = (*fit);
- found = ( folderp->getListener()
- && (folderp->getFiltered(filter_generation)
- || (folderp->getFilteredFolder(filter_generation)
- && folderp->hasFilteredDescendants(filter_generation))));
- if (found)
- break;
- }
- }
-
- mHasVisibleChildren = found;
- }
-
- // calculate height as a single item (without any children), and reshapes rectangle to match
- LLFolderViewItem::arrange( width, height, filter_generation );
-
- // clamp existing animated height so as to never get smaller than a single item
- mCurHeight = llmax((F32)*height, mCurHeight);
-
- // initialize running height value as height of single item in case we have no children
- *height = getItemHeight();
- F32 running_height = (F32)*height;
- F32 target_height = (F32)*height;
-
- // are my children visible?
- if (needsArrange())
- {
- // set last arrange generation first, in case children are animating
- // and need to be arranged again
- mLastArrangeGeneration = getRoot()->getArrangeGeneration();
- if (mIsOpen)
- {
- // Add sizes of children
- S32 parent_item_height = getRect().getHeight();
-
- for(folders_t::iterator fit = mFolders.begin(); fit != mFolders.end(); ++fit)
- {
- LLFolderViewFolder* folderp = (*fit);
- if (getRoot()->getDebugFilters())
- {
- folderp->setVisible(TRUE);
- }
- else
- {
- folderp->setVisible( folderp->getListener()
- && (folderp->getFiltered(filter_generation)
- || (folderp->getFilteredFolder(filter_generation)
- && folderp->hasFilteredDescendants(filter_generation)))); // passed filter or has descendants that passed filter
- }
-
- if (folderp->getVisible())
- {
- S32 child_width = *width;
- S32 child_height = 0;
- S32 child_top = parent_item_height - llround(running_height);
-
- target_height += folderp->arrange( &child_width, &child_height, filter_generation );
-
- running_height += (F32)child_height;
- *width = llmax(*width, child_width);
- folderp->setOrigin( 0, child_top - folderp->getRect().getHeight() );
- }
- }
- for(items_t::iterator iit = mItems.begin();
- iit != mItems.end(); ++iit)
- {
- LLFolderViewItem* itemp = (*iit);
- if (getRoot()->getDebugFilters())
- {
- itemp->setVisible(TRUE);
- }
- else
- {
- itemp->setVisible(itemp->getFiltered(filter_generation));
- }
-
- if (itemp->getVisible())
- {
- S32 child_width = *width;
- S32 child_height = 0;
- S32 child_top = parent_item_height - llround(running_height);
-
- target_height += itemp->arrange( &child_width, &child_height, filter_generation );
- // don't change width, as this item is as wide as its parent folder by construction
- itemp->reshape( itemp->getRect().getWidth(), child_height);
-
- running_height += (F32)child_height;
- *width = llmax(*width, child_width);
- itemp->setOrigin( 0, child_top - itemp->getRect().getHeight() );
- }
- }
- }
-
- mTargetHeight = target_height;
- // cache this width so next time we can just return it
- mLastCalculatedWidth = *width;
- }
- else
- {
- // just use existing width
- *width = mLastCalculatedWidth;
- }
-
- // animate current height towards target height
- if (llabs(mCurHeight - mTargetHeight) > 1.f)
- {
- mCurHeight = lerp(mCurHeight, mTargetHeight, LLCriticalDamp::getInterpolant(mIsOpen ? FOLDER_OPEN_TIME_CONSTANT : FOLDER_CLOSE_TIME_CONSTANT));
-
- requestArrange();
-
- // hide child elements that fall out of current animated height
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- // number of pixels that bottom of folder label is from top of parent folder
- if (getRect().getHeight() - (*fit)->getRect().mTop + (*fit)->getItemHeight()
- > llround(mCurHeight) + MAX_FOLDER_ITEM_OVERLAP)
- {
- // hide if beyond current folder height
- (*fit)->setVisible(FALSE);
- }
- }
-
- for (items_t::iterator iter = mItems.begin();
- iter != mItems.end();)
- {
- items_t::iterator iit = iter++;
- // number of pixels that bottom of item label is from top of parent folder
- if (getRect().getHeight() - (*iit)->getRect().mBottom
- > llround(mCurHeight) + MAX_FOLDER_ITEM_OVERLAP)
- {
- (*iit)->setVisible(FALSE);
- }
- }
- }
- else
- {
- mCurHeight = mTargetHeight;
- }
-
- // don't change width as this item is already as wide as its parent folder
- reshape(getRect().getWidth(),llround(mCurHeight));
-
- // pass current height value back to parent
- *height = llround(mCurHeight);
-
- return llround(mTargetHeight);
-}
-
-BOOL LLFolderViewFolder::needsArrange()
-{
- return mLastArrangeGeneration < getRoot()->getArrangeGeneration();
-}
-
-void LLFolderViewFolder::requestSort()
-{
- mNeedsSort = true;
- // whenever item order changes, we need to lay things out again
- requestArrange();
-}
-
-void LLFolderViewFolder::setCompletedFilterGeneration(S32 generation, BOOL recurse_up)
-{
- //mMostFilteredDescendantGeneration = llmin(mMostFilteredDescendantGeneration, generation);
- mCompletedFilterGeneration = generation;
- // only aggregate up if we are a lower (older) value
- if (recurse_up
- && mParentFolder
- && generation < mParentFolder->getCompletedFilterGeneration())
- {
- mParentFolder->setCompletedFilterGeneration(generation, TRUE);
- }
-}
-
-void LLFolderViewFolder::filter( LLInventoryFilter& filter)
-{
- S32 filter_generation = filter.getCurrentGeneration();
- // 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();
-
- bool autoopen_folders = (filter.hasFilterString());
-
- // if we have already been filtered against this generation, skip out
- if (getCompletedFilterGeneration() >= filter_generation)
- {
- return;
- }
-
- // filter folder itself
- if (getLastFilterGeneration() < filter_generation)
- {
- if (getLastFilterGeneration() >= must_pass_generation // folder has been compared to a valid precursor filter
- && !mPassedFilter) // and did not pass the filter
- {
- // go ahead and flag this folder as done
- mLastFilterGeneration = filter_generation;
- mStringMatchOffset = std::string::npos;
- }
- else // filter self only on first pass through
- {
- // filter against folder rules
- filterFolder(filter);
- // and then item rules
- LLFolderViewItem::filter( filter );
- }
- }
-
- if (getRoot()->getDebugFilters())
- {
- mStatusText = llformat("%d", mLastFilterGeneration);
- mStatusText += llformat("(%d)", mCompletedFilterGeneration);
- mStatusText += llformat("+%d", mMostFilteredDescendantGeneration);
- }
-
- // all descendants have been filtered later than must pass generation
- // but none passed
- if(getCompletedFilterGeneration() >= must_pass_generation && !hasFilteredDescendants(must_pass_generation))
- {
- // don't traverse children if we've already filtered them since must_pass_generation
- // and came back with nothing
- return;
- }
-
- // we entered here with at least one filter iteration left
- // check to see if we have any more before continuing on to children
- if (filter.getFilterCount() < 0)
- {
- return;
- }
-
- // when applying a filter, matching folders get their contents downloaded first
- if (filter.isNotDefault()
- && getFiltered(filter.getMinRequiredGeneration())
- && (mListener
- && !gInventory.isCategoryComplete(mListener->getUUID())))
- {
- LLInventoryModelBackgroundFetch::instance().start(mListener->getUUID());
- }
-
- // now query children
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();
- ++iter)
- {
- LLFolderViewFolder* folder = (*iter);
- // have we run out of iterations this frame?
- if (filter.getFilterCount() < 0)
- {
- break;
- }
-
- // mMostFilteredDescendantGeneration might have been reset
- // in which case we need to update it even for folders that
- // don't need to be filtered anymore
- if (folder->getCompletedFilterGeneration() >= filter_generation)
- {
- // track latest generation to pass any child items
- if (folder->getFiltered() || folder->hasFilteredDescendants(filter.getMinRequiredGeneration()))
- {
- mMostFilteredDescendantGeneration = filter_generation;
- requestArrange();
- }
- // just skip it, it has already been filtered
- continue;
- }
-
- // update this folders filter status (and children)
- folder->filter( filter );
-
- // track latest generation to pass any child items
- if (folder->getFiltered() || folder->hasFilteredDescendants(filter_generation))
- {
- mMostFilteredDescendantGeneration = filter_generation;
- requestArrange();
- if (getRoot()->needsAutoSelect() && autoopen_folders)
- {
- folder->setOpenArrangeRecursively(TRUE);
- }
- }
- }
-
- for (items_t::iterator iter = mItems.begin();
- iter != mItems.end();
- ++iter)
- {
- LLFolderViewItem* item = (*iter);
- if (filter.getFilterCount() < 0)
- {
- break;
- }
- if (item->getLastFilterGeneration() >= filter_generation)
- {
- if (item->getFiltered())
- {
- mMostFilteredDescendantGeneration = filter_generation;
- requestArrange();
- }
- continue;
- }
-
- if (item->getLastFilterGeneration() >= must_pass_generation &&
- !item->getFiltered(must_pass_generation))
- {
- // failed to pass an earlier filter that was a subset of the current one
- // go ahead and flag this item as done
- item->setFiltered(FALSE, filter_generation);
- continue;
- }
-
- item->filter( filter );
-
- if (item->getFiltered(filter.getMinRequiredGeneration()))
- {
- mMostFilteredDescendantGeneration = filter_generation;
- requestArrange();
- }
- }
-
- // if we didn't use all filter iterations
- // that means we filtered all of our descendants
- // instead of exhausting the filter count for this frame
- if (filter.getFilterCount() > 0)
- {
- // flag this folder as having completed filter pass for all descendants
- setCompletedFilterGeneration(filter_generation, FALSE/*dont recurse up to root*/);
- }
-}
-
-void LLFolderViewFolder::filterFolder(LLInventoryFilter& filter)
-{
- const BOOL previous_passed_filter = mPassedFolderFilter;
- const BOOL passed_filter = filter.checkFolder(this);
-
- // If our visibility will change as a result of this filter, then
- // we need to be rearranged in our parent folder
- if (mParentFolder)
- {
- if (getVisible() != passed_filter
- || previous_passed_filter != passed_filter )
- {
- mParentFolder->requestArrange();
- }
- }
-
- setFilteredFolder(passed_filter, filter.getCurrentGeneration());
- filter.decrementFilterCount();
-
- if (getRoot()->getDebugFilters())
- {
- mStatusText = llformat("%d", mLastFilterGeneration);
- }
-}
-
-void LLFolderViewFolder::setFiltered(BOOL filtered, S32 filter_generation)
-{
- // if this folder is now filtered, but wasn't before
- // (it just passed)
- if (filtered && !mPassedFilter)
- {
- // reset current height, because last time we drew it
- // it might have had more visible items than now
- mCurHeight = 0.f;
- }
-
- LLFolderViewItem::setFiltered(filtered, filter_generation);
-}
-
-void LLFolderViewFolder::dirtyFilter()
-{
- // we're a folder, so invalidate our completed generation
- setCompletedFilterGeneration(-1, FALSE);
- LLFolderViewItem::dirtyFilter();
-}
-
-BOOL LLFolderViewFolder::getFiltered()
-{
- return getFilteredFolder(getRoot()->getFilter()->getMinRequiredGeneration())
- && LLFolderViewItem::getFiltered();
-}
-
-BOOL LLFolderViewFolder::getFiltered(S32 filter_generation)
-{
- return getFilteredFolder(filter_generation) && LLFolderViewItem::getFiltered(filter_generation);
-}
-
-BOOL LLFolderViewFolder::hasFilteredDescendants(S32 filter_generation)
-{
- return mMostFilteredDescendantGeneration >= filter_generation;
-}
-
-
-BOOL LLFolderViewFolder::hasFilteredDescendants()
-{
- return mMostFilteredDescendantGeneration >= getRoot()->getFilter()->getCurrentGeneration();
-}
-
-// Passes selection information on to children and record selection
-// information if necessary.
-BOOL LLFolderViewFolder::setSelection(LLFolderViewItem* selection, BOOL openitem,
- BOOL take_keyboard_focus)
-{
- BOOL rv = FALSE;
- if (selection == this)
- {
- if (!isSelected())
- {
- selectItem();
- }
- rv = TRUE;
- }
- else
- {
- if (isSelected())
- {
- deselectItem();
- }
- rv = FALSE;
- }
- BOOL child_selected = FALSE;
-
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- if((*fit)->setSelection(selection, openitem, take_keyboard_focus))
- {
- rv = TRUE;
- child_selected = TRUE;
- }
- }
- for (items_t::iterator iter = mItems.begin();
- iter != mItems.end();)
- {
- items_t::iterator iit = iter++;
- if((*iit)->setSelection(selection, openitem, take_keyboard_focus))
- {
- rv = TRUE;
- child_selected = TRUE;
- }
- }
- if(openitem && child_selected)
- {
- setOpenArrangeRecursively(TRUE);
- }
- return rv;
-}
-
-// This method is used to change the selection of an item.
-// Recursively traverse all children; if 'selection' is 'this' then change
-// the select status if necessary.
-// Returns TRUE if the selection state of this folder, or of a child, was changed.
-BOOL LLFolderViewFolder::changeSelection(LLFolderViewItem* selection, BOOL selected)
-{
- BOOL rv = FALSE;
- if(selection == this)
- {
- if (isSelected() != selected)
- {
- rv = TRUE;
- if (selected)
- {
- selectItem();
- }
- else
- {
- deselectItem();
- }
- }
- }
-
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- if((*fit)->changeSelection(selection, selected))
- {
- rv = TRUE;
- }
- }
- for (items_t::iterator iter = mItems.begin();
- iter != mItems.end();)
- {
- items_t::iterator iit = iter++;
- if((*iit)->changeSelection(selection, selected))
- {
- rv = TRUE;
- }
- }
- return rv;
-}
-
-LLFolderViewFolder* LLFolderViewFolder::getCommonAncestor(LLFolderViewItem* item_a, LLFolderViewItem* item_b, bool& reverse)
-{
- if (!item_a->getParentFolder() || !item_b->getParentFolder()) return NULL;
-
- std::deque<LLFolderViewFolder*> item_a_ancestors;
-
- LLFolderViewFolder* parent = item_a->getParentFolder();
- while(parent)
- {
- item_a_ancestors.push_back(parent);
- parent = parent->getParentFolder();
- }
-
- std::deque<LLFolderViewFolder*> item_b_ancestors;
-
- parent = item_b->getParentFolder();
- while(parent)
- {
- item_b_ancestors.push_back(parent);
- parent = parent->getParentFolder();
- }
-
- LLFolderViewFolder* common_ancestor = item_a->getRoot();
-
- while(item_a_ancestors.size() > item_b_ancestors.size())
- {
- item_a = item_a_ancestors.front();
- item_a_ancestors.pop_front();
- }
-
- while(item_b_ancestors.size() > item_a_ancestors.size())
- {
- item_b = item_b_ancestors.front();
- item_b_ancestors.pop_front();
- }
-
- while(item_a_ancestors.size())
- {
- common_ancestor = item_a_ancestors.front();
-
- if (item_a_ancestors.front() == item_b_ancestors.front())
- {
- // which came first, sibling a or sibling b?
- for (folders_t::iterator it = common_ancestor->mFolders.begin(), end_it = common_ancestor->mFolders.end();
- it != end_it;
- ++it)
- {
- LLFolderViewItem* item = *it;
-
- if (item == item_a)
- {
- reverse = false;
- return common_ancestor;
- }
- if (item == item_b)
- {
- reverse = true;
- return common_ancestor;
- }
- }
-
- for (items_t::iterator it = common_ancestor->mItems.begin(), end_it = common_ancestor->mItems.end();
- it != end_it;
- ++it)
- {
- LLFolderViewItem* item = *it;
-
- if (item == item_a)
- {
- reverse = false;
- return common_ancestor;
- }
- if (item == item_b)
- {
- reverse = true;
- return common_ancestor;
- }
- }
- break;
- }
-
- item_a = item_a_ancestors.front();
- item_a_ancestors.pop_front();
- item_b = item_b_ancestors.front();
- item_b_ancestors.pop_front();
- }
-
- return NULL;
-}
-
-void LLFolderViewFolder::gatherChildRangeExclusive(LLFolderViewItem* start, LLFolderViewItem* end, bool reverse, std::vector<LLFolderViewItem*>& items)
-{
- bool selecting = start == NULL;
- if (reverse)
- {
- for (items_t::reverse_iterator it = mItems.rbegin(), end_it = mItems.rend();
- it != end_it;
- ++it)
- {
- if (*it == end)
- {
- return;
- }
- if (selecting)
- {
- items.push_back(*it);
- }
-
- if (*it == start)
- {
- selecting = true;
- }
- }
- for (folders_t::reverse_iterator it = mFolders.rbegin(), end_it = mFolders.rend();
- it != end_it;
- ++it)
- {
- if (*it == end)
- {
- return;
- }
-
- if (selecting)
- {
- items.push_back(*it);
- }
-
- if (*it == start)
- {
- selecting = true;
- }
- }
- }
- else
- {
- for (folders_t::iterator it = mFolders.begin(), end_it = mFolders.end();
- it != end_it;
- ++it)
- {
- if (*it == end)
- {
- return;
- }
-
- if (selecting)
- {
- items.push_back(*it);
- }
-
- if (*it == start)
- {
- selecting = true;
- }
- }
- for (items_t::iterator it = mItems.begin(), end_it = mItems.end();
- it != end_it;
- ++it)
- {
- if (*it == end)
- {
- return;
- }
-
- if (selecting)
- {
- items.push_back(*it);
- }
-
- if (*it == start)
- {
- selecting = true;
- }
- }
- }
-}
-
-void LLFolderViewFolder::extendSelectionTo(LLFolderViewItem* new_selection)
-{
- if (getRoot()->getAllowMultiSelect() == FALSE) return;
-
- LLFolderViewItem* cur_selected_item = getRoot()->getCurSelectedItem();
- if (cur_selected_item == NULL)
- {
- cur_selected_item = new_selection;
- }
-
-
- bool reverse = false;
- LLFolderViewFolder* common_ancestor = getCommonAncestor(cur_selected_item, new_selection, reverse);
- if (!common_ancestor) return;
-
- LLFolderViewItem* last_selected_item_from_cur = cur_selected_item;
- LLFolderViewFolder* cur_folder = cur_selected_item->getParentFolder();
-
- std::vector<LLFolderViewItem*> items_to_select_forward;
-
- while(cur_folder != common_ancestor)
- {
- cur_folder->gatherChildRangeExclusive(last_selected_item_from_cur, NULL, reverse, items_to_select_forward);
-
- last_selected_item_from_cur = cur_folder;
- cur_folder = cur_folder->getParentFolder();
- }
-
- std::vector<LLFolderViewItem*> items_to_select_reverse;
-
- LLFolderViewItem* last_selected_item_from_new = new_selection;
- cur_folder = new_selection->getParentFolder();
- while(cur_folder != common_ancestor)
- {
- cur_folder->gatherChildRangeExclusive(last_selected_item_from_new, NULL, !reverse, items_to_select_reverse);
-
- last_selected_item_from_new = cur_folder;
- cur_folder = cur_folder->getParentFolder();
- }
-
- common_ancestor->gatherChildRangeExclusive(last_selected_item_from_cur, last_selected_item_from_new, reverse, items_to_select_forward);
-
- for (std::vector<LLFolderViewItem*>::reverse_iterator it = items_to_select_reverse.rbegin(), end_it = items_to_select_reverse.rend();
- it != end_it;
- ++it)
- {
- items_to_select_forward.push_back(*it);
- }
-
- LLFolderView* root = getRoot();
-
- for (std::vector<LLFolderViewItem*>::iterator it = items_to_select_forward.begin(), end_it = items_to_select_forward.end();
- it != end_it;
- ++it)
- {
- LLFolderViewItem* item = *it;
- if (item->isSelected())
- {
- root->removeFromSelectionList(item);
- }
- else
- {
- item->selectItem();
- }
- root->addToSelectionList(item);
- }
-
- if (new_selection->isSelected())
- {
- root->removeFromSelectionList(new_selection);
- }
- else
- {
- new_selection->selectItem();
- }
- root->addToSelectionList(new_selection);
-}
-
-
-void LLFolderViewFolder::destroyView()
-{
- for (items_t::iterator iter = mItems.begin();
- iter != mItems.end();)
- {
- items_t::iterator iit = iter++;
- LLFolderViewItem* item = (*iit);
- getRoot()->removeItemID(item->getListener()->getUUID());
- }
-
- std::for_each(mItems.begin(), mItems.end(), DeletePointer());
- mItems.clear();
-
- while (!mFolders.empty())
- {
- LLFolderViewFolder *folderp = mFolders.back();
- folderp->destroyView(); // removes entry from mFolders
- }
-
- //deleteAllChildren();
-
- if (mParentFolder)
- {
- mParentFolder->removeView(this);
- }
-}
-
-// remove the specified item (and any children) if possible. Return
-// TRUE if the item was deleted.
-BOOL LLFolderViewFolder::removeItem(LLFolderViewItem* item)
-{
- if(item->remove())
- {
- return TRUE;
- }
- return FALSE;
-}
-
-// simply remove the view (and any children) Don't bother telling the
-// listeners.
-void LLFolderViewFolder::removeView(LLFolderViewItem* item)
-{
- if (!item || item->getParentFolder() != this)
- {
- return;
- }
- // deselect without traversing hierarchy
- if (item->isSelected())
- {
- item->deselectItem();
- }
- getRoot()->removeFromSelectionList(item);
- extractItem(item);
- delete item;
-}
-
-// extractItem() removes the specified item from the folder, but
-// doesn't delete it.
-void LLFolderViewFolder::extractItem( LLFolderViewItem* item )
-{
- items_t::iterator it = std::find(mItems.begin(), mItems.end(), item);
- if(it == mItems.end())
- {
- // This is an evil downcast. However, it's only doing
- // pointer comparison to find if (which it should be ) the
- // item is in the container, so it's pretty safe.
- LLFolderViewFolder* f = static_cast<LLFolderViewFolder*>(item);
- folders_t::iterator ft;
- ft = std::find(mFolders.begin(), mFolders.end(), f);
- if (ft != mFolders.end())
- {
- mFolders.erase(ft);
- }
- }
- else
- {
- mItems.erase(it);
- }
- //item has been removed, need to update filter
- dirtyFilter();
- //because an item is going away regardless of filter status, force rearrange
- requestArrange();
- getRoot()->removeItemID(item->getListener()->getUUID());
- removeChild(item);
-}
-
-bool LLFolderViewFolder::isTrash() const
-{
- if (mAmTrash == LLFolderViewFolder::UNKNOWN)
- {
- mAmTrash = mListener->getUUID() == gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH, false) ? LLFolderViewFolder::TRASH : LLFolderViewFolder::NOT_TRASH;
- }
- return mAmTrash == LLFolderViewFolder::TRASH;
-}
-
-void LLFolderViewFolder::sortBy(U32 order)
-{
- if (!mSortFunction.updateSort(order))
- {
- // No changes.
- return;
- }
-
- // Propagate this change to sub folders
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- (*fit)->sortBy(order);
- }
-
- // Don't sort the topmost folders (My Inventory and Library)
- if (mListener->getUUID().notNull())
- {
- mFolders.sort(mSortFunction);
- mItems.sort(mSortFunction);
- }
-
- if (order & LLInventoryFilter::SO_DATE)
- {
- time_t latest = 0;
-
- if (!mItems.empty())
- {
- LLFolderViewItem* item = *(mItems.begin());
- latest = item->getCreationDate();
- }
-
- if (!mFolders.empty())
- {
- LLFolderViewFolder* folder = *(mFolders.begin());
- if (folder->getCreationDate() > latest)
- {
- latest = folder->getCreationDate();
- }
- }
- mSubtreeCreationDate = latest;
- }
-}
-
-void LLFolderViewFolder::setItemSortOrder(U32 ordering)
-{
- if (mSortFunction.updateSort(ordering))
- {
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- (*fit)->setItemSortOrder(ordering);
- }
-
- mFolders.sort(mSortFunction);
- mItems.sort(mSortFunction);
- }
-}
-
-EInventorySortGroup LLFolderViewFolder::getSortGroup() const
-{
- if (isTrash())
- {
- return SG_TRASH_FOLDER;
- }
-
- if( mListener )
- {
- if(LLFolderType::lookupIsProtectedType(mListener->getPreferredType()))
- {
- return SG_SYSTEM_FOLDER;
- }
- }
-
- return SG_NORMAL_FOLDER;
-}
-
-BOOL LLFolderViewFolder::isMovable()
-{
- if( mListener )
- {
- if( !(mListener->isItemMovable()) )
- {
- return FALSE;
- }
-
- for (items_t::iterator iter = mItems.begin();
- iter != mItems.end();)
- {
- items_t::iterator iit = iter++;
- if(!(*iit)->isMovable())
- {
- return FALSE;
- }
- }
-
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- if(!(*fit)->isMovable())
- {
- return FALSE;
- }
- }
- }
- return TRUE;
-}
-
-
-BOOL LLFolderViewFolder::isRemovable()
-{
- if( mListener )
- {
- if( !(mListener->isItemRemovable()) )
- {
- return FALSE;
- }
-
- for (items_t::iterator iter = mItems.begin();
- iter != mItems.end();)
- {
- items_t::iterator iit = iter++;
- if(!(*iit)->isRemovable())
- {
- return FALSE;
- }
- }
-
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- if(!(*fit)->isRemovable())
- {
- return FALSE;
- }
- }
- }
- return TRUE;
-}
-
-// this is an internal method used for adding items to folders.
-BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)
-{
- mItems.push_back(item);
-
- item->setRect(LLRect(0, 0, getRect().getWidth(), 0));
- item->setVisible(FALSE);
-
- addChild(item);
-
- item->dirtyFilter();
-
- // Update the folder creation date if the folder has no creation date
- bool setting_date = false;
- const time_t item_creation_date = item->getCreationDate();
- if ((item_creation_date > 0) && (mCreationDate == 0))
- {
- setCreationDate(item_creation_date);
- setting_date = true;
- }
-
- // Handle sorting
- requestArrange();
- requestSort();
-
- // Traverse parent folders and update creation date and resort, if necessary
- LLFolderViewFolder* parentp = getParentFolder();
- while (parentp)
- {
- // Update the parent folder creation date
- if (setting_date && (parentp->mCreationDate == 0))
- {
- parentp->setCreationDate(item_creation_date);
- }
-
- if (parentp->mSortFunction.isByDate())
- {
- // parent folder doesn't have a time stamp yet, so get it from us
- parentp->requestSort();
- }
-
- parentp = parentp->getParentFolder();
- }
-
- return TRUE;
-}
-
-// this is an internal method used for adding items to folders.
-BOOL LLFolderViewFolder::addFolder(LLFolderViewFolder* folder)
-{
- mFolders.push_back(folder);
- folder->setOrigin(0, 0);
- folder->reshape(getRect().getWidth(), 0);
- folder->setVisible(FALSE);
- addChild( folder );
- folder->dirtyFilter();
- // rearrange all descendants too, as our indentation level might have changed
- folder->requestArrange(TRUE);
- requestSort();
- LLFolderViewFolder* parentp = getParentFolder();
- while (parentp && !parentp->mSortFunction.isByDate())
- {
- // parent folder doesn't have a time stamp yet, so get it from us
- parentp->requestSort();
- parentp = parentp->getParentFolder();
- }
- return TRUE;
-}
-
-void LLFolderViewFolder::requestArrange(BOOL include_descendants)
-{
- mLastArrangeGeneration = -1;
- // flag all items up to root
- if (mParentFolder)
- {
- mParentFolder->requestArrange();
- }
-
- if (include_descendants)
- {
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();
- ++iter)
- {
- (*iter)->requestArrange(TRUE);
- }
- }
-}
-
-void LLFolderViewFolder::toggleOpen()
-{
- setOpen(!mIsOpen);
-}
-
-// Force a folder open or closed
-void LLFolderViewFolder::setOpen(BOOL openitem)
-{
- setOpenArrangeRecursively(openitem);
-}
-
-void LLFolderViewFolder::setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse)
-{
- BOOL was_open = mIsOpen;
- mIsOpen = openitem;
- if (mListener)
- {
- if(!was_open && openitem)
- {
- mListener->openItem();
- }
- else if(was_open && !openitem)
- {
- mListener->closeItem();
- }
- }
-
- if (recurse == RECURSE_DOWN || recurse == RECURSE_UP_DOWN)
- {
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- (*fit)->setOpenArrangeRecursively(openitem, RECURSE_DOWN); /* Flawfinder: ignore */
- }
- }
- if (mParentFolder
- && (recurse == RECURSE_UP
- || recurse == RECURSE_UP_DOWN))
- {
- mParentFolder->setOpenArrangeRecursively(openitem, RECURSE_UP);
- }
-
- if (was_open != mIsOpen)
- {
- requestArrange();
- }
-}
-
-BOOL LLFolderViewFolder::handleDragAndDropFromChild(MASK mask,
- BOOL drop,
- EDragAndDropType c_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg)
-{
- BOOL accepted = mListener && mListener->dragOrDrop(mask,drop,c_type,cargo_data, tooltip_msg);
- if (accepted)
- {
- mDragAndDropTarget = TRUE;
- *accept = ACCEPT_YES_MULTI;
- }
- else
- {
- *accept = ACCEPT_NO;
- }
-
- // drag and drop to child item, so clear pending auto-opens
- getRoot()->autoOpenTest(NULL);
-
- return TRUE;
-}
-
-void LLFolderViewFolder::openItem( void )
-{
- toggleOpen();
-}
-
-void LLFolderViewFolder::applyFunctorToChildren(LLFolderViewFunctor& functor)
-{
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- functor.doItem((*fit));
- }
- for (items_t::iterator iter = mItems.begin();
- iter != mItems.end();)
- {
- items_t::iterator iit = iter++;
- functor.doItem((*iit));
- }
-}
-
-void LLFolderViewFolder::applyFunctorRecursively(LLFolderViewFunctor& functor)
-{
- functor.doFolder(this);
-
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- (*fit)->applyFunctorRecursively(functor);
- }
- for (items_t::iterator iter = mItems.begin();
- iter != mItems.end();)
- {
- items_t::iterator iit = iter++;
- functor.doItem((*iit));
- }
-}
-
-void LLFolderViewFolder::applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor)
-{
- functor(mListener);
- for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
- {
- folders_t::iterator fit = iter++;
- (*fit)->applyListenerFunctorRecursively(functor);
- }
- for (items_t::iterator iter = mItems.begin();
- iter != mItems.end();)
- {
- items_t::iterator iit = iter++;
- (*iit)->applyListenerFunctorRecursively(functor);
- }
-}
-
-// LLView functionality
-BOOL LLFolderViewFolder::handleDragAndDrop(S32 x, S32 y, MASK mask,
- BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg)
-{
- BOOL handled = FALSE;
-
- if (mIsOpen)
- {
- handled = (childrenHandleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg) != NULL);
- }
-
- if (!handled)
- {
- handleDragAndDropToThisFolder(mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
-
- lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderViewFolder" << llendl;
- }
-
- return TRUE;
-}
-
-BOOL LLFolderViewFolder::handleDragAndDropToThisFolder(MASK mask,
- BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg)
-{
- BOOL accepted = mListener && mListener->dragOrDrop(mask, drop, cargo_type, cargo_data, tooltip_msg);
-
- if (accepted)
- {
- mDragAndDropTarget = TRUE;
- *accept = ACCEPT_YES_MULTI;
- }
- else
- {
- *accept = ACCEPT_NO;
- }
-
- if (!drop && accepted)
- {
- getRoot()->autoOpenTest(this);
- }
-
- return TRUE;
-}
-
-
-BOOL LLFolderViewFolder::handleRightMouseDown( S32 x, S32 y, MASK mask )
-{
- BOOL handled = FALSE;
- // fetch contents of this folder, as context menu can depend on contents
- // still, user would have to open context menu again to see the changes
- gInventory.fetchDescendentsOf(mListener->getUUID());
-
- if( mIsOpen )
- {
- handled = childrenHandleRightMouseDown( x, y, mask ) != NULL;
- }
- if (!handled)
- {
- handled = LLFolderViewItem::handleRightMouseDown( x, y, mask );
- }
- return handled;
-}
-
-
-BOOL LLFolderViewFolder::handleHover(S32 x, S32 y, MASK mask)
-{
- mIsMouseOverTitle = (y > (getRect().getHeight() - mItemHeight));
-
- BOOL handled = LLView::handleHover(x, y, mask);
-
- if (!handled)
- {
- // this doesn't do child processing
- handled = LLFolderViewItem::handleHover(x, y, mask);
- }
-
- return handled;
-}
-
-BOOL LLFolderViewFolder::handleMouseDown( S32 x, S32 y, MASK mask )
-{
- BOOL handled = FALSE;
- if( mIsOpen )
- {
- handled = childrenHandleMouseDown(x,y,mask) != NULL;
- }
- if( !handled )
- {
- if(mIndentation < x && x < mIndentation + ARROW_SIZE + TEXT_PAD)
- {
- toggleOpen();
- handled = TRUE;
- }
- else
- {
- // do normal selection logic
- handled = LLFolderViewItem::handleMouseDown(x, y, mask);
- }
- }
-
- return handled;
-}
-
-BOOL LLFolderViewFolder::handleDoubleClick( S32 x, S32 y, MASK mask )
-{
- /* Disable outfit double click to wear
- const LLUUID &cat_uuid = getListener()->getUUID();
- const LLViewerInventoryCategory *cat = gInventory.getCategory(cat_uuid);
- if (cat && cat->getPreferredType() == LLFolderType::FT_OUTFIT)
- {
- getListener()->performAction(NULL, NULL,"replaceoutfit");
- return TRUE;
- }
- */
-
- BOOL handled = FALSE;
- if( mIsOpen )
- {
- handled = childrenHandleDoubleClick( x, y, mask ) != NULL;
- }
- if( !handled )
- {
- if(mIndentation < x && x < mIndentation + ARROW_SIZE + TEXT_PAD)
- {
- // don't select when user double-clicks plus sign
- // so as not to contradict single-click behavior
- toggleOpen();
- }
- else
- {
- setSelectionFromRoot(this, FALSE);
- toggleOpen();
- }
- handled = TRUE;
- }
- return handled;
-}
-
-void LLFolderViewFolder::draw()
-{
- if (mAutoOpenCountdown != 0.f)
- {
- mControlLabelRotation = mAutoOpenCountdown * -90.f;
- }
- else if (mIsOpen)
- {
- mControlLabelRotation = lerp(mControlLabelRotation, -90.f, LLCriticalDamp::getInterpolant(0.04f));
- }
- else
- {
- mControlLabelRotation = lerp(mControlLabelRotation, 0.f, LLCriticalDamp::getInterpolant(0.025f));
- }
-
- bool possibly_has_children = false;
- bool up_to_date = mListener && mListener->isUpToDate();
- if(!up_to_date
- && mListener->hasChildren()) // we know we have children but haven't fetched them (doesn't obey filter)
- {
- possibly_has_children = true;
- }
-
-
- BOOL loading = (mIsOpen
- && possibly_has_children
- && !up_to_date );
-
- if ( loading && !mIsLoading )
- {
- // Measure how long we've been in the loading state
- mTimeSinceRequestStart.reset();
- }
-
- mIsLoading = loading;
-
- LLFolderViewItem::draw();
-
- // draw children if root folder, or any other folder that is open or animating to closed state
- if( getRoot() == this || (mIsOpen || mCurHeight != mTargetHeight ))
- {
- LLView::draw();
- }
-
- mExpanderHighlighted = FALSE;
-}
-
-time_t LLFolderViewFolder::getCreationDate() const
-{
- return llmax<time_t>(mCreationDate, mSubtreeCreationDate);
-}
-
-
-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())
- // or not all of its descendants have been checked against minimum filter requirement
- || getCompletedFilterGeneration() < getRoot()->getFilter()->getMinRequiredGeneration();
-}
-
-// this does prefix traversal, as folders are listed above their contents
-LLFolderViewItem* LLFolderViewFolder::getNextFromChild( LLFolderViewItem* item, BOOL include_children )
-{
- BOOL found_item = FALSE;
-
- LLFolderViewItem* result = NULL;
- // when not starting from a given item, start at beginning
- if(item == NULL)
- {
- found_item = TRUE;
- }
-
- // find current item among children
- folders_t::iterator fit = mFolders.begin();
- folders_t::iterator fend = mFolders.end();
-
- items_t::iterator iit = mItems.begin();
- items_t::iterator iend = mItems.end();
-
- // if not trivially starting at the beginning, we have to find the current item
- if (!found_item)
- {
- // first, look among folders, since they are always above items
- for(; fit != fend; ++fit)
- {
- if(item == (*fit))
- {
- found_item = TRUE;
- // if we are on downwards traversal
- if (include_children && (*fit)->isOpen())
- {
- // look for first descendant
- return (*fit)->getNextFromChild(NULL, TRUE);
- }
- // otherwise advance to next folder
- ++fit;
- include_children = TRUE;
- break;
- }
- }
-
- // didn't find in folders? Check items...
- if (!found_item)
- {
- for(; iit != iend; ++iit)
- {
- if(item == (*iit))
- {
- found_item = TRUE;
- // point to next item
- ++iit;
- break;
- }
- }
- }
- }
-
- if (!found_item)
- {
- // you should never call this method with an item that isn't a child
- // so we should always find something
- llassert(FALSE);
- return NULL;
- }
-
- // at this point, either iit or fit point to a candidate "next" item
- // if both are out of range, we need to punt up to our parent
-
- // now, starting from found folder, continue through folders
- // searching for next visible folder
- while(fit != fend && !(*fit)->getVisible())
- {
- // turn on downwards traversal for next folder
- ++fit;
- }
-
- if (fit != fend)
- {
- result = (*fit);
- }
- else
- {
- // otherwise, scan for next visible item
- while(iit != iend && !(*iit)->getVisible())
- {
- ++iit;
- }
-
- // check to see if we have a valid item
- if (iit != iend)
- {
- result = (*iit);
- }
- }
-
- if( !result && mParentFolder )
- {
- // If there are no siblings or children to go to, recurse up one level in the tree
- // and skip children for this folder, as we've already discounted them
- result = mParentFolder->getNextFromChild(this, FALSE);
- }
-
- return result;
-}
-
-// this does postfix traversal, as folders are listed above their contents
-LLFolderViewItem* LLFolderViewFolder::getPreviousFromChild( LLFolderViewItem* item, BOOL include_children )
-{
- BOOL found_item = FALSE;
-
- LLFolderViewItem* result = NULL;
- // when not starting from a given item, start at end
- if(item == NULL)
- {
- found_item = TRUE;
- }
-
- // find current item among children
- folders_t::reverse_iterator fit = mFolders.rbegin();
- folders_t::reverse_iterator fend = mFolders.rend();
-
- items_t::reverse_iterator iit = mItems.rbegin();
- items_t::reverse_iterator iend = mItems.rend();
-
- // if not trivially starting at the end, we have to find the current item
- if (!found_item)
- {
- // first, look among items, since they are always below the folders
- for(; iit != iend; ++iit)
- {
- if(item == (*iit))
- {
- found_item = TRUE;
- // point to next item
- ++iit;
- break;
- }
- }
-
- // didn't find in items? Check folders...
- if (!found_item)
- {
- for(; fit != fend; ++fit)
- {
- if(item == (*fit))
- {
- found_item = TRUE;
- // point to next folder
- ++fit;
- break;
- }
- }
- }
- }
-
- if (!found_item)
- {
- // you should never call this method with an item that isn't a child
- // so we should always find something
- llassert(FALSE);
- return NULL;
- }
-
- // at this point, either iit or fit point to a candidate "next" item
- // if both are out of range, we need to punt up to our parent
-
- // now, starting from found item, continue through items
- // searching for next visible item
- while(iit != iend && !(*iit)->getVisible())
- {
- ++iit;
- }
-
- if (iit != iend)
- {
- // we found an appropriate item
- result = (*iit);
- }
- else
- {
- // otherwise, scan for next visible folder
- while(fit != fend && !(*fit)->getVisible())
- {
- ++fit;
- }
-
- // check to see if we have a valid folder
- if (fit != fend)
- {
- // try selecting child element of this folder
- if ((*fit)->isOpen())
- {
- result = (*fit)->getPreviousFromChild(NULL);
- }
- else
- {
- result = (*fit);
- }
- }
- }
-
- if( !result )
- {
- // If there are no siblings or children to go to, recurse up one level in the tree
- // which gets back to this folder, which will only be visited if it is a valid, visible item
- result = this;
- }
-
- return result;
-}
-
-
-bool LLInventorySort::updateSort(U32 order)
-{
- if (order != mSortOrder)
- {
- mSortOrder = order;
- mByDate = (order & LLInventoryFilter::SO_DATE);
- mSystemToTop = (order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP);
- mFoldersByName = (order & LLInventoryFilter::SO_FOLDERS_BY_NAME);
- return true;
- }
- return false;
-}
-
-bool LLInventorySort::operator()(const LLFolderViewItem* const& a, const LLFolderViewItem* const& b)
-{
- // ignore sort order for landmarks in the Favorites folder.
- // they should be always sorted as in Favorites bar. See EXT-719
- if (a->getSortGroup() == SG_ITEM
- && b->getSortGroup() == SG_ITEM
- && a->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK
- && b->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK)
- {
-
- static const LLUUID& favorites_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
-
- LLUUID a_uuid = a->getParentFolder()->getListener()->getUUID();
- LLUUID b_uuid = b->getParentFolder()->getListener()->getUUID();
-
- if ((a_uuid == favorites_folder_id && b_uuid == favorites_folder_id))
- {
- // *TODO: mantipov: probably it is better to add an appropriate method to LLFolderViewItem
- // or to LLInvFVBridge
- LLViewerInventoryItem* aitem = (static_cast<const LLItemBridge*>(a->getListener()))->getItem();
- LLViewerInventoryItem* bitem = (static_cast<const LLItemBridge*>(b->getListener()))->getItem();
- if (!aitem || !bitem)
- return false;
- S32 a_sort = aitem->getSortField();
- S32 b_sort = bitem->getSortField();
- return a_sort < b_sort;
- }
- }
-
- // We sort by name if we aren't sorting by date
- // OR if these are folders and we are sorting folders by name.
- bool by_name = (!mByDate
- || (mFoldersByName
- && (a->getSortGroup() != SG_ITEM)));
-
- if (a->getSortGroup() != b->getSortGroup())
- {
- if (mSystemToTop)
- {
- // Group order is System Folders, Trash, Normal Folders, Items
- return (a->getSortGroup() < b->getSortGroup());
- }
- else if (mByDate)
- {
- // Trash needs to go to the bottom if we are sorting by date
- if ( (a->getSortGroup() == SG_TRASH_FOLDER)
- || (b->getSortGroup() == SG_TRASH_FOLDER))
- {
- return (b->getSortGroup() == SG_TRASH_FOLDER);
- }
- }
- }
-
- if (by_name)
- {
- S32 compare = LLStringUtil::compareDict(a->getLabel(), b->getLabel());
- if (0 == compare)
- {
- return (a->getCreationDate() > b->getCreationDate());
- }
- else
- {
- return (compare < 0);
- }
- }
- else
- {
- // BUG: This is very very slow. The getCreationDate() is log n in number
- // of inventory items.
- time_t first_create = a->getCreationDate();
- time_t second_create = b->getCreationDate();
- if (first_create == second_create)
- {
- return (LLStringUtil::compareDict(a->getLabel(), b->getLabel()) < 0);
- }
- else
- {
- return (first_create > second_create);
- }
- }
-}
diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h
deleted file mode 100644
index 3c7592046a..0000000000
--- a/indra/newview/llfolderviewitem.h
+++ /dev/null
@@ -1,576 +0,0 @@
-/**
-* @file llfolderviewitem.h
-* @brief Items and folders that can appear in a hierarchical folder view
-*
-* $LicenseInfo:firstyear=2001&license=viewerlgpl$
-* Second Life Viewer Source Code
-* Copyright (C) 2010, Linden Research, Inc.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation;
-* version 2.1 of the License only.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
-* $/LicenseInfo$
-*/
-#ifndef LLFOLDERVIEWITEM_H
-#define LLFOLDERVIEWITEM_H
-
-#include "llview.h"
-#include "lldarray.h" // *TODO: Eliminate, forward declare
-#include "lluiimage.h"
-
-class LLFontGL;
-class LLFolderView;
-class LLFolderViewEventListener;
-class LLFolderViewFolder;
-class LLFolderViewFunctor;
-class LLFolderViewItem;
-class LLFolderViewListenerFunctor;
-class LLInventoryFilter;
-class LLMenuGL;
-class LLUIImage;
-class LLViewerInventoryItem;
-
-// These are grouping of inventory types.
-// Order matters when sorting system folders to the top.
-enum EInventorySortGroup
-{
- SG_SYSTEM_FOLDER,
- SG_TRASH_FOLDER,
- SG_NORMAL_FOLDER,
- SG_ITEM
-};
-
-// *TODO: do we really need one sort object per folder?
-// can we just have one of these per LLFolderView ?
-class LLInventorySort
-{
-public:
- LLInventorySort()
- : mSortOrder(0),
- mByDate(false),
- mSystemToTop(false),
- mFoldersByName(false) { }
-
- // Returns true if order has changed
- bool updateSort(U32 order);
- U32 getSort() { return mSortOrder; }
- bool isByDate() { return mByDate; }
-
- bool operator()(const LLFolderViewItem* const& a, const LLFolderViewItem* const& b);
-private:
- U32 mSortOrder;
- bool mByDate;
- bool mSystemToTop;
- bool mFoldersByName;
-};
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLFolderViewItem
-//
-// An instance of this class represents a single item in a folder view
-// such as an inventory item or a file.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-class LLFolderViewItem : public LLView
-{
-public:
- static void initClass();
- static void cleanupClass();
-
- struct Params : public LLInitParam::Block<Params, LLView::Params>
- {
- Optional<LLUIImage*> icon;
- Optional<LLUIImage*> icon_open; // used for folders
- Optional<LLUIImage*> icon_overlay; // for links
- Optional<LLFolderView*> root;
- Mandatory<LLFolderViewEventListener*> listener;
-
- Optional<LLUIImage*> folder_arrow_image;
- Optional<S32> folder_indentation; // pixels
- Optional<LLUIImage*> selection_image;
- Optional<S32> item_height; // pixels
- Optional<S32> item_top_pad; // pixels
-
- Optional<S32> creation_date; //UTC seconds
-
- Params();
- };
-
- // layout constants
- static const S32 LEFT_PAD = 5;
- // LEFT_INDENTATION is set via folder_indentation above
- static const S32 ICON_PAD = 2;
- static const S32 ICON_WIDTH = 16;
- static const S32 TEXT_PAD = 1;
- static const S32 TEXT_PAD_RIGHT = 4;
- static const S32 ARROW_SIZE = 12;
- static const S32 MAX_FOLDER_ITEM_OVERLAP = 2;
- // animation parameters
- static const F32 FOLDER_CLOSE_TIME_CONSTANT;
- static const F32 FOLDER_OPEN_TIME_CONSTANT;
-
- // Mostly for debugging printout purposes.
- const std::string& getSearchableLabel() { return mSearchableLabel; }
-
- BOOL isLoading() const { return mIsLoading; }
-
-private:
- BOOL mIsSelected;
-
-protected:
- friend class LLUICtrlFactory;
- friend class LLFolderViewEventListener;
-
- LLFolderViewItem(const Params& p);
-
- std::string mLabel;
- std::string mSearchableLabel;
- S32 mLabelWidth;
- bool mLabelWidthDirty;
- time_t mCreationDate;
- LLFolderViewFolder* mParentFolder;
- LLFolderViewEventListener* mListener;
- BOOL mIsCurSelection;
- BOOL mSelectPending;
- LLFontGL::StyleFlags mLabelStyle;
- std::string mLabelSuffix;
- LLUIImagePtr mIcon;
- std::string mStatusText;
- LLUIImagePtr mIconOpen;
- LLUIImagePtr mIconOverlay;
- BOOL mHasVisibleChildren;
- S32 mIndentation;
- S32 mItemHeight;
- BOOL mPassedFilter;
- S32 mLastFilterGeneration;
- std::string::size_type mStringMatchOffset;
- F32 mControlLabelRotation;
- LLFolderView* mRoot;
- BOOL mDragAndDropTarget;
- BOOL mIsLoading;
- LLTimer mTimeSinceRequestStart;
- bool mShowLoadStatus;
- bool mIsMouseOverTitle;
-
- // helper function to change the selection from the root.
- void changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected);
-
- // this is an internal method used for adding items to folders. A
- // no-op at this level, but reimplemented in derived classes.
- virtual BOOL addItem(LLFolderViewItem*) { return FALSE; }
- virtual BOOL addFolder(LLFolderViewFolder*) { return FALSE; }
-
- static LLFontGL* getLabelFontForStyle(U8 style);
-
- virtual void setCreationDate(time_t creation_date_utc) { mCreationDate = creation_date_utc; }
-
-public:
- BOOL postBuild();
-
- // This function clears the currently selected item, and records
- // the specified selected item appropriately for display and use
- // in the UI. If open is TRUE, then folders are opened up along
- // the way to the selection.
- void setSelectionFromRoot(LLFolderViewItem* selection, BOOL openitem,
- BOOL take_keyboard_focus = TRUE);
-
- // This function is called when the folder view is dirty. It's
- // implemented here but called by derived classes when folding the
- // views.
- void arrangeFromRoot();
- void filterFromRoot( void );
-
- void arrangeAndSet(BOOL set_selection, BOOL take_keyboard_focus);
-
- virtual ~LLFolderViewItem( void );
-
- // addToFolder() returns TRUE if it succeeds. FALSE otherwise
- enum { ARRANGE = TRUE, DO_NOT_ARRANGE = FALSE };
- virtual BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root);
-
- virtual EInventorySortGroup getSortGroup() const;
-
- // Finds width and height of this object and it's children. Also
- // makes sure that this view and it's children are the right size.
- virtual S32 arrange( S32* width, S32* height, S32 filter_generation );
- virtual S32 getItemHeight();
-
- // applies filters to control visibility of inventory items
- virtual void filter( LLInventoryFilter& filter);
-
- // updates filter serial number and optionally propagated value up to root
- S32 getLastFilterGeneration() { return mLastFilterGeneration; }
-
- virtual void dirtyFilter();
-
- // If 'selection' is 'this' then note that otherwise ignore.
- // Returns TRUE if this item ends up being selected.
- virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus);
-
- // This method is used to set the selection state of an item.
- // If 'selection' is 'this' then note selection.
- // Returns TRUE if the selection state of this item was changed.
- virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
-
- // this method is used to deselect this element
- void deselectItem();
-
- // this method is used to select this element
- virtual void selectItem();
-
- // gets multiple-element selection
- virtual std::set<LLUUID> getSelectionList() const;
-
- // Returns true is this object and all of its children can be removed (deleted by user)
- virtual BOOL isRemovable();
-
- // Returns true is this object and all of its children can be moved
- virtual BOOL isMovable();
-
- // destroys this item recursively
- virtual void destroyView();
-
- BOOL isSelected() const { return mIsSelected; }
-
- void setUnselected() { mIsSelected = FALSE; }
-
- void setIsCurSelection(BOOL select) { mIsCurSelection = select; }
-
- BOOL getIsCurSelection() { return mIsCurSelection; }
-
- BOOL hasVisibleChildren() { return mHasVisibleChildren; }
-
- void setShowLoadStatus(bool status) { mShowLoadStatus = status; }
-
- // Call through to the viewed object and return true if it can be
- // removed. Returns true if it's removed.
- //virtual BOOL removeRecursively(BOOL single_item);
- BOOL remove();
-
- // Build an appropriate context menu for the item. Flags unused.
- void buildContextMenu(LLMenuGL& menu, U32 flags);
-
- // This method returns the actual name of the thing being
- // viewed. This method will ask the viewed object itself.
- const std::string& getName( void ) const;
-
- const std::string& getSearchableLabel( void ) const;
-
- // This method returns the label displayed on the view. This
- // method was primarily added to allow sorting on the folder
- // contents possible before the entire view has been constructed.
- const std::string& getLabel() const { return mLabel; }
-
- // Used for sorting, like getLabel() above.
- virtual time_t getCreationDate() const { return mCreationDate; }
-
- LLFolderViewFolder* getParentFolder( void ) { return mParentFolder; }
- const LLFolderViewFolder* getParentFolder( void ) const { return mParentFolder; }
-
- LLFolderViewItem* getNextOpenNode( BOOL include_children = TRUE );
- LLFolderViewItem* getPreviousOpenNode( BOOL include_children = TRUE );
-
- const LLFolderViewEventListener* getListener( void ) const { return mListener; }
- LLFolderViewEventListener* getListener( void ) { return mListener; }
-
- // Gets the inventory item if it exists (null otherwise)
- LLViewerInventoryItem * getInventoryItem(void);
-
- // just rename the object.
- void rename(const std::string& new_name);
-
- // open
- virtual void openItem( void );
- virtual void preview(void);
-
- // Show children (unfortunate that this is called "open")
- virtual void setOpen(BOOL open = TRUE) {};
-
- virtual BOOL isOpen() const { return FALSE; }
-
- virtual LLFolderView* getRoot();
- BOOL isDescendantOf( const LLFolderViewFolder* potential_ancestor );
- S32 getIndentation() { return mIndentation; }
-
- virtual BOOL potentiallyVisible(); // do we know for a fact that this item won't be displayed?
- virtual BOOL potentiallyFiltered(); // do we know for a fact that this item has been filtered out?
-
- virtual BOOL getFiltered();
- virtual BOOL getFiltered(S32 filter_generation);
- virtual void setFiltered(BOOL filtered, S32 filter_generation);
-
- // change the icon
- void setIcon(LLUIImagePtr icon);
-
- // refresh information from the object being viewed.
- void refreshFromListener();
- virtual void refresh();
-
- virtual void applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor);
-
- // LLView functionality
- virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
- virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
- virtual BOOL handleHover( S32 x, S32 y, MASK mask );
- virtual BOOL handleMouseUp( S32 x, S32 y, MASK mask );
- virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
-
- virtual void onMouseLeave(S32 x, S32 y, MASK mask);
-
- virtual LLView* findChildView(const std::string& name, BOOL recurse) const { return NULL; }
-
- // virtual void handleDropped();
- virtual void draw();
- virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg);
-
-private:
- static std::map<U8, LLFontGL*> sFonts; // map of styles to fonts
-};
-
-
-// function used for sorting.
-typedef bool (*sort_order_f)(LLFolderViewItem* a, LLFolderViewItem* b);
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLFolderViewFolder
-//
-// An instance of an LLFolderViewFolder represents a collection of
-// more folders and items. This is used to build the hierarchy of
-// items found in the folder view.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-class LLFolderViewFolder : public LLFolderViewItem
-{
-protected:
- LLFolderViewFolder( const LLFolderViewItem::Params& );
- friend class LLUICtrlFactory;
-
-public:
- typedef enum e_trash
- {
- UNKNOWN, TRASH, NOT_TRASH
- } ETrash;
-
- typedef std::list<LLFolderViewItem*> items_t;
- typedef std::list<LLFolderViewFolder*> folders_t;
-
-protected:
- items_t mItems;
- folders_t mFolders;
- LLInventorySort mSortFunction;
-
- BOOL mIsOpen;
- BOOL mExpanderHighlighted;
- F32 mCurHeight;
- F32 mTargetHeight;
- F32 mAutoOpenCountdown;
- time_t mSubtreeCreationDate;
- mutable ETrash mAmTrash;
- S32 mLastArrangeGeneration;
- S32 mLastCalculatedWidth;
- S32 mCompletedFilterGeneration;
- S32 mMostFilteredDescendantGeneration;
- bool mNeedsSort;
- bool mPassedFolderFilter;
-
-public:
- typedef enum e_recurse_type
- {
- RECURSE_NO,
- RECURSE_UP,
- RECURSE_DOWN,
- RECURSE_UP_DOWN
- } ERecurseType;
-
-
- virtual ~LLFolderViewFolder( void );
-
- virtual BOOL potentiallyVisible();
-
- LLFolderViewItem* getNextFromChild( LLFolderViewItem*, BOOL include_children = TRUE );
- LLFolderViewItem* getPreviousFromChild( LLFolderViewItem*, BOOL include_children = TRUE );
-
- // addToFolder() returns TRUE if it succeeds. FALSE otherwise
- virtual BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root);
-
- // Finds width and height of this object and it's children. Also
- // makes sure that this view and it's children are the right size.
- virtual S32 arrange( S32* width, S32* height, S32 filter_generation );
-
- BOOL needsArrange();
- void requestSort();
-
- // Returns the sort group (system, trash, folder) for this folder.
- virtual EInventorySortGroup getSortGroup() const;
-
- virtual void setCompletedFilterGeneration(S32 generation, BOOL recurse_up);
- virtual S32 getCompletedFilterGeneration() { return mCompletedFilterGeneration; }
-
- BOOL hasFilteredDescendants(S32 filter_generation);
- BOOL hasFilteredDescendants();
-
- // applies filters to control visibility of inventory items
- virtual void filter( LLInventoryFilter& filter);
- virtual void setFiltered(BOOL filtered, S32 filter_generation);
- virtual BOOL getFiltered();
- virtual BOOL getFiltered(S32 filter_generation);
-
- virtual void dirtyFilter();
-
- // folder-specific filtering (filter status propagates top down instead of bottom up)
- void filterFolder(LLInventoryFilter& filter);
- void setFilteredFolder(bool filtered, S32 filter_generation);
- bool getFilteredFolder(S32 filter_generation);
-
- // Passes selection information on to children and record
- // selection information if necessary.
- // Returns TRUE if this object (or a child) ends up being selected.
- // If 'openitem' is TRUE then folders are opened up along the way to the selection.
- virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus);
-
- // This method is used to change the selection of an item.
- // Recursively traverse all children; if 'selection' is 'this' then change
- // the select status if necessary.
- // Returns TRUE if the selection state of this folder, or of a child, was changed.
- virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
-
- // this method is used to group select items
- void extendSelectionTo(LLFolderViewItem* selection);
-
- // Returns true is this object and all of its children can be removed.
- virtual BOOL isRemovable();
-
- // Returns true is this object and all of its children can be moved
- virtual BOOL isMovable();
-
- // destroys this folder, and all children
- virtual void destroyView();
-
- // If this folder can be removed, remove all children that can be
- // removed, return TRUE if this is empty after the operation and
- // it's viewed folder object can be removed.
- //virtual BOOL removeRecursively(BOOL single_item);
- //virtual BOOL remove();
-
- // remove the specified item (and any children) if
- // possible. Return TRUE if the item was deleted.
- BOOL removeItem(LLFolderViewItem* item);
-
- // simply remove the view (and any children) Don't bother telling
- // the listeners.
- void removeView(LLFolderViewItem* item);
-
- // extractItem() removes the specified item from the folder, but
- // doesn't delete it.
- void extractItem( LLFolderViewItem* item );
-
- // This function is called by a child that needs to be resorted.
- void resort(LLFolderViewItem* item);
-
- void setItemSortOrder(U32 ordering);
- void sortBy(U32);
- //BOOL (*func)(LLFolderViewItem* a, LLFolderViewItem* b));
-
- void setAutoOpenCountdown(F32 countdown) { mAutoOpenCountdown = countdown; }
-
- // folders can be opened. This will usually be called by internal
- // methods.
- virtual void toggleOpen();
-
- // Force a folder open or closed
- virtual void setOpen(BOOL openitem = TRUE);
-
- // Called when a child is refreshed.
- // don't rearrange child folder contents unless explicitly requested
- virtual void requestArrange(BOOL include_descendants = FALSE);
-
- // internal method which doesn't update the entire view. This
- // method was written because the list iterators destroy the state
- // of other iterations, thus, we can't arrange while iterating
- // through the children (such as when setting which is selected.
- virtual void setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse = RECURSE_NO);
-
- // Get the current state of the folder.
- virtual BOOL isOpen() const { return mIsOpen; }
-
- // special case if an object is dropped on the child.
- BOOL handleDragAndDropFromChild(MASK mask,
- BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg);
-
- void applyFunctorRecursively(LLFolderViewFunctor& functor);
- virtual void applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor);
-
- // Just apply this functor to the folder's immediate children.
- void applyFunctorToChildren(LLFolderViewFunctor& functor);
-
- virtual void openItem( void );
- virtual BOOL addItem(LLFolderViewItem* item);
- virtual BOOL addFolder( LLFolderViewFolder* folder);
-
- // LLView functionality
- virtual BOOL handleHover(S32 x, S32 y, MASK mask);
- virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
- virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
- virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
- virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg);
- BOOL handleDragAndDropToThisFolder(MASK mask, BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg);
- virtual void draw();
-
- time_t getCreationDate() const;
- bool isTrash() const;
-
- folders_t::const_iterator getFoldersBegin() const { return mFolders.begin(); }
- folders_t::const_iterator getFoldersEnd() const { return mFolders.end(); }
- folders_t::size_type getFoldersCount() const { return mFolders.size(); }
-
- items_t::const_iterator getItemsBegin() const { return mItems.begin(); }
- items_t::const_iterator getItemsEnd() const { return mItems.end(); }
- items_t::size_type getItemsCount() const { return mItems.size(); }
- LLFolderViewFolder* getCommonAncestor(LLFolderViewItem* item_a, LLFolderViewItem* item_b, bool& reverse);
- void gatherChildRangeExclusive(LLFolderViewItem* start, LLFolderViewItem* end, bool reverse, std::vector<LLFolderViewItem*>& items);
-};
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLFolderViewListenerFunctor
-//
-// This simple abstract base class can be used to applied to all
-// listeners in a hierarchy.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-class LLFolderViewListenerFunctor
-{
-public:
- virtual ~LLFolderViewListenerFunctor() {}
- virtual void operator()(LLFolderViewEventListener* listener) = 0;
-};
-
-#endif // LLFOLDERVIEWITEM_H
diff --git a/indra/newview/llfolderviewmodelinventory.cpp b/indra/newview/llfolderviewmodelinventory.cpp
new file mode 100644
index 0000000000..d23b4af8cb
--- /dev/null
+++ b/indra/newview/llfolderviewmodelinventory.cpp
@@ -0,0 +1,332 @@
+/*
+ * @file llfolderviewmodelinventory.cpp
+ * @brief Implementation of the inventory-specific view model
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llfolderviewmodelinventory.h"
+#include "llinventorymodelbackgroundfetch.h"
+#include "llinventorypanel.h"
+#include "lltooldraganddrop.h"
+
+//
+// class LLFolderViewModelInventory
+//
+static LLFastTimer::DeclareTimer FTM_INVENTORY_SORT("Sort");
+
+bool LLFolderViewModelInventory::startDrag(std::vector<LLFolderViewModelItem*>& items)
+{
+ std::vector<EDragAndDropType> types;
+ uuid_vec_t cargo_ids;
+ std::vector<LLFolderViewModelItem*>::iterator item_it;
+ bool can_drag = true;
+ if (!items.empty())
+ {
+ for (item_it = items.begin(); item_it != items.end(); ++item_it)
+ {
+ EDragAndDropType type = DAD_NONE;
+ LLUUID id = LLUUID::null;
+ can_drag = can_drag && static_cast<LLFolderViewModelItemInventory*>(*item_it)->startDrag(&type, &id);
+
+ types.push_back(type);
+ cargo_ids.push_back(id);
+ }
+
+ LLToolDragAndDrop::getInstance()->beginMultiDrag(types, cargo_ids,
+ static_cast<LLFolderViewModelItemInventory*>(items.front())->getDragSource(), mTaskID);
+ }
+ return can_drag;
+}
+
+
+void LLFolderViewModelInventory::sort( LLFolderViewFolder* folder )
+{
+ LLFastTimer _(FTM_INVENTORY_SORT);
+
+ if (!needsSort(folder->getViewModelItem())) return;
+
+ LLFolderViewModelItemInventory* modelp = static_cast<LLFolderViewModelItemInventory*>(folder->getViewModelItem());
+ if (modelp->getUUID().isNull()) return;
+
+ for (std::list<LLFolderViewFolder*>::iterator it = folder->getFoldersBegin(), end_it = folder->getFoldersEnd();
+ it != end_it;
+ ++it)
+ {
+ LLFolderViewFolder* child_folderp = *it;
+ sort(child_folderp);
+
+ if (child_folderp->getFoldersCount() > 0)
+ {
+ time_t most_recent_folder_time =
+ static_cast<LLFolderViewModelItemInventory*>((*child_folderp->getFoldersBegin())->getViewModelItem())->getCreationDate();
+ LLFolderViewModelItemInventory* modelp = static_cast<LLFolderViewModelItemInventory*>(child_folderp->getViewModelItem());
+ if (most_recent_folder_time > modelp->getCreationDate())
+ {
+ modelp->setCreationDate(most_recent_folder_time);
+ }
+ }
+ if (child_folderp->getItemsCount() > 0)
+ {
+ time_t most_recent_item_time =
+ static_cast<LLFolderViewModelItemInventory*>((*child_folderp->getItemsBegin())->getViewModelItem())->getCreationDate();
+
+ LLFolderViewModelItemInventory* modelp = static_cast<LLFolderViewModelItemInventory*>(child_folderp->getViewModelItem());
+ if (most_recent_item_time > modelp->getCreationDate())
+ {
+ modelp->setCreationDate(most_recent_item_time);
+ }
+ }
+ }
+ base_t::sort(folder);
+}
+
+bool LLFolderViewModelInventory::contentsReady()
+{
+ return !LLInventoryModelBackgroundFetch::instance().folderFetchActive();
+}
+
+void LLFolderViewModelItemInventory::requestSort()
+{
+ LLFolderViewModelItemCommon::requestSort();
+ if (mRootViewModel->getSorter().isByDate())
+ {
+ // sort by date potentially affects parent folders which use a date
+ // derived from newest item in them
+ if (mParent)
+ {
+ mParent->requestSort();
+ }
+ }
+}
+
+bool LLFolderViewModelItemInventory::potentiallyVisible()
+{
+ return passedFilter() // we've passed the filter
+ || getLastFilterGeneration() < mRootViewModel->getFilter()->getFirstSuccessGeneration() // or we don't know yet
+ || descendantsPassedFilter();
+}
+
+bool LLFolderViewModelItemInventory::passedFilter(S32 filter_generation)
+{
+ if (filter_generation < 0 && mRootViewModel)
+ filter_generation = mRootViewModel->getFilter()->getFirstSuccessGeneration();
+
+ return mPassedFolderFilter
+ && mLastFilterGeneration >= filter_generation
+ && (mPassedFilter || descendantsPassedFilter(filter_generation));
+}
+
+bool LLFolderViewModelItemInventory::descendantsPassedFilter(S32 filter_generation)
+{
+ if (filter_generation < 0) filter_generation = mRootViewModel->getFilter()->getFirstSuccessGeneration();
+ return mMostFilteredDescendantGeneration >= filter_generation;
+}
+
+void LLFolderViewModelItemInventory::setPassedFilter(bool passed, bool passed_folder, S32 filter_generation)
+{
+ mPassedFilter = passed;
+ mPassedFolderFilter = passed_folder;
+ mLastFilterGeneration = filter_generation;
+}
+
+bool LLFolderViewModelItemInventory::filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter )
+{
+ bool passed_filter_before = item->passedFilter();
+ S32 filter_generation = filter.getCurrentGeneration();
+ S32 must_pass_generation = filter.getFirstRequiredGeneration();
+
+ if (item->getLastFilterGeneration() < filter_generation)
+ {
+ if (item->getLastFilterGeneration() >= must_pass_generation
+ && !item->passedFilter(must_pass_generation))
+ {
+ // failed to pass an earlier filter that was a subset of the current one
+ // go ahead and flag this item as done
+ item->filter(filter);
+ if (item->passedFilter())
+ {
+ llerrs << "Invalid shortcut in inventory filtering!" << llendl;
+ }
+ item->setPassedFilter(false, false, filter_generation);
+ }
+ else
+ {
+ item->filter( filter );
+ }
+ }
+
+ // track latest generation to pass any child items, for each folder up to root
+ if (item->passedFilter())
+ {
+ LLFolderViewModelItemInventory* view_model = this;
+
+ while(view_model && view_model->mMostFilteredDescendantGeneration < filter_generation)
+ {
+ view_model->mMostFilteredDescendantGeneration = filter_generation;
+ view_model = static_cast<LLFolderViewModelItemInventory*>(view_model->mParent);
+ }
+
+ return !passed_filter_before;
+ }
+ else // !item->passedfilter()
+ {
+ return passed_filter_before;
+ }
+}
+
+bool LLFolderViewModelItemInventory::filter( LLFolderViewFilter& filter)
+{
+ bool changed = false;
+
+ if(!mChildren.empty()
+ && (getLastFilterGeneration() < filter.getFirstRequiredGeneration() // haven't checked descendants against minimum required generation to pass
+ || descendantsPassedFilter(filter.getFirstRequiredGeneration()))) // or at least one descendant has passed the minimum requirement
+ {
+ // now query children
+ for (child_list_t::iterator iter = mChildren.begin();
+ iter != mChildren.end() && filter.getFilterCount() > 0;
+ ++iter)
+ {
+ changed |= filterChildItem((*iter), filter);
+ }
+ }
+
+ if (changed)
+ {
+ //TODO RN: ensure this still happens, but without dependency on folderview
+ LLFolderViewFolder* folder = static_cast<LLFolderViewFolder*>(mFolderViewItem);
+ folder->requestArrange();
+ }
+
+ // if we didn't use all filter iterations
+ // that means we filtered all of our descendants
+ // so filter ourselves now
+ if (filter.getFilterCount() > 0)
+ {
+ filter.decrementFilterCount();
+
+ const BOOL passed_filter = filter.check(this);
+ const BOOL passed_filter_folder = (getInventoryType() == LLInventoryType::IT_CATEGORY)
+ ? filter.checkFolder(this)
+ : true;
+
+ setPassedFilter(passed_filter, passed_filter_folder, filter.getCurrentGeneration());
+ //TODO RN: create interface for string highlighting
+ //mStringMatchOffset = filter.getStringMatchOffset(this);
+ }
+ return changed;
+}
+
+LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel()
+{
+ return &mInventoryViewModel;
+}
+
+
+const LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel() const
+{
+ return &mInventoryViewModel;
+}
+
+bool LLInventorySort::operator()(const LLFolderViewModelItemInventory* const& a, const LLFolderViewModelItemInventory* const& b) const
+{
+ // ignore sort order for landmarks in the Favorites folder.
+ // they should be always sorted as in Favorites bar. See EXT-719
+ //TODO RN: fix sorting in favorites folder
+ //if (a->getSortGroup() == SG_ITEM
+ // && b->getSortGroup() == SG_ITEM
+ // && a->getInventoryType() == LLInventoryType::IT_LANDMARK
+ // && b->getInventoryType() == LLInventoryType::IT_LANDMARK)
+ //{
+
+ // static const LLUUID& favorites_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+
+ // LLUUID a_uuid = a->getParentFolder()->getUUID();
+ // LLUUID b_uuid = b->getParentFolder()->getUUID();
+
+ // if ((a_uuid == favorites_folder_id && b_uuid == favorites_folder_id))
+ // {
+ // // *TODO: mantipov: probably it is better to add an appropriate method to LLFolderViewItem
+ // // or to LLInvFVBridge
+ // LLViewerInventoryItem* aitem = (static_cast<const LLItemBridge*>(a))->getItem();
+ // LLViewerInventoryItem* bitem = (static_cast<const LLItemBridge*>(b))->getItem();
+ // if (!aitem || !bitem)
+ // return false;
+ // S32 a_sort = aitem->getSortField();
+ // S32 b_sort = bitem->getSortField();
+ // return a_sort < b_sort;
+ // }
+ //}
+
+ // We sort by name if we aren't sorting by date
+ // OR if these are folders and we are sorting folders by name.
+ bool by_name = (!mByDate
+ || (mFoldersByName
+ && (a->getSortGroup() != SG_ITEM)));
+
+ if (a->getSortGroup() != b->getSortGroup())
+ {
+ if (mSystemToTop)
+ {
+ // Group order is System Folders, Trash, Normal Folders, Items
+ return (a->getSortGroup() < b->getSortGroup());
+ }
+ else if (mByDate)
+ {
+ // Trash needs to go to the bottom if we are sorting by date
+ if ( (a->getSortGroup() == SG_TRASH_FOLDER)
+ || (b->getSortGroup() == SG_TRASH_FOLDER))
+ {
+ return (b->getSortGroup() == SG_TRASH_FOLDER);
+ }
+ }
+ }
+
+ if (by_name)
+ {
+ S32 compare = LLStringUtil::compareDict(a->getDisplayName(), b->getDisplayName());
+ if (0 == compare)
+ {
+ return (a->getCreationDate() > b->getCreationDate());
+ }
+ else
+ {
+ return (compare < 0);
+ }
+ }
+ else
+ {
+ time_t first_create = a->getCreationDate();
+ time_t second_create = b->getCreationDate();
+ if (first_create == second_create)
+ {
+ return (LLStringUtil::compareDict(a->getDisplayName(), b->getDisplayName()) < 0);
+ }
+ else
+ {
+ return (first_create > second_create);
+ }
+ }
+}
+
diff --git a/indra/newview/llfolderviewmodelinventory.h b/indra/newview/llfolderviewmodelinventory.h
new file mode 100644
index 0000000000..12a977b28b
--- /dev/null
+++ b/indra/newview/llfolderviewmodelinventory.h
@@ -0,0 +1,116 @@
+/**
+ * @file llfolderviewmodelinventory.h
+ * @brief view model implementation specific to inventory
+ * class definition
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFOLDERVIEWMODELINVENTORY_H
+#define LL_LLFOLDERVIEWMODELINVENTORY_H
+
+#include "llinventoryfilter.h"
+#include "llinventory.h"
+#include "llwearabletype.h"
+#include "lltooldraganddrop.h"
+
+class LLFolderViewModelItemInventory
+ : public LLFolderViewModelItemCommon
+{
+public:
+ LLFolderViewModelItemInventory()
+ : mRootViewModel(NULL)
+ {}
+ void setRootViewModel(class LLFolderViewModelInventory* root_view_model)
+ {
+ mRootViewModel = root_view_model;
+ }
+ virtual const LLUUID& getUUID() const = 0;
+ virtual time_t getCreationDate() const = 0; // UTC seconds
+ virtual void setCreationDate(time_t creation_date_utc) = 0;
+ virtual PermissionMask getPermissionMask() const = 0;
+ virtual LLFolderType::EType getPreferredType() const = 0;
+ virtual void showProperties(void) = 0;
+ virtual BOOL isItemInTrash( void) const { return FALSE; } // TODO: make into pure virtual.
+ virtual BOOL isUpToDate() const = 0;
+ virtual bool hasChildren() const = 0;
+ virtual LLInventoryType::EType getInventoryType() const = 0;
+ virtual void performAction(LLInventoryModel* model, std::string action) = 0;
+ virtual LLWearableType::EType getWearableType() const = 0;
+ virtual EInventorySortGroup getSortGroup() const = 0;
+ virtual LLInventoryObject* getInventoryObject() const = 0;
+ virtual void requestSort();
+ virtual bool potentiallyVisible();
+ virtual bool passedFilter(S32 filter_generation = -1);
+ virtual bool descendantsPassedFilter(S32 filter_generation = -1);
+ virtual void setPassedFilter(bool filtered, bool filtered_folder, S32 filter_generation);
+ virtual bool filter( LLFolderViewFilter& filter);
+ virtual bool filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter);
+
+ virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const = 0;
+ virtual LLToolDragAndDrop::ESource getDragSource() const = 0;
+
+protected:
+ class LLFolderViewModelInventory* mRootViewModel;
+};
+
+class LLInventorySort
+{
+public:
+ LLInventorySort(U32 order = 0)
+ : mSortOrder(order),
+ mByDate(false),
+ mSystemToTop(false),
+ mFoldersByName(false)
+ {
+ mByDate = (order & LLInventoryFilter::SO_DATE);
+ mSystemToTop = (order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP);
+ mFoldersByName = (order & LLInventoryFilter::SO_FOLDERS_BY_NAME);
+ }
+
+ bool isByDate() const { return mByDate; }
+ U32 getSortOrder() const { return mSortOrder; }
+
+ bool operator()(const LLFolderViewModelItemInventory* const& a, const LLFolderViewModelItemInventory* const& b) const;
+private:
+ U32 mSortOrder;
+ bool mByDate;
+ bool mSystemToTop;
+ bool mFoldersByName;
+};
+
+class LLFolderViewModelInventory
+ : public LLFolderViewModel<LLInventorySort, LLFolderViewModelItemInventory, LLFolderViewModelItemInventory, LLInventoryFilter>
+{
+public:
+ typedef LLFolderViewModel<LLInventorySort, LLFolderViewModelItemInventory, LLFolderViewModelItemInventory, LLInventoryFilter> base_t;
+
+ void setTaskID(const LLUUID& id) {mTaskID = id;}
+
+ void sort(LLFolderViewFolder* folder);
+ bool contentsReady();
+ bool startDrag(std::vector<LLFolderViewModelItem*>& items);
+
+private:
+ LLUUID mTaskID;
+};
+#endif // LL_LLFOLDERVIEWMODELINVENTORY_H
diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp
index 11401d6c68..a64ddd185d 100644
--- a/indra/newview/llfriendcard.cpp
+++ b/indra/newview/llfriendcard.cpp
@@ -47,13 +47,13 @@ static const std::string INVENTORY_STRING_FRIENDS_ALL_SUBFOLDER = "All";
// helper functions
// NOTE: For now Friends & All folders are created as protected folders of the LLFolderType::FT_CALLINGCARD type.
-// So, their names will be processed in the LLFolderViewItem::refreshFromListener() to be localized
+// So, their names will be processed in the LLFolderViewItem::refresh() to be localized
// using "InvFolder LABEL_NAME" as LLTrans::findString argument.
// We must use in this file their hard-coded names to ensure found them on different locales. EXT-5829.
// These hard-coded names will be stored in InventoryItems but shown localized in FolderViewItems
-// If hack in the LLFolderViewItem::refreshFromListener() to localize protected folder is removed
+// If hack in the LLFolderViewItem::refresh() to localize protected folder is removed
// or these folders are not protected these names should be localized in another place/way.
inline const std::string get_friend_folder_name()
{
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index f3b97776fc..e9144a4969 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -48,8 +48,9 @@
// LLIMFloaterContainer
//
LLIMFloaterContainer::LLIMFloaterContainer(const LLSD& seed)
-: LLMultiFloater(seed)
- ,mExpandCollapseBtn(NULL)
+: LLMultiFloater(seed),
+ mExpandCollapseBtn(NULL),
+ mConversationsRoot(NULL)
{
// Firstly add our self to IMSession observers, so we catch session events
LLIMMgr::getInstance()->addSessionObserver(this);
@@ -98,6 +99,18 @@ BOOL LLIMFloaterContainer::postBuild()
mConversationsListPanel = getChild<LLPanel>("conversations_list_panel");
+ // CHUI-98 : View Model for conversations
+ LLConversationItem* base_item = new LLConversationItem();
+ LLFolderView::Params p;
+ p.view_model = &mConversationViewModel;
+ p.parent_panel = mConversationsListPanel;
+ p.rect = mConversationsListPanel->getLocalRect();
+ p.follows.flags = FOLLOWS_ALL;
+ p.listener = base_item;
+
+ mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
+ mConversationsListPanel->addChild(mConversationsRoot);
+
mExpandCollapseBtn = getChild<LLButton>("expand_collapse_btn");
mExpandCollapseBtn->setClickedCallback(boost::bind(&LLIMFloaterContainer::onExpandCollapseButtonClicked, this));
@@ -521,7 +534,7 @@ LLFolderViewItem* LLIMFloaterContainer::createConversationItemWidget(LLConversat
//params.icon = bridge->getIcon();
//params.icon_open = bridge->getOpenIcon();
//params.creation_date = bridge->getCreationDate();
- //params.root = mFolderRoot;
+ params.root = mConversationsRoot;
params.listener = item;
params.rect = LLRect (0, 0, 0, 0);
params.tool_tip = params.name;
@@ -538,6 +551,15 @@ LLConversationItem::LLConversationItem(std::string name, const LLUUID& uuid, LLF
{
}
+LLConversationItem::LLConversationItem() :
+ mName(""),
+ mUUID(),
+ mFloater(NULL),
+ mContainer(NULL)
+{
+}
+
+
// Virtual action callbacks
void LLConversationItem::selectItem(void)
{
@@ -583,4 +605,12 @@ void LLConversationItem::showProperties(void)
{
}
+bool LLConversationSort::operator()(const LLConversationItem* const& a, const LLConversationItem* const& b) const
+{
+ // We compare only by name for the moment
+ // *TODO : Implement the sorting by date
+ S32 compare = LLStringUtil::compareDict(a->getDisplayName(), b->getDisplayName());
+ return (compare < 0);
+}
+
// EOF
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index c062127bee..0d988b5b73 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -37,7 +37,7 @@
#include "llgroupmgr.h"
#include "llfolderviewitem.h"
-#include "llfoldervieweventlistener.h"
+#include "llfolderviewmodel.h"
class LLButton;
class LLLayoutPanel;
@@ -53,19 +53,19 @@ typedef std::map<LLFloater*, LLFolderViewItem*> conversations_widgets_map;
// Conversation items: we hold a list of those and create an LLFolderViewItem widget for each
// that we tuck into the mConversationsListPanel.
-class LLConversationItem : public LLFolderViewEventListener
+class LLConversationItem : public LLFolderViewModelItemCommon
{
public:
LLConversationItem(std::string name, const LLUUID& uuid, LLFloater* floaterp, LLIMFloaterContainer* containerp);
+ LLConversationItem();
virtual ~LLConversationItem() {}
// Stub those things we won't really be using in this conversation context
virtual const std::string& getName() const { return mName; }
virtual const std::string& getDisplayName() const { return mName; }
+ virtual const std::string& getSearchableName() const { return mName; }
virtual const LLUUID& getUUID() const { return mUUID; }
virtual time_t getCreationDate() const { return 0; }
- virtual PermissionMask getPermissionMask() const { return PERM_ALL; }
- virtual LLFolderType::EType getPreferredType() const { return LLFolderType::FT_NONE; }
virtual LLPointer<LLUIImage> getIcon() const { return NULL; }
virtual LLPointer<LLUIImage> getOpenIcon() const { return getIcon(); }
virtual LLFontGL::StyleFlags getLabelStyle() const { return LLFontGL::NORMAL; }
@@ -76,8 +76,8 @@ public:
virtual BOOL isItemRemovable( void ) const { return FALSE; }
virtual BOOL isItemInTrash( void) const { return FALSE; }
virtual BOOL removeItem() { return FALSE; }
- virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch) { }
- virtual void move( LLFolderViewEventListener* parent_listener ) { }
+ virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch) { }
+ virtual void move( LLFolderViewModelItem* parent_listener ) { }
virtual BOOL isItemCopyable() const { return FALSE; }
virtual BOOL copyToClipboard() const { return FALSE; }
virtual BOOL cutToClipboard() const { return FALSE; }
@@ -86,9 +86,13 @@ public:
virtual void pasteLinkFromClipboard() { }
virtual void buildContextMenu(LLMenuGL& menu, U32 flags) { }
virtual BOOL isUpToDate() const { return TRUE; }
- virtual BOOL hasChildren() const { return FALSE; }
- virtual LLInventoryType::EType getInventoryType() const { return LLInventoryType::IT_NONE; }
- virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_NONE; }
+ virtual bool hasChildren() const { return FALSE; }
+
+ virtual bool potentiallyVisible() { return true; }
+ virtual bool filter( LLFolderViewFilter& filter) { return true; }
+ virtual bool descendantsPassedFilter(S32 filter_generation = -1) { return true; }
+ virtual void setPassedFilter(bool passed, bool passed_folder, S32 filter_generation) { }
+ virtual bool passedFilter(S32 filter_generation = -1) { return true; }
// The action callbacks
virtual void performAction(LLInventoryModel* model, std::string action);
@@ -100,10 +104,6 @@ public:
void setVisibleIfDetached(BOOL visible);
- // This method should be called when a drag begins.
- // Returns TRUE if the drag can begin, FALSE otherwise.
- virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const { return FALSE; }
-
// This method will be called to determine if a drop can be
// performed, and will set drop to TRUE if a drop is
// requested.
@@ -121,6 +121,86 @@ private:
LLFloater* mFloater;
LLIMFloaterContainer* mContainer;
};
+
+// We don't want to ever filter conversations but we need to declare that class to create a conversation view model.
+// We just stubb everything for the moment.
+class LLConversationFilter : public LLFolderViewFilter
+{
+public:
+
+ enum ESortOrderType
+ {
+ SO_NAME = 0, // Sort inventory by name
+ SO_DATE = 0x1, // Sort inventory by date
+ };
+
+ LLConversationFilter() { mEmpty = ""; }
+ ~LLConversationFilter() {}
+
+ bool check(const LLFolderViewModelItem* item) { return true; }
+ bool checkFolder(const LLFolderViewModelItem* folder) const { return true; }
+ void setEmptyLookupMessage(const std::string& message) { }
+ std::string getEmptyLookupMessage() const { return mEmpty; }
+ bool showAllResults() const { return true; }
+
+ bool isActive() const { return false; }
+ bool isModified() const { return false; }
+ void clearModified() { }
+ const std::string& getName() const { return mEmpty; }
+ const std::string& getFilterText() { return mEmpty; }
+ void setModified(EFilterModified behavior = FILTER_RESTART) { }
+
+ void setFilterCount(S32 count) { }
+ S32 getFilterCount() const { return 0; }
+ void decrementFilterCount() { }
+
+ bool isDefault() const { return true; }
+ bool isNotDefault() const { return false; }
+ void markDefault() { }
+ void resetDefault() { }
+
+ S32 getCurrentGeneration() const { return 0; }
+ S32 getFirstSuccessGeneration() const { return 0; }
+ S32 getFirstRequiredGeneration() const { return 0; }
+private:
+ std::string mEmpty;
+};
+
+class LLConversationSort
+{
+public:
+ LLConversationSort(U32 order = 0)
+ : mSortOrder(order),
+ mByDate(false),
+ mByName(false)
+ {
+ mByDate = (order & LLConversationFilter::SO_DATE);
+ mByName = (order & LLConversationFilter::SO_NAME);
+ }
+
+ bool isByDate() const { return mByDate; }
+ U32 getSortOrder() const { return mSortOrder; }
+
+ bool operator()(const LLConversationItem* const& a, const LLConversationItem* const& b) const;
+private:
+ U32 mSortOrder;
+ bool mByDate;
+ bool mByName;
+};
+
+class LLConversationViewModel
+: public LLFolderViewModel<LLConversationSort, LLConversationItem, LLConversationItem, LLConversationFilter>
+{
+public:
+ typedef LLFolderViewModel<LLConversationSort, LLConversationItem, LLConversationItem, LLConversationFilter> base_t;
+
+ void sort(LLFolderViewFolder* folder) { } // *TODO : implement conversation sort
+ bool contentsReady() { return true; } // *TODO : we need to check that participants names are available somewhat
+ bool startDrag(std::vector<LLFolderViewModelItem*>& items) { return false; } // We do not allow drag of conversation items
+
+private:
+};
+
// CHUI-137 : End
class LLIMFloaterContainer
@@ -184,17 +264,20 @@ private:
LLLayoutPanel* mConversationsPane;
LLLayoutStack* mConversationsStack;
- // CHUI-137 : Temporary implementation of conversations list
+ // Conversation list implementation
public:
void removeConversationListItem(LLFloater* floaterp, bool change_focus = true);
void addConversationListItem(std::string name, const LLUUID& uuid, LLFloater* floaterp);
LLFloater* findConversationItem(LLUUID& uuid);
private:
LLFolderViewItem* createConversationItemWidget(LLConversationItem* item);
+
// Conversation list data
- LLPanel* mConversationsListPanel; // This is the widget we add items to (i.e. clickable title for each conversation)
+ LLPanel* mConversationsListPanel; // This is the main widget we add conversation widget to
conversations_items_map mConversationsItems;
conversations_widgets_map mConversationsWidgets;
+ LLConversationViewModel mConversationViewModel;
+ LLFolderView* mConversationsRoot;
};
#endif // LL_LLIMFLOATERCONTAINER_H
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index b86c453d61..d17c25d9f3 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -37,6 +37,7 @@
#include "llappearancemgr.h"
#include "llattachmentsmgr.h"
#include "llavataractions.h"
+#include "llfavoritesbar.h" // management of favorites folder
#include "llfloateropenobject.h"
#include "llfloaterreg.h"
#include "llfloatersidepanelcontainer.h"
@@ -115,10 +116,10 @@ void teleport_via_landmark(const LLUUID& asset_id);
static BOOL can_move_to_outfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit);
static bool check_category(LLInventoryModel* model,
const LLUUID& cat_id,
- LLFolderView* active_folder_view,
+ LLInventoryPanel* active_panel,
LLInventoryFilter* filter);
static bool check_item(const LLUUID& item_id,
- LLFolderView* active_folder_view,
+ LLInventoryPanel* active_panel,
LLInventoryFilter* filter);
// Helper functions
@@ -208,7 +209,11 @@ const std::string& LLInvFVBridge::getName() const
const std::string& LLInvFVBridge::getDisplayName() const
{
- return getName();
+ if(mDisplayName.empty())
+ {
+ buildDisplayName();
+ }
+ return mDisplayName;
}
// Folders have full perms
@@ -227,9 +232,24 @@ LLFolderType::EType LLInvFVBridge::getPreferredType() const
// Folders don't have creation dates.
time_t LLInvFVBridge::getCreationDate() const
{
- return 0;
+ LLInventoryObject* objectp = getInventoryObject();
+ if (objectp)
+ {
+ return objectp->getCreationDate();
+ }
+ return (time_t)0;
+}
+
+void LLInvFVBridge::setCreationDate(time_t creation_date_utc)
+{
+ LLInventoryObject* objectp = getInventoryObject();
+ if (objectp)
+ {
+ objectp->setCreationDate(creation_date_utc);
+ }
}
+
// Can be destroyed (or moved to trash)
BOOL LLInvFVBridge::isItemRemovable() const
{
@@ -283,7 +303,7 @@ void LLInvFVBridge::showProperties()
*/
}
-void LLInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch)
+void LLInvFVBridge::removeBatch(std::vector<LLFolderViewModelItem*>& batch)
{
// Deactivate gestures when moving them into Trash
LLInvFVBridge* bridge;
@@ -292,11 +312,11 @@ void LLInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batc
LLViewerInventoryCategory* cat = NULL;
LLInventoryModel::cat_array_t descendent_categories;
LLInventoryModel::item_array_t descendent_items;
- S32 count = batch.count();
+ S32 count = batch.size();
S32 i,j;
for(i = 0; i < count; ++i)
{
- bridge = (LLInvFVBridge*)(batch.get(i));
+ bridge = (LLInvFVBridge*)(batch[i]);
if(!bridge || !bridge->isItemRemovable()) continue;
item = (LLViewerInventoryItem*)model->getItem(bridge->getUUID());
if (item)
@@ -309,7 +329,7 @@ void LLInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batc
}
for(i = 0; i < count; ++i)
{
- bridge = (LLInvFVBridge*)(batch.get(i));
+ bridge = (LLInvFVBridge*)(batch[i]);
if(!bridge || !bridge->isItemRemovable()) continue;
cat = (LLViewerInventoryCategory*)model->getCategory(bridge->getUUID());
if (cat)
@@ -327,7 +347,7 @@ void LLInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batc
removeBatchNoCheck(batch);
}
-void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*>& batch)
+void LLInvFVBridge::removeBatchNoCheck(std::vector<LLFolderViewModelItem*>& batch)
{
// this method moves a bunch of items and folders to the trash. As
// per design guidelines for the inventory model, the message is
@@ -343,14 +363,14 @@ void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*
uuid_vec_t move_ids;
LLInventoryModel::update_map_t update;
bool start_new_message = true;
- S32 count = batch.count();
+ S32 count = batch.size();
S32 i;
// first, hide any 'preview' floaters that correspond to the items
// being deleted.
for(i = 0; i < count; ++i)
{
- bridge = (LLInvFVBridge*)(batch.get(i));
+ bridge = (LLInvFVBridge*)(batch[i]);
if(!bridge || !bridge->isItemRemovable()) continue;
item = (LLViewerInventoryItem*)model->getItem(bridge->getUUID());
if(item)
@@ -363,7 +383,7 @@ void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*
for(i = 0; i < count; ++i)
{
- bridge = (LLInvFVBridge*)(batch.get(i));
+ bridge = (LLInvFVBridge*)(batch[i]);
if(!bridge || !bridge->isItemRemovable()) continue;
item = (LLViewerInventoryItem*)model->getItem(bridge->getUUID());
if(item)
@@ -404,7 +424,7 @@ void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*
for(i = 0; i < count; ++i)
{
- bridge = (LLInvFVBridge*)(batch.get(i));
+ bridge = (LLInvFVBridge*)(batch[i]);
if(!bridge || !bridge->isItemRemovable()) continue;
LLViewerInventoryCategory* cat = (LLViewerInventoryCategory*)model->getCategory(bridge->getUUID());
if(cat)
@@ -876,6 +896,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();
@@ -1000,6 +1026,7 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type,
LLAssetType::EType actual_asset_type,
LLInventoryType::EType inv_type,
LLInventoryPanel* inventory,
+ LLFolderViewModelInventory* view_model,
LLFolderView* root,
const LLUUID& uuid,
U32 flags)
@@ -1125,12 +1152,13 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type,
default:
llinfos << "Unhandled asset type (llassetstorage.h): "
<< (S32)asset_type << " (" << LLAssetType::lookup(asset_type) << ")" << llendl;
- break;
+ break;
}
if (new_listener)
{
new_listener->mInvType = inv_type;
+ new_listener->setRootViewModel(view_model);
}
return new_listener;
@@ -1250,10 +1278,10 @@ bool LLInvFVBridge::canListOnMarketplaceNow() const
if (can_list)
{
- LLFolderViewFolder * object_folderp = mRoot->getFolderByID(object_id);
+ LLFolderViewFolder * object_folderp = mInventoryPanel.get() ? mInventoryPanel.get()->getFolderByID(object_id) : NULL;
if (object_folderp)
{
- can_list = !object_folderp->isLoading();
+ can_list = !static_cast<LLFolderBridge*>(object_folderp->getViewModelItem())->isLoading();
}
}
@@ -1261,7 +1289,7 @@ bool LLInvFVBridge::canListOnMarketplaceNow() const
{
// Get outbox id
const LLUUID & outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
- LLFolderViewItem * outbox_itemp = mRoot->getItemByID(outbox_id);
+ LLFolderViewItem * outbox_itemp = mInventoryPanel.get() ? mInventoryPanel.get()->getItemByID(outbox_id) : NULL;
if (outbox_itemp)
{
@@ -1271,7 +1299,7 @@ bool LLInvFVBridge::canListOnMarketplaceNow() const
void * cargo_data = (void *) obj;
std::string tooltip_msg;
- can_list = outbox_itemp->getListener()->dragOrDrop(mask, drop, cargo_type, cargo_data, tooltip_msg);
+ can_list = outbox_itemp->getViewModelItem()->dragOrDrop(mask, drop, cargo_type, cargo_data, tooltip_msg);
}
}
}
@@ -1283,6 +1311,21 @@ bool LLInvFVBridge::canListOnMarketplaceNow() const
#endif
}
+LLToolDragAndDrop::ESource LLInvFVBridge::getDragSource() const
+{
+ if (gInventory.isObjectDescendentOf(getUUID(), gInventory.getRootFolderID()))
+ {
+ return LLToolDragAndDrop::SOURCE_AGENT;
+ }
+ else if (gInventory.isObjectDescendentOf(getUUID(), gInventory.getLibraryRootFolderID()))
+ {
+ return LLToolDragAndDrop::SOURCE_LIBRARY;
+ }
+
+ return LLToolDragAndDrop::SOURCE_VIEWER;
+}
+
+
// +=================================================+
// | InventoryFVBridgeBuilder |
@@ -1291,6 +1334,7 @@ LLInvFVBridge* LLInventoryFVBridgeBuilder::createBridge(LLAssetType::EType asset
LLAssetType::EType actual_asset_type,
LLInventoryType::EType inv_type,
LLInventoryPanel* inventory,
+ LLFolderViewModelInventory* view_model,
LLFolderView* root,
const LLUUID& uuid,
U32 flags /* = 0x00 */) const
@@ -1299,6 +1343,7 @@ LLInvFVBridge* LLInventoryFVBridgeBuilder::createBridge(LLAssetType::EType asset
actual_asset_type,
inv_type,
inventory,
+ view_model,
root,
uuid,
flags);
@@ -1355,7 +1400,7 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)
else if ("cut" == action)
{
cutToClipboard();
- LLFolderView::removeCutItems();
+ gInventory.removeObject(mUUID);
return;
}
else if ("copy" == action)
@@ -1368,10 +1413,10 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)
LLInventoryItem* itemp = model->getItem(mUUID);
if (!itemp) return;
- LLFolderViewItem* folder_view_itemp = mRoot->getItemByID(itemp->getParentUUID());
+ LLFolderViewItem* folder_view_itemp = mInventoryPanel.get()->getItemByID(itemp->getParentUUID());
if (!folder_view_itemp) return;
- folder_view_itemp->getListener()->pasteFromClipboard();
+ folder_view_itemp->getViewModelItem()->pasteFromClipboard();
return;
}
else if ("paste_link" == action)
@@ -1380,10 +1425,10 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)
LLInventoryItem* itemp = model->getItem(mUUID);
if (!itemp) return;
- LLFolderViewItem* folder_view_itemp = mRoot->getItemByID(itemp->getParentUUID());
+ LLFolderViewItem* folder_view_itemp = mInventoryPanel.get()->getItemByID(itemp->getParentUUID());
if (!folder_view_itemp) return;
- folder_view_itemp->getListener()->pasteLinkFromClipboard();
+ folder_view_itemp->getViewModelItem()->pasteLinkFromClipboard();
return;
}
else if (isMarketplaceCopyAction(action))
@@ -1494,25 +1539,20 @@ PermissionMask LLItemBridge::getPermissionMask() const
return perm_mask;
}
-const std::string& LLItemBridge::getDisplayName() const
-{
- if(mDisplayName.empty())
- {
- buildDisplayName(getItem(), mDisplayName);
- }
- return mDisplayName;
-}
-
-void LLItemBridge::buildDisplayName(LLInventoryItem* item, std::string& name)
+void LLItemBridge::buildDisplayName() const
{
- if(item)
+ if(getItem())
{
- name.assign(item->getName());
+ mDisplayName.assign(getItem()->getName());
}
else
{
- name.assign(LLStringUtil::null);
+ mDisplayName.assign(LLStringUtil::null);
}
+
+ mSearchableName.assign(mDisplayName);
+ mSearchableName.append(getLabelSuffix());
+ LLStringUtil::toUpper(mSearchableName);
}
LLFontGL::StyleFlags LLItemBridge::getLabelStyle() const
@@ -1629,25 +1669,23 @@ BOOL LLItemBridge::renameItem(const std::string& new_name)
{
LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
new_item->rename(new_name);
- buildDisplayName(new_item, mDisplayName);
new_item->updateServer(FALSE);
model->updateItem(new_item);
model->notifyObservers();
+ buildDisplayName();
}
// return FALSE because we either notified observers (& therefore
// rebuilt) or we didn't update.
return FALSE;
}
-
BOOL LLItemBridge::removeItem()
{
if(!isItemRemovable())
{
return FALSE;
}
-
// move it to the trash
LLPreview::hide(mUUID, TRUE);
@@ -1786,6 +1824,93 @@ void LLFolderBridge::selectItem()
LLInventoryModelBackgroundFetch::instance().start(getUUID(), true);
}
+void LLFolderBridge::buildDisplayName() const
+{
+ LLFolderType::EType preferred_type = getPreferredType();
+
+ // *TODO: to be removed when database supports multi language. This is a
+ // temporary attempt to display the inventory folder in the user locale.
+ // mantipov: *NOTE: be sure this code is synchronized with LLFriendCardsManager::findChildFolderUUID
+ // it uses the same way to find localized string
+
+ // HACK: EXT - 6028 ([HARD CODED]? Inventory > Library > "Accessories" folder)
+ // Translation of Accessories folder in Library inventory folder
+ bool accessories = false;
+ if(getName() == "Accessories")
+ {
+ //To ensure that Accessories folder is in Library we have to check its parent folder.
+ //Due to parent LLFolderViewFloder is not set to this item yet we have to check its parent via Inventory Model
+ LLInventoryCategory* cat = gInventory.getCategory(getUUID());
+ if(cat)
+ {
+ const LLUUID& parent_folder_id = cat->getParentUUID();
+ accessories = (parent_folder_id == gInventory.getLibraryRootFolderID());
+ }
+ }
+
+ //"Accessories" inventory category has folder type FT_NONE. So, this folder
+ //can not be detected as protected with LLFolderType::lookupIsProtectedType
+ mDisplayName.assign(getName());
+ if (accessories || LLFolderType::lookupIsProtectedType(preferred_type))
+ {
+ LLTrans::findString(mDisplayName, std::string("InvFolder ") + getName(), LLSD());
+ }
+
+ mSearchableName.assign(mDisplayName);
+ mSearchableName.append(getLabelSuffix());
+ LLStringUtil::toUpper(mSearchableName);
+}
+
+
+void LLFolderBridge::update()
+{
+ bool possibly_has_children = false;
+ bool up_to_date = isUpToDate();
+ if(!up_to_date && hasChildren()) // we know we have children but haven't fetched them (doesn't obey filter)
+ {
+ possibly_has_children = true;
+ }
+
+ bool loading = (possibly_has_children
+ && !up_to_date );
+
+ if (loading != mIsLoading)
+ {
+ if ( loading && !mIsLoading )
+ {
+ // Measure how long we've been in the loading state
+ mTimeSinceRequestStart.reset();
+ }
+
+ const BOOL in_inventory = gInventory.isObjectDescendentOf(getUUID(), gInventory.getRootFolderID());
+ const BOOL in_library = gInventory.isObjectDescendentOf(getUUID(), gInventory.getLibraryRootFolderID());
+
+ bool root_is_loading = false;
+ if (in_inventory)
+ {
+ root_is_loading = LLInventoryModelBackgroundFetch::instance().inventoryFetchInProgress();
+ }
+ if (in_library)
+ {
+ root_is_loading = LLInventoryModelBackgroundFetch::instance().libraryFetchInProgress();
+ }
+ if ((mIsLoading
+ && mTimeSinceRequestStart.getElapsedTimeF32() >= gSavedSettings.getF32("FolderLoadingMessageWaitTime"))
+ || (LLInventoryModelBackgroundFetch::instance().folderFetchActive()
+ && root_is_loading))
+ {
+ mDisplayName = LLInvFVBridge::getDisplayName() + " ( " + LLTrans::getString("LoadingData") + " ) ";
+ mIsLoading = true;
+ }
+ else
+ {
+ mDisplayName = LLInvFVBridge::getDisplayName();
+ mIsLoading = false;
+ }
+ }
+}
+
+
// Iterate through a folder's children to determine if
// all the children are removable.
class LLIsItemRemovable : public LLFolderViewFunctor
@@ -1794,11 +1919,11 @@ public:
LLIsItemRemovable() : mPassed(TRUE) {}
virtual void doFolder(LLFolderViewFolder* folder)
{
- mPassed &= folder->getListener()->isItemRemovable();
+ mPassed &= folder->getViewModelItem()->isItemRemovable();
}
virtual void doItem(LLFolderViewItem* item)
{
- mPassed &= item->getListener()->isItemRemovable();
+ mPassed &= item->getViewModelItem()->isItemRemovable();
}
BOOL mPassed;
};
@@ -1812,7 +1937,7 @@ BOOL LLFolderBridge::isItemRemovable() const
}
LLInventoryPanel* panel = mInventoryPanel.get();
- LLFolderViewFolder* folderp = dynamic_cast<LLFolderViewFolder*>(panel ? panel->getRootFolder()->getItemByID(mUUID) : NULL);
+ LLFolderViewFolder* folderp = dynamic_cast<LLFolderViewFolder*>(panel ? panel->getItemByID(mUUID) : NULL);
if (folderp)
{
LLIsItemRemovable folder_test;
@@ -2051,7 +2176,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
LLInventoryPanel* destination_panel = mInventoryPanel.get();
if (!destination_panel) return false;
- LLInventoryFilter* filter = destination_panel->getFilter();
+ LLInventoryFilter* filter = getInventoryFilter();
if (!filter) return false;
const LLUUID &cat_id = inv_cat->getUUID();
@@ -2270,7 +2395,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
{
// Check whether the folder being dragged from active inventory panel
// passes the filter of the destination panel.
- is_movable = check_category(model, cat_id, active_folder_view, filter);
+ is_movable = check_category(model, cat_id, active_panel, filter);
}
}
}
@@ -2696,7 +2821,7 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
{
if ("open" == action)
{
- LLFolderViewFolder *f = dynamic_cast<LLFolderViewFolder *>(mRoot->getItemByID(mUUID));
+ LLFolderViewFolder *f = dynamic_cast<LLFolderViewFolder *>(mInventoryPanel.get()->getItemByID(mUUID));
if (f)
{
f->setOpen(TRUE);
@@ -2743,7 +2868,7 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
else if ("cut" == action)
{
cutToClipboard();
- LLFolderView::removeCutItems();
+ gInventory.removeObject(mUUID);
return;
}
else if ("copy" == action)
@@ -2880,17 +3005,24 @@ LLUIImagePtr LLFolderBridge::getIcon() const
LLUIImagePtr LLFolderBridge::getIcon(LLFolderType::EType preferred_type)
{
return LLUI::getUIImage(LLViewerFolderType::lookupIconName(preferred_type, FALSE));
- /*case LLAssetType::AT_MESH:
- control = "inv_folder_mesh.tga";
- break;*/
}
-LLUIImagePtr LLFolderBridge::getOpenIcon() const
+LLUIImagePtr LLFolderBridge::getIconOpen() const
{
return LLUI::getUIImage(LLViewerFolderType::lookupIconName(getPreferredType(), TRUE));
}
+LLUIImagePtr LLFolderBridge::getIconOverlay() const
+{
+ if (getInventoryObject() && getInventoryObject()->getIsLinkType())
+ {
+ return LLUI::getUIImage("Inv_Link");
+ }
+ return NULL;
+}
+
+
BOOL LLFolderBridge::renameItem(const std::string& new_name)
{
rename_category(getInventoryModel(), mUUID, new_name);
@@ -2971,7 +3103,7 @@ void LLFolderBridge::pasteFromClipboard()
if (move_is_into_outbox)
{
- LLFolderViewItem * outbox_itemp = mRoot->getItemByID(mUUID);
+ LLFolderViewItem * outbox_itemp = mInventoryPanel.get()->getItemByID(mUUID);
if (outbox_itemp)
{
@@ -2994,7 +3126,7 @@ void LLFolderBridge::pasteFromClipboard()
void * cargo_data = (void *) item;
std::string tooltip_msg;
- can_list = outbox_itemp->getListener()->dragOrDrop(mask, drop, cargo_type, cargo_data, tooltip_msg);
+ can_list = outbox_itemp->getViewModelItem()->dragOrDrop(mask, drop, cargo_type, cargo_data, tooltip_msg);
}
}
@@ -3166,7 +3298,7 @@ BOOL LLFolderBridge::checkFolderForContentsOfType(LLInventoryModel* model, LLInv
return ((item_array.count() > 0) ? TRUE : FALSE );
}
-void LLFolderBridge::buildContextMenuBaseOptions(U32 flags)
+void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items, menuentry_vec_t& disabled_items)
{
LLInventoryModel* model = getInventoryModel();
llassert(model != NULL);
@@ -3177,30 +3309,30 @@ void LLFolderBridge::buildContextMenuBaseOptions(U32 flags)
if (lost_and_found_id == mUUID)
{
// This is the lost+found folder.
- mItems.push_back(std::string("Empty Lost And Found"));
+ items.push_back(std::string("Empty Lost And Found"));
- mDisabledItems.push_back(std::string("New Folder"));
- mDisabledItems.push_back(std::string("New Script"));
- mDisabledItems.push_back(std::string("New Note"));
- mDisabledItems.push_back(std::string("New Gesture"));
- mDisabledItems.push_back(std::string("New Clothes"));
- mDisabledItems.push_back(std::string("New Body Parts"));
+ disabled_items.push_back(std::string("New Folder"));
+ disabled_items.push_back(std::string("New Script"));
+ disabled_items.push_back(std::string("New Note"));
+ disabled_items.push_back(std::string("New Gesture"));
+ disabled_items.push_back(std::string("New Clothes"));
+ disabled_items.push_back(std::string("New Body Parts"));
}
if(trash_id == mUUID)
{
// This is the trash.
- mItems.push_back(std::string("Empty Trash"));
+ items.push_back(std::string("Empty Trash"));
}
else if(isItemInTrash())
{
// This is a folder in the trash.
- mItems.clear(); // clear any items that used to exist
- addTrashContextMenuOptions(mItems, mDisabledItems);
+ items.clear(); // clear any items that used to exist
+ addTrashContextMenuOptions(items, disabled_items);
}
else if(isOutboxFolder())
{
- addOutboxContextMenuOptions(flags, mItems, mDisabledItems);
+ addOutboxContextMenuOptions(flags, items, disabled_items);
}
else if(isAgentInventory()) // do not allow creating in library
{
@@ -3214,40 +3346,40 @@ void LLFolderBridge::buildContextMenuBaseOptions(U32 flags)
// Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694.
if (!LLFriendCardsManager::instance().isCategoryInFriendFolder(cat))
{
- mItems.push_back(std::string("New Folder"));
+ items.push_back(std::string("New Folder"));
}
- mItems.push_back(std::string("New Script"));
- mItems.push_back(std::string("New Note"));
- mItems.push_back(std::string("New Gesture"));
- mItems.push_back(std::string("New Clothes"));
- mItems.push_back(std::string("New Body Parts"));
+ items.push_back(std::string("New Script"));
+ items.push_back(std::string("New Note"));
+ items.push_back(std::string("New Gesture"));
+ items.push_back(std::string("New Clothes"));
+ items.push_back(std::string("New Body Parts"));
}
#if SUPPORT_ENSEMBLES
// Changing folder types is an unfinished unsupported feature
// and can lead to unexpected behavior if enabled.
- mItems.push_back(std::string("Change Type"));
+ items.push_back(std::string("Change Type"));
const LLViewerInventoryCategory *cat = getCategory();
if (cat && LLFolderType::lookupIsProtectedType(cat->getPreferredType()))
{
- mDisabledItems.push_back(std::string("Change Type"));
+ disabled_items.push_back(std::string("Change Type"));
}
#endif
- getClipboardEntries(false, mItems, mDisabledItems, flags);
+ getClipboardEntries(false, items, disabled_items, flags);
}
else
{
// Want some but not all of the items from getClipboardEntries for outfits.
if (cat && (cat->getPreferredType() == LLFolderType::FT_OUTFIT))
{
- mItems.push_back(std::string("Rename"));
+ items.push_back(std::string("Rename"));
- addDeleteContextMenuOptions(mItems, mDisabledItems);
+ addDeleteContextMenuOptions(items, disabled_items);
// EXT-4030: disallow deletion of currently worn outfit
const LLViewerInventoryItem *base_outfit_link = LLAppearanceMgr::instance().getBaseOutfitLink();
if (base_outfit_link && (cat == base_outfit_link->getLinkedCategory()))
{
- mDisabledItems.push_back(std::string("Delete"));
+ disabled_items.push_back(std::string("Delete"));
}
}
}
@@ -3276,20 +3408,44 @@ void LLFolderBridge::buildContextMenuBaseOptions(U32 flags)
// Preemptively disable system folder removal if more than one item selected.
if ((flags & FIRST_SELECTED_ITEM) == 0)
{
- mDisabledItems.push_back(std::string("Delete System Folder"));
+ disabled_items.push_back(std::string("Delete System Folder"));
}
if (!isOutboxFolder())
{
- mItems.push_back(std::string("Share"));
+ items.push_back(std::string("Share"));
if (!canShare())
{
- mDisabledItems.push_back(std::string("Share"));
+ disabled_items.push_back(std::string("Share"));
+ }
+ }
+ // Add menu items that are dependent on the contents of the folder.
+ LLViewerInventoryCategory* category = (LLViewerInventoryCategory *) model->getCategory(mUUID);
+ if (category)
+ {
+ uuid_vec_t folders;
+ folders.push_back(category->getUUID());
+
+ sSelf = getHandle();
+ LLRightClickInventoryFetchDescendentsObserver* fetch = new LLRightClickInventoryFetchDescendentsObserver(folders);
+ fetch->startFetch();
+ if (fetch->isFinished())
+ {
+ // Do not call execute() or done() here as if the folder is here, there's likely no point drilling down
+ // This saves lots of time as buildContextMenu() is called a lot
+ delete fetch;
+ buildContextMenuFolderOptions(flags, items, disabled_items);
+ }
+ else
+ {
+ // it's all on its way - add an observer, and the inventory will call done for us when everything is here.
+ inc_busy_count();
+ gInventory.addObserver(fetch);
}
}
}
-void LLFolderBridge::buildContextMenuFolderOptions(U32 flags)
+void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t& items, menuentry_vec_t& disabled_items)
{
// Build folder specific options back up
LLInventoryModel* model = getInventoryModel();
@@ -3316,21 +3472,21 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags)
LLIsType is_callingcard(LLAssetType::AT_CALLINGCARD);
if (mCallingCards || checkFolderForContentsOfType(model, is_callingcard))
{
- mItems.push_back(std::string("Calling Card Separator"));
- mItems.push_back(std::string("Conference Chat Folder"));
- mItems.push_back(std::string("IM All Contacts In Folder"));
+ items.push_back(std::string("Calling Card Separator"));
+ items.push_back(std::string("Conference Chat Folder"));
+ items.push_back(std::string("IM All Contacts In Folder"));
}
}
if (!isItemRemovable())
{
- mDisabledItems.push_back(std::string("Delete"));
+ disabled_items.push_back(std::string("Delete"));
}
#ifndef LL_RELEASE_FOR_DOWNLOAD
if (LLFolderType::lookupIsProtectedType(type))
{
- mItems.push_back(std::string("Delete System Folder"));
+ items.push_back(std::string("Delete System Folder"));
}
#endif
@@ -3345,7 +3501,7 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags)
checkFolderForContentsOfType(model, is_object) ||
checkFolderForContentsOfType(model, is_gesture) )
{
- mItems.push_back(std::string("Folder Wearables Separator"));
+ items.push_back(std::string("Folder Wearables Separator"));
// Only enable add/replace outfit for non-system folders.
if (!is_system_folder)
@@ -3353,25 +3509,25 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags)
// Adding an outfit onto another (versus replacing) doesn't make sense.
if (type != LLFolderType::FT_OUTFIT)
{
- mItems.push_back(std::string("Add To Outfit"));
+ items.push_back(std::string("Add To Outfit"));
}
- mItems.push_back(std::string("Replace Outfit"));
+ items.push_back(std::string("Replace Outfit"));
}
if (is_ensemble)
{
- mItems.push_back(std::string("Wear As Ensemble"));
+ items.push_back(std::string("Wear As Ensemble"));
}
- mItems.push_back(std::string("Remove From Outfit"));
+ items.push_back(std::string("Remove From Outfit"));
if (!LLAppearanceMgr::getCanRemoveFromCOF(mUUID))
{
- mDisabledItems.push_back(std::string("Remove From Outfit"));
+ disabled_items.push_back(std::string("Remove From Outfit"));
}
if (!LLAppearanceMgr::instance().getCanReplaceCOF(mUUID))
{
- mDisabledItems.push_back(std::string("Replace Outfit"));
+ disabled_items.push_back(std::string("Replace Outfit"));
}
- mItems.push_back(std::string("Outfit Separator"));
+ items.push_back(std::string("Outfit Separator"));
}
}
@@ -3380,49 +3536,28 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
sSelf.markDead();
- mItems.clear();
- mDisabledItems.clear();
+ // fetch contents of this folder, as context menu can depend on contents
+ // still, user would have to open context menu again to see the changes
+ gInventory.fetchDescendentsOf(getUUID());
+
+
+ menuentry_vec_t items;
+ menuentry_vec_t disabled_items;
lldebugs << "LLFolderBridge::buildContextMenu()" << llendl;
LLInventoryModel* model = getInventoryModel();
if(!model) return;
- buildContextMenuBaseOptions(flags);
-
- // Add menu items that are dependent on the contents of the folder.
- LLViewerInventoryCategory* category = (LLViewerInventoryCategory *) model->getCategory(mUUID);
- if (category)
- {
- uuid_vec_t folders;
- folders.push_back(category->getUUID());
-
- sSelf = getHandle();
- LLRightClickInventoryFetchDescendentsObserver* fetch = new LLRightClickInventoryFetchDescendentsObserver(folders);
- fetch->startFetch();
- if (fetch->isFinished())
- {
- // Do not call execute() or done() here as if the folder is here, there's likely no point drilling down
- // This saves lots of time as buildContextMenu() is called a lot
- delete fetch;
- buildContextMenuFolderOptions(flags);
- }
- else
- {
- // it's all on its way - add an observer, and the inventory will call done for us when everything is here.
- inc_busy_count();
- gInventory.addObserver(fetch);
- }
- }
-
- hide_context_entries(menu, mItems, mDisabledItems);
+ buildContextMenuOptions(flags, items, disabled_items);
+ hide_context_entries(menu, items, disabled_items);
// Reposition the menu, in case we're adding items to an existing menu.
menu.needsArrange();
menu.arrangeAndClear();
}
-BOOL LLFolderBridge::hasChildren() const
+bool LLFolderBridge::hasChildren() const
{
LLInventoryModel* model = getInventoryModel();
if(!model) return FALSE;
@@ -3512,25 +3647,6 @@ void LLFolderBridge::pasteClipboard(void* user_data)
if(self) self->pasteFromClipboard();
}
-void LLFolderBridge::createNewCategory(void* user_data)
-{
- LLFolderBridge* bridge = (LLFolderBridge*)user_data;
- if(!bridge) return;
- LLInventoryPanel* panel = bridge->mInventoryPanel.get();
- if (!panel) return;
- LLInventoryModel* model = panel->getModel();
- if(!model) return;
- LLUUID id;
- id = model->createNewCategory(bridge->getUUID(),
- LLFolderType::FT_NONE,
- LLStringUtil::null);
- model->notifyObservers();
-
- // At this point, the bridge has probably been deleted, but the
- // view is still there.
- panel->setSelection(id, TAKE_FOCUS_YES);
-}
-
void LLFolderBridge::createNewShirt(void* user_data)
{
LLFolderBridge::createWearable((LLFolderBridge*)user_data, LLWearableType::WT_SHIRT);
@@ -3596,6 +3712,24 @@ void LLFolderBridge::createNewEyes(void* user_data)
LLFolderBridge::createWearable((LLFolderBridge*)user_data, LLWearableType::WT_EYES);
}
+EInventorySortGroup LLFolderBridge::getSortGroup() const
+{
+ LLFolderType::EType preferred_type = getPreferredType();
+
+ if (preferred_type == LLFolderType::FT_TRASH)
+ {
+ return SG_TRASH_FOLDER;
+ }
+
+ if(LLFolderType::lookupIsProtectedType(preferred_type))
+ {
+ return SG_SYSTEM_FOLDER;
+ }
+
+ return SG_NORMAL_FOLDER;
+}
+
+
// static
void LLFolderBridge::createWearable(LLFolderBridge* bridge, LLWearableType::EType type)
{
@@ -3698,9 +3832,10 @@ void LLFolderBridge::dropToFavorites(LLInventoryItem* inv_item)
LLPointer<AddFavoriteLandmarkCallback> cb = new AddFavoriteLandmarkCallback();
LLInventoryPanel* panel = mInventoryPanel.get();
LLFolderViewItem* drag_over_item = panel ? panel->getRootFolder()->getDraggingOverItem() : NULL;
- if (drag_over_item && drag_over_item->getListener())
+ LLFolderViewModelItemInventory* view_model = drag_over_item ? static_cast<LLFolderViewModelItemInventory*>(drag_over_item->getViewModelItem()) : NULL;
+ if (view_model)
{
- cb.get()->setTargetLandmarkId(drag_over_item->getListener()->getUUID());
+ cb.get()->setTargetLandmarkId(view_model->getUUID());
}
copy_inventory_item(
@@ -3749,7 +3884,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
LLInventoryPanel* destination_panel = mInventoryPanel.get();
if (!destination_panel) return false;
- LLInventoryFilter* filter = destination_panel->getFilter();
+ LLInventoryFilter* filter = getInventoryFilter();
if (!filter) return false;
const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false);
@@ -3866,13 +4001,10 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
// passes the filter of the destination panel.
if (accept && active_panel)
{
- LLFolderView* active_folder_view = active_panel->getRootFolder();
- if (!active_folder_view) return false;
-
- LLFolderViewItem* fv_item = active_folder_view->getItemByID(inv_item->getUUID());
+ LLFolderViewItem* fv_item = active_panel->getItemByID(inv_item->getUUID());
if (!fv_item) return false;
- accept = filter->check(fv_item);
+ accept = filter->check(fv_item->getViewModelItem());
}
if (accept && drop)
@@ -3884,6 +4016,8 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
}
// If an item is being dragged between windows, unselect everything in the active window
// so that we don't follow the selection to its new location (which is very annoying).
+ // RN: a better solution would be to deselect automatically when an item is moved
+ // and then select any item that is dropped only in the panel that it is dropped in
if (active_panel && (destination_panel != active_panel))
{
active_panel->unSelectAll();
@@ -3901,8 +4035,8 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
if (itemp)
{
LLUUID srcItemId = inv_item->getUUID();
- LLUUID destItemId = itemp->getListener()->getUUID();
- gInventory.rearrangeFavoriteLandmarks(srcItemId, destItemId);
+ LLUUID destItemId = static_cast<LLFolderViewModelItemInventory*>(itemp->getViewModelItem())->getUUID();
+ LLFavoritesOrderStorage::instance().rearrangeFavoriteLandmarks(srcItemId, destItemId);
}
}
@@ -4089,13 +4223,10 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
// passes the filter of the destination panel.
if (accept && active_panel)
{
- LLFolderView* active_folder_view = active_panel->getRootFolder();
- if (!active_folder_view) return false;
-
- LLFolderViewItem* fv_item = active_folder_view->getItemByID(inv_item->getUUID());
+ LLFolderViewItem* fv_item = active_panel->getItemByID(inv_item->getUUID());
if (!fv_item) return false;
- accept = filter->check(fv_item);
+ accept = filter->check(fv_item->getViewModelItem());
}
if (accept && drop)
@@ -4135,10 +4266,10 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
// static
bool check_category(LLInventoryModel* model,
const LLUUID& cat_id,
- LLFolderView* active_folder_view,
+ LLInventoryPanel* active_panel,
LLInventoryFilter* filter)
{
- if (!model || !active_folder_view || !filter)
+ if (!model || !active_panel || !filter)
return false;
if (!filter->checkFolder(cat_id))
@@ -4158,13 +4289,13 @@ bool check_category(LLInventoryModel* model,
// Empty folder should be checked as any other folder view item.
// If we are filtering by date the folder should not pass because
// it doesn't have its own creation date. See LLInvFVBridge::getCreationDate().
- return check_item(cat_id, active_folder_view, filter);
+ return check_item(cat_id, active_panel, filter);
}
for (S32 i = 0; i < num_descendent_categories; ++i)
{
LLInventoryCategory* category = descendent_categories[i];
- if(!check_category(model, category->getUUID(), active_folder_view, filter))
+ if(!check_category(model, category->getUUID(), active_panel, filter))
{
return false;
}
@@ -4173,7 +4304,7 @@ bool check_category(LLInventoryModel* model,
for (S32 i = 0; i < num_descendent_items; ++i)
{
LLViewerInventoryItem* item = descendent_items[i];
- if(!check_item(item->getUUID(), active_folder_view, filter))
+ if(!check_item(item->getUUID(), active_panel, filter))
{
return false;
}
@@ -4184,15 +4315,15 @@ bool check_category(LLInventoryModel* model,
// static
bool check_item(const LLUUID& item_id,
- LLFolderView* active_folder_view,
+ LLInventoryPanel* active_panel,
LLInventoryFilter* filter)
{
- if (!active_folder_view || !filter) return false;
+ if (!active_panel || !filter) return false;
- LLFolderViewItem* fv_item = active_folder_view->getItemByID(item_id);
+ LLFolderViewItem* fv_item = active_panel->getItemByID(item_id);
if (!fv_item) return false;
- return filter->check(fv_item);
+ return filter->check(fv_item->getViewModelItem());
}
// +=================================================+
@@ -4294,15 +4425,6 @@ void LLSoundBridge::openItem()
}
}
-void LLSoundBridge::previewItem()
-{
- LLViewerInventoryItem* item = getItem();
- if(item)
- {
- send_sound_trigger(item->getAssetUUID(), 1.0);
- }
-}
-
void LLSoundBridge::openSoundPreview(void* which)
{
LLSoundBridge *me = (LLSoundBridge *)which;
@@ -4518,7 +4640,7 @@ LLCallingCardBridge::~LLCallingCardBridge()
void LLCallingCardBridge::refreshFolderViewItem()
{
LLInventoryPanel* panel = mInventoryPanel.get();
- LLFolderViewItem* itemp = panel ? panel->getRootFolder()->getItemByID(mUUID) : NULL;
+ LLFolderViewItem* itemp = panel ? panel->getItemByID(mUUID) : NULL;
if (itemp)
{
itemp->refresh();
@@ -5309,11 +5431,10 @@ BOOL LLObjectBridge::renameItem(const std::string& new_name)
{
LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
new_item->rename(new_name);
- buildDisplayName(new_item, mDisplayName);
new_item->updateServer(FALSE);
model->updateItem(new_item);
-
model->notifyObservers();
+ buildDisplayName();
if (isAgentAvatarValid())
{
@@ -5913,16 +6034,6 @@ void LLMeshBridge::openItem()
}
}
-void LLMeshBridge::previewItem()
-{
- LLViewerInventoryItem* item = getItem();
- if(item)
- {
- // preview mesh
- }
-}
-
-
void LLMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
lldebugs << "LLMeshBridge::buildContextMenu()" << llendl;
@@ -6011,14 +6122,15 @@ void LLLinkFolderBridge::gotoItem()
const LLUUID &cat_uuid = getFolderID();
if (!cat_uuid.isNull())
{
- if (LLFolderViewItem *base_folder = mRoot->getItemByID(cat_uuid))
+ LLFolderViewItem *base_folder = mInventoryPanel.get()->getItemByID(cat_uuid);
+ if (base_folder)
{
if (LLInventoryModel* model = getInventoryModel())
{
model->fetchDescendentsOf(cat_uuid);
}
base_folder->setOpen(TRUE);
- mRoot->setSelectionFromRoot(base_folder,TRUE);
+ mRoot->setSelection(base_folder,TRUE);
mRoot->scrollToShowSelection();
}
}
@@ -6349,9 +6461,8 @@ LLInvFVBridgeAction* LLInvFVBridgeAction::createAction(LLAssetType::EType asset_
/************************************************************************/
void LLRecentItemsFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
- LLFolderBridge::buildContextMenu(menu, flags);
-
- menuentry_vec_t disabled_items, items = getMenuItems();
+ menuentry_vec_t disabled_items, items;
+ buildContextMenuOptions(flags, items, disabled_items);
items.erase(std::remove(items.begin(), items.end(), std::string("New Folder")), items.end());
@@ -6363,42 +6474,30 @@ LLInvFVBridge* LLRecentInventoryBridgeBuilder::createBridge(
LLAssetType::EType actual_asset_type,
LLInventoryType::EType inv_type,
LLInventoryPanel* inventory,
+ LLFolderViewModelInventory* view_model,
LLFolderView* root,
const LLUUID& uuid,
U32 flags /*= 0x00*/ ) const
{
LLInvFVBridge* new_listener = NULL;
- switch(asset_type)
+ if (asset_type == LLAssetType::AT_CATEGORY
+ && actual_asset_type != LLAssetType::AT_LINK_FOLDER)
{
- case LLAssetType::AT_CATEGORY:
- if (actual_asset_type == LLAssetType::AT_LINK_FOLDER)
- {
- // *TODO: Create a link folder handler instead if it is necessary
- new_listener = LLInventoryFVBridgeBuilder::createBridge(
- asset_type,
- actual_asset_type,
- inv_type,
- inventory,
- root,
- uuid,
- flags);
- break;
- }
new_listener = new LLRecentItemsFolderBridge(inv_type, inventory, root, uuid);
- break;
- default:
- new_listener = LLInventoryFVBridgeBuilder::createBridge(
- asset_type,
- actual_asset_type,
- inv_type,
- inventory,
- root,
- uuid,
- flags);
+ new_listener->setRootViewModel(view_model);
+ }
+ else
+ {
+ new_listener = LLInventoryFVBridgeBuilder::createBridge(asset_type,
+ actual_asset_type,
+ inv_type,
+ inventory,
+ view_model,
+ root,
+ uuid,
+ flags);
}
return new_listener;
-
}
-
// EOF
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index dc9e88d54d..b4a91ca0f7 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -29,11 +29,13 @@
#include "llcallingcard.h"
#include "llfloaterproperties.h"
-#include "llfoldervieweventlistener.h"
+#include "llfolderviewmodel.h"
#include "llinventorymodel.h"
#include "llinventoryobserver.h"
+#include "llinventorypanel.h"
#include "llviewercontrol.h"
#include "llwearable.h"
+#include "lltooldraganddrop.h"
class LLInventoryFilter;
class LLInventoryPanel;
@@ -41,7 +43,7 @@ class LLInventoryModel;
class LLMenuGL;
class LLCallingCardObserver;
class LLViewerJointAttachment;
-
+class LLFolderView;
typedef std::vector<std::string> menuentry_vec_t;
@@ -56,7 +58,7 @@ typedef std::vector<std::string> menuentry_vec_t;
// functionality a bit. (except for folders, you can create those
// manually...)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLInvFVBridge : public LLFolderViewEventListener
+class LLInvFVBridge : public LLFolderViewModelItemInventory
{
public:
// This method is a convenience function which creates the correct
@@ -65,6 +67,7 @@ public:
LLAssetType::EType actual_asset_type,
LLInventoryType::EType inv_type,
LLInventoryPanel* inventory,
+ LLFolderViewModelInventory* view_model,
LLFolderView* root,
const LLUUID& uuid,
U32 flags = 0x00);
@@ -83,18 +86,20 @@ public:
virtual void restoreToWorld() {}
//--------------------------------------------------------------------
- // Inherited LLFolderViewEventListener functions
+ // Inherited LLFolderViewModelItemInventory functions
//--------------------------------------------------------------------
virtual const std::string& getName() const;
virtual const std::string& getDisplayName() const;
+ const std::string& getSearchableName() const { return mSearchableName; }
+
virtual PermissionMask getPermissionMask() const;
virtual LLFolderType::EType getPreferredType() const;
virtual time_t getCreationDate() const;
+ virtual void setCreationDate(time_t creation_date_utc);
virtual LLFontGL::StyleFlags getLabelStyle() const { return LLFontGL::NORMAL; }
virtual std::string getLabelSuffix() const { return LLStringUtil::null; }
virtual void openItem() {}
virtual void closeItem() {}
- virtual void previewItem() {openItem();}
virtual void showProperties();
virtual BOOL isItemRenameable() const { return TRUE; }
//virtual BOOL renameItem(const std::string& new_name) {}
@@ -103,8 +108,8 @@ public:
virtual BOOL isItemInTrash() const;
virtual BOOL isLink() const;
//virtual BOOL removeItem() = 0;
- virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch);
- virtual void move(LLFolderViewEventListener* new_parent_bridge) {}
+ virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch);
+ virtual void move(LLFolderViewModelItem* new_parent_bridge) {}
virtual BOOL isItemCopyable() const { return FALSE; }
virtual BOOL copyToClipboard() const;
virtual BOOL cutToClipboard() const;
@@ -115,6 +120,7 @@ public:
void getClipboardEntries(bool show_asset_id, menuentry_vec_t &items,
menuentry_vec_t &disabled_items, U32 flags);
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
+ virtual LLToolDragAndDrop::ESource getDragSource() const;
virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const;
virtual BOOL dragOrDrop(MASK mask, BOOL drop,
EDragAndDropType cargo_type,
@@ -122,6 +128,9 @@ public:
std::string& tooltip_msg) { return FALSE; }
virtual LLInventoryType::EType getInventoryType() const { return mInvType; }
virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_NONE; }
+ EInventorySortGroup getSortGroup() const { return SG_ITEM; }
+ virtual LLInventoryObject* getInventoryObject() const;
+
//--------------------------------------------------------------------
// Convenience functions for adding various common menu options.
@@ -138,16 +147,16 @@ protected:
protected:
LLInvFVBridge(LLInventoryPanel* inventory, LLFolderView* root, const LLUUID& uuid);
- LLInventoryObject* getInventoryObject() const;
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?
BOOL isAgentInventory() const; // false if lost or in the inventory library
- BOOL isCOFFolder() const; // true if COF or descendent of
- BOOL isInboxFolder() const; // true if COF or descendent of marketplace inbox
- BOOL isOutboxFolder() const; // true if COF or descendent of marketplace outbox
+ BOOL isCOFFolder() const; // true if COF or descendant of
+ BOOL isInboxFolder() const; // true if COF or descendant of marketplace inbox
+ BOOL isOutboxFolder() const; // true if COF or descendant of marketplace outbox
BOOL isOutboxFolderDirectParent() const;
const LLUUID getOutboxFolder() const;
@@ -160,14 +169,19 @@ protected:
LLViewerInventoryCategory* item,
const LLUUID& new_parent,
BOOL restamp);
- void removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*>& batch);
+ void removeBatchNoCheck(std::vector<LLFolderViewModelItem*>& batch);
protected:
- LLHandle<LLInventoryPanel> mInventoryPanel;
- LLFolderView* mRoot;
- const LLUUID mUUID; // item id
- LLInventoryType::EType mInvType;
- BOOL mIsLink;
+ LLHandle<LLInventoryPanel> mInventoryPanel;
+ LLFolderView* mRoot;
+ const LLUUID mUUID; // item id
+ LLInventoryType::EType mInvType;
+ bool mIsLink;
+ LLTimer mTimeSinceRequestStart;
+ mutable std::string mDisplayName;
+ mutable std::string mSearchableName;
+
void purgeItem(LLInventoryModel *model, const LLUUID &uuid);
+ virtual void buildDisplayName() const {}
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -184,6 +198,7 @@ public:
LLAssetType::EType actual_asset_type,
LLInventoryType::EType inv_type,
LLInventoryPanel* inventory,
+ LLFolderViewModelInventory* view_model,
LLFolderView* root,
const LLUUID& uuid,
U32 flags = 0x00) const;
@@ -203,7 +218,6 @@ public:
virtual void restoreToWorld();
virtual void gotoItem();
virtual LLUIImagePtr getIcon() const;
- virtual const std::string& getDisplayName() const;
virtual std::string getLabelSuffix() const;
virtual LLFontGL::StyleFlags getLabelStyle() const;
virtual PermissionMask getPermissionMask() const;
@@ -212,7 +226,7 @@ public:
virtual BOOL renameItem(const std::string& new_name);
virtual BOOL removeItem();
virtual BOOL isItemCopyable() const;
- virtual BOOL hasChildren() const { return FALSE; }
+ virtual bool hasChildren() const { return FALSE; }
virtual BOOL isUpToDate() const { return TRUE; }
/*virtual*/ void clearDisplayName() { mDisplayName.clear(); }
@@ -222,9 +236,8 @@ public:
protected:
BOOL confirmRemoveItem(const LLSD& notification, const LLSD& response);
virtual BOOL isItemPermissive() const;
- static void buildDisplayName(LLInventoryItem* item, std::string& name);
+ virtual void buildDisplayName() const;
- mutable std::string mDisplayName;
};
class LLFolderBridge : public LLInvFVBridge
@@ -232,15 +245,18 @@ class LLFolderBridge : public LLInvFVBridge
public:
LLFolderBridge(LLInventoryPanel* inventory,
LLFolderView* root,
- const LLUUID& uuid) :
- LLInvFVBridge(inventory, root, uuid),
+ const LLUUID& uuid)
+ : LLInvFVBridge(inventory, root, uuid),
mCallingCards(FALSE),
- mWearables(FALSE)
+ mWearables(FALSE),
+ mIsLoading(false)
{}
BOOL dragItemIntoFolder(LLInventoryItem* inv_item, BOOL drop, std::string& tooltip_msg);
BOOL dragCategoryIntoFolder(LLInventoryCategory* inv_category, BOOL drop, std::string& tooltip_msg);
+ virtual void buildDisplayName() const;
+
virtual void performAction(LLInventoryModel* model, std::string action);
virtual void openItem();
virtual void closeItem();
@@ -250,7 +266,9 @@ public:
virtual LLFolderType::EType getPreferredType() const;
virtual LLUIImagePtr getIcon() const;
- virtual LLUIImagePtr getOpenIcon() const;
+ virtual LLUIImagePtr getIconOpen() const;
+ virtual LLUIImagePtr getIconOverlay() const;
+
static LLUIImagePtr getIcon(LLFolderType::EType preferred_type);
virtual BOOL renameItem(const std::string& new_name);
@@ -262,7 +280,7 @@ public:
virtual void pasteFromClipboard();
virtual void pasteLinkFromClipboard();
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
- virtual BOOL hasChildren() const;
+ virtual bool hasChildren() const;
virtual BOOL dragOrDrop(MASK mask, BOOL drop,
EDragAndDropType cargo_type,
void* cargo_data,
@@ -275,20 +293,24 @@ public:
virtual BOOL isClipboardPasteable() const;
virtual BOOL isClipboardPasteableAsLink() const;
+ EInventorySortGroup getSortGroup() const;
+ virtual void update();
+
static void createWearable(LLFolderBridge* bridge, LLWearableType::EType type);
LLViewerInventoryCategory* getCategory() const;
LLHandle<LLFolderBridge> getHandle() { mHandle.bind(this); return mHandle; }
+ bool isLoading() { return mIsLoading; }
+
protected:
- void buildContextMenuBaseOptions(U32 flags);
- void buildContextMenuFolderOptions(U32 flags);
+ void buildContextMenuOptions(U32 flags, menuentry_vec_t& items, menuentry_vec_t& disabled_items);
+ void buildContextMenuFolderOptions(U32 flags, menuentry_vec_t& items, menuentry_vec_t& disabled_items);
//--------------------------------------------------------------------
// Menu callbacks
//--------------------------------------------------------------------
static void pasteClipboard(void* user_data);
- static void createNewCategory(void* user_data);
static void createNewShirt(void* user_data);
static void createNewPants(void* user_data);
static void createNewShoes(void* user_data);
@@ -308,8 +330,6 @@ protected:
void modifyOutfit(BOOL append);
void determineFolderType();
- menuentry_vec_t getMenuItems() { return mItems; } // returns a copy of current menu items
-
void dropToFavorites(LLInventoryItem* inv_item);
void dropToOutfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit);
@@ -321,11 +341,12 @@ public:
static void staticFolderOptionsMenu();
private:
- BOOL mCallingCards;
- BOOL mWearables;
- menuentry_vec_t mItems;
- menuentry_vec_t mDisabledItems;
- LLRootHandle<LLFolderBridge> mHandle;
+
+ bool mCallingCards;
+ bool mWearables;
+ bool mIsLoading;
+ LLTimer mTimeSinceRequestStart;
+ LLRootHandle<LLFolderBridge> mHandle;
};
class LLTextureBridge : public LLItemBridge
@@ -354,7 +375,6 @@ public:
const LLUUID& uuid) :
LLItemBridge(inventory, root, uuid) {}
virtual void openItem();
- virtual void previewItem();
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
static void openSoundPreview(void*);
};
@@ -544,7 +564,6 @@ class LLMeshBridge : public LLItemBridge
public:
virtual LLUIImagePtr getIcon() const;
virtual void openItem();
- virtual void previewItem();
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
protected:
@@ -629,6 +648,7 @@ public:
LLAssetType::EType actual_asset_type,
LLInventoryType::EType inv_type,
LLInventoryPanel* inventory,
+ LLFolderViewModelInventory* view_model,
LLFolderView* root,
const LLUUID& uuid,
U32 flags = 0x00) const;
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index 4d0af94f9f..3f38d80a39 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -29,7 +29,7 @@
#include "llinventoryfilter.h"
// viewer includes
-#include "llfoldervieweventlistener.h"
+#include "llfolderviewmodel.h"
#include "llfolderviewitem.h"
#include "llinventorymodel.h"
#include "llinventorymodelbackgroundfetch.h"
@@ -42,109 +42,91 @@
#include "llclipboard.h"
#include "lltrans.h"
+//TODO RN: fix use of static cast as much as possible
+
LLFastTimer::DeclareTimer FT_FILTER_CLIPBOARD("Filter Clipboard");
-LLInventoryFilter::FilterOps::FilterOps() :
- mFilterObjectTypes(0xffffffffffffffffULL),
- mFilterCategoryTypes(0xffffffffffffffffULL),
- mFilterWearableTypes(0xffffffffffffffffULL),
- mMinDate(time_min()),
- mMaxDate(time_max()),
- mHoursAgo(0),
- mShowFolderState(SHOW_NON_EMPTY_FOLDERS),
- mPermissions(PERM_NONE),
- mFilterTypes(FILTERTYPE_OBJECT),
- mFilterUUID(LLUUID::null),
- mFilterLinks(FILTERLINK_INCLUDE_LINKS)
+LLInventoryFilter::FilterOps::FilterOps(const Params& p)
+: mFilterObjectTypes(p.object_types),
+ mFilterCategoryTypes(p.category_types),
+ mFilterWearableTypes(p.wearable_types),
+ mMinDate(p.date_range.min_date),
+ mMaxDate(p.date_range.max_date),
+ mHoursAgo(p.hours_ago),
+ mShowFolderState(p.show_folder_state),
+ mPermissions(p.permissions),
+ mFilterTypes(p.types),
+ mFilterUUID(p.uuid),
+ mFilterLinks(p.links)
{
}
///----------------------------------------------------------------------------
/// Class LLInventoryFilter
///----------------------------------------------------------------------------
-LLInventoryFilter::LLInventoryFilter(const std::string& name)
-: mName(name),
- mModified(FALSE),
- mNeedTextRebuild(TRUE),
- mEmptyLookupMessage("InventoryNoMatchingItems")
+LLInventoryFilter::LLInventoryFilter(const Params& p)
+: mName(p.name),
+ mFilterModified(FILTER_NONE),
+ mEmptyLookupMessage("InventoryNoMatchingItems"),
+ mFilterOps(p.filter_ops),
+ mOrder(p.sort_order),
+ mFilterSubString(p.substring),
+ mCurrentGeneration(0),
+ mFirstRequiredGeneration(0),
+ mFirstSuccessGeneration(0),
+ mFilterCount(0)
{
- mOrder = SO_FOLDERS_BY_NAME; // This gets overridden by a pref immediately
-
- mSubStringMatchOffset = 0;
- mFilterSubString.clear();
- mFilterGeneration = 0;
- mMustPassGeneration = S32_MAX;
- mMinRequiredGeneration = 0;
- mFilterCount = 0;
- mNextFilterGeneration = mFilterGeneration + 1;
-
- mLastLogoff = gSavedPerAccountSettings.getU32("LastLogoff");
- mFilterBehavior = FILTER_NONE;
+ mNextFilterGeneration = mCurrentGeneration + 1;
// copy mFilterOps into mDefaultFilterOps
markDefault();
}
-LLInventoryFilter::~LLInventoryFilter()
-{
-}
-
-BOOL LLInventoryFilter::check(const LLFolderViewItem* item)
+bool LLInventoryFilter::check(const LLFolderViewModelItem* item)
{
+ const LLFolderViewModelItemInventory* listener = static_cast<const LLFolderViewModelItemInventory*>(item);
// Clipboard cut items are *always* filtered so we need this value upfront
- const LLFolderViewEventListener* listener = item->getListener();
const BOOL passed_clipboard = (listener ? checkAgainstClipboard(listener->getUUID()) : TRUE);
// If it's a folder and we're showing all folders, return automatically.
- const BOOL is_folder = (dynamic_cast<const LLFolderViewFolder*>(item) != NULL);
+ const BOOL is_folder = listener->getInventoryType() == LLInventoryType::IT_CATEGORY;;
if (is_folder && (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS))
{
return passed_clipboard;
}
- mSubStringMatchOffset = mFilterSubString.size() ? item->getSearchableLabel().find(mFilterSubString) : std::string::npos;
+ std::string::size_type string_offset = mFilterSubString.size() ? listener->getSearchableName().find(mFilterSubString) : 0;
- const BOOL passed_filtertype = checkAgainstFilterType(item);
- const BOOL passed_permissions = checkAgainstPermissions(item);
- const BOOL passed_filterlink = checkAgainstFilterLinks(item);
- const BOOL passed = (passed_filtertype &&
- passed_permissions &&
- passed_filterlink &&
- passed_clipboard &&
- (mFilterSubString.size() == 0 || mSubStringMatchOffset != std::string::npos));
+ BOOL passed = string_offset != std::string::npos;
+ passed = passed && checkAgainstFilterType(listener);
+ passed = passed && checkAgainstPermissions(listener);
+ passed = passed && checkAgainstFilterLinks(listener);
+ passed = passed && passed_clipboard;
return passed;
}
bool LLInventoryFilter::check(const LLInventoryItem* item)
{
- mSubStringMatchOffset = mFilterSubString.size() ? item->getName().find(mFilterSubString) : std::string::npos;
+ std::string::size_type string_offset = mFilterSubString.size() ? item->getName().find(mFilterSubString) : std::string::npos;
const bool passed_filtertype = checkAgainstFilterType(item);
const bool passed_permissions = checkAgainstPermissions(item);
const BOOL passed_clipboard = checkAgainstClipboard(item->getUUID());
- const bool passed = (passed_filtertype &&
- passed_permissions &&
- passed_clipboard &&
- (mFilterSubString.size() == 0 || mSubStringMatchOffset != std::string::npos));
+ const bool passed = (passed_filtertype
+ && passed_permissions
+ && passed_clipboard
+ && (mFilterSubString.size() == 0 || string_offset != std::string::npos));
return passed;
}
-bool LLInventoryFilter::checkFolder(const LLFolderViewFolder* folder) const
+bool LLInventoryFilter::checkFolder(const LLFolderViewModelItem* item) const
{
- if (!folder)
- {
- llwarns << "The filter can not be checked on an invalid folder." << llendl;
- llassert(false); // crash in development builds
- return false;
- }
-
- const LLFolderViewEventListener* listener = folder->getListener();
+ const LLFolderViewModelItemInventory* listener = static_cast<const LLFolderViewModelItemInventory*>(item);
if (!listener)
{
- llwarns << "Folder view event listener not found." << llendl;
- llassert(false); // crash in development builds
+ llerrs << "Folder view event listener not found." << llendl;
return false;
}
@@ -155,6 +137,13 @@ bool LLInventoryFilter::checkFolder(const LLFolderViewFolder* folder) const
bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const
{
+ // when applying a filter, matching folders get their contents downloaded first
+ if (isNotDefault()
+ && !gInventory.isCategoryComplete(folder_id))
+ {
+ LLInventoryModelBackgroundFetch::instance().start(folder_id);
+ }
+
// Always check against the clipboard
const BOOL passed_clipboard = checkAgainstClipboard(folder_id);
@@ -163,14 +152,14 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const
{
return passed_clipboard;
}
-
+
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;
@@ -179,9 +168,8 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const
return passed_clipboard;
}
-BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) const
+bool LLInventoryFilter::checkAgainstFilterType(const LLFolderViewModelItemInventory* listener) const
{
- const LLFolderViewEventListener* listener = item->getListener();
if (!listener) return FALSE;
LLInventoryType::EType object_type = listener->getInventoryType();
@@ -268,7 +256,7 @@ BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) con
}
}
}
-
+
return TRUE;
}
@@ -347,13 +335,12 @@ bool LLInventoryFilter::checkAgainstClipboard(const LLUUID& object_id) const
return true;
}
-BOOL LLInventoryFilter::checkAgainstPermissions(const LLFolderViewItem* item) const
+bool LLInventoryFilter::checkAgainstPermissions(const LLFolderViewModelItemInventory* listener) const
{
- const LLFolderViewEventListener* listener = item->getListener();
if (!listener) return FALSE;
PermissionMask perm = listener->getPermissionMask();
- const LLInvFVBridge *bridge = dynamic_cast<const LLInvFVBridge *>(item->getListener());
+ const LLInvFVBridge *bridge = dynamic_cast<const LLInvFVBridge *>(listener);
if (bridge && bridge->isLink())
{
const LLUUID& linked_uuid = gInventory.getLinkedItemID(bridge->getUUID());
@@ -375,9 +362,8 @@ bool LLInventoryFilter::checkAgainstPermissions(const LLInventoryItem* item) con
return (perm & mFilterOps.mPermissions) == mFilterOps.mPermissions;
}
-BOOL LLInventoryFilter::checkAgainstFilterLinks(const LLFolderViewItem* item) const
+bool LLInventoryFilter::checkAgainstFilterLinks(const LLFolderViewModelItemInventory* listener) const
{
- const LLFolderViewEventListener* listener = item->getListener();
if (!listener) return TRUE;
const LLUUID object_id = listener->getUUID();
@@ -397,20 +383,20 @@ const std::string& LLInventoryFilter::getFilterSubString(BOOL trim) const
return mFilterSubString;
}
-std::string::size_type LLInventoryFilter::getStringMatchOffset() const
+std::string::size_type LLInventoryFilter::getStringMatchOffset(LLFolderViewItem* item) const
{
- return mSubStringMatchOffset;
+ return mFilterSubString.size() ? item->getName().find(mFilterSubString) : std::string::npos;
}
-BOOL LLInventoryFilter::isDefault() const
+bool LLInventoryFilter::isDefault() const
{
return !isNotDefault();
}
// has user modified default filter params?
-BOOL LLInventoryFilter::isNotDefault() const
+bool LLInventoryFilter::isNotDefault() const
{
- BOOL not_default = FALSE;
+ S32 not_default = 0;
not_default |= (mFilterOps.mFilterObjectTypes != mDefaultFilterOps.mFilterObjectTypes);
not_default |= (mFilterOps.mFilterCategoryTypes != mDefaultFilterOps.mFilterCategoryTypes);
@@ -422,11 +408,11 @@ BOOL LLInventoryFilter::isNotDefault() const
not_default |= (mFilterOps.mMinDate != mDefaultFilterOps.mMinDate);
not_default |= (mFilterOps.mMaxDate != mDefaultFilterOps.mMaxDate);
not_default |= (mFilterOps.mHoursAgo != mDefaultFilterOps.mHoursAgo);
-
- return not_default;
+
+ return not_default != 0;
}
-BOOL LLInventoryFilter::isActive() const
+bool LLInventoryFilter::isActive() const
{
return mFilterOps.mFilterObjectTypes != 0xffffffffffffffffULL
|| mFilterOps.mFilterCategoryTypes != 0xffffffffffffffffULL
@@ -440,16 +426,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)
@@ -613,9 +592,10 @@ void LLInventoryFilter::setDateRange(time_t min_date, time_t max_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())
@@ -634,17 +614,18 @@ void LLInventoryFilter::setDateRangeLastLogoff(BOOL sl)
}
}
-BOOL LLInventoryFilter::isSinceLogoff() const
+bool LLInventoryFilter::isSinceLogoff() const
{
- return (mFilterOps.mMinDate == (time_t)mLastLogoff) &&
+ static LLCachedControl<U32> s_last_logoff(gSavedSettings, "LastLogoff", 0);
+
+ return (mFilterOps.mMinDate == (time_t)s_last_logoff()) &&
(mFilterOps.mMaxDate == time_max()) &&
(mFilterOps.mFilterTypes & FILTERTYPE_DATE);
}
void LLInventoryFilter::clearModified()
{
- mModified = FALSE;
- mFilterBehavior = FILTER_NONE;
+ mFilterModified = FILTER_NONE;
}
void LLInventoryFilter::setHoursAgo(U32 hours)
@@ -742,83 +723,68 @@ void LLInventoryFilter::resetDefault()
setModified();
}
-void LLInventoryFilter::setModified(EFilterBehavior behavior)
+void LLInventoryFilter::setModified(EFilterModified behavior)
{
- mModified = TRUE;
- mNeedTextRebuild = TRUE;
- mFilterGeneration = mNextFilterGeneration++;
+ mFilterText.clear();
+ mCurrentGeneration = mNextFilterGeneration++;
- 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(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:
- llerrs << "Bad filter behavior specified" << llendl;
- }
- }
- else
+ // if not keeping current filter results, update last valid as well
+ switch(mFilterModified)
{
- // 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:
+ llerrs << "Bad filter behavior specified" << llendl;
}
}
-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;
@@ -826,140 +792,120 @@ const std::string& LLInventoryFilter::getFilterText()
if (isFilterObjectTypesWith(LLInventoryType::IT_CALLINGCARD))
{
- //filtered_types += " Calling Cards,";
filtered_types += LLTrans::getString("Calling Cards");
filtered_by_type = TRUE;
num_filter_types++;
}
else
{
- //not_filtered_types += " Calling Cards,";
not_filtered_types += LLTrans::getString("Calling Cards");
filtered_by_all_types = FALSE;
}
if (isFilterObjectTypesWith(LLInventoryType::IT_WEARABLE))
{
- //filtered_types += " Clothing,";
filtered_types += LLTrans::getString("Clothing");
filtered_by_type = TRUE;
num_filter_types++;
}
else
{
- //not_filtered_types += " Clothing,";
not_filtered_types += LLTrans::getString("Clothing");
filtered_by_all_types = FALSE;
}
if (isFilterObjectTypesWith(LLInventoryType::IT_GESTURE))
{
- //filtered_types += " Gestures,";
filtered_types += LLTrans::getString("Gestures");
filtered_by_type = TRUE;
num_filter_types++;
}
else
{
- //not_filtered_types += " Gestures,";
not_filtered_types += LLTrans::getString("Gestures");
filtered_by_all_types = FALSE;
}
if (isFilterObjectTypesWith(LLInventoryType::IT_LANDMARK))
{
- //filtered_types += " Landmarks,";
filtered_types += LLTrans::getString("Landmarks");
filtered_by_type = TRUE;
num_filter_types++;
}
else
{
- //not_filtered_types += " Landmarks,";
not_filtered_types += LLTrans::getString("Landmarks");
filtered_by_all_types = FALSE;
}
if (isFilterObjectTypesWith(LLInventoryType::IT_NOTECARD))
{
- //filtered_types += " Notecards,";
filtered_types += LLTrans::getString("Notecards");
filtered_by_type = TRUE;
num_filter_types++;
}
else
{
- //not_filtered_types += " Notecards,";
not_filtered_types += LLTrans::getString("Notecards");
filtered_by_all_types = FALSE;
}
if (isFilterObjectTypesWith(LLInventoryType::IT_OBJECT) && isFilterObjectTypesWith(LLInventoryType::IT_ATTACHMENT))
{
- //filtered_types += " Objects,";
filtered_types += LLTrans::getString("Objects");
filtered_by_type = TRUE;
num_filter_types++;
}
else
{
- //not_filtered_types += " Objects,";
not_filtered_types += LLTrans::getString("Objects");
filtered_by_all_types = FALSE;
}
if (isFilterObjectTypesWith(LLInventoryType::IT_LSL))
{
- //filtered_types += " Scripts,";
filtered_types += LLTrans::getString("Scripts");
filtered_by_type = TRUE;
num_filter_types++;
}
else
{
- //not_filtered_types += " Scripts,";
not_filtered_types += LLTrans::getString("Scripts");
filtered_by_all_types = FALSE;
}
if (isFilterObjectTypesWith(LLInventoryType::IT_SOUND))
{
- //filtered_types += " Sounds,";
filtered_types += LLTrans::getString("Sounds");
filtered_by_type = TRUE;
num_filter_types++;
}
else
{
- //not_filtered_types += " Sounds,";
not_filtered_types += LLTrans::getString("Sounds");
filtered_by_all_types = FALSE;
}
if (isFilterObjectTypesWith(LLInventoryType::IT_TEXTURE))
{
- //filtered_types += " Textures,";
filtered_types += LLTrans::getString("Textures");
filtered_by_type = TRUE;
num_filter_types++;
}
else
{
- //not_filtered_types += " Textures,";
not_filtered_types += LLTrans::getString("Textures");
filtered_by_all_types = FALSE;
}
if (isFilterObjectTypesWith(LLInventoryType::IT_SNAPSHOT))
{
- //filtered_types += " Snapshots,";
filtered_types += LLTrans::getString("Snapshots");
filtered_by_type = TRUE;
num_filter_types++;
}
else
{
- //not_filtered_types += " Snapshots,";
not_filtered_types += LLTrans::getString("Snapshots");
filtered_by_all_types = FALSE;
}
@@ -975,7 +921,6 @@ const std::string& LLInventoryFilter::getFilterText()
}
else
{
- //mFilterText += "No ";
mFilterText += LLTrans::getString("No Filters");
mFilterText += not_filtered_types;
}
@@ -985,66 +930,58 @@ const std::string& LLInventoryFilter::getFilterText()
if (isSinceLogoff())
{
- //mFilterText += " - Since Logoff";
mFilterText += LLTrans::getString("Since Logoff");
}
return mFilterText;
}
-void LLInventoryFilter::toLLSD(LLSD& data) const
-{
- data["filter_types"] = (LLSD::Integer)getFilterObjectTypes();
- data["min_date"] = (LLSD::Integer)getMinDate();
- data["max_date"] = (LLSD::Integer)getMaxDate();
- data["hours_ago"] = (LLSD::Integer)getHoursAgo();
- data["show_folder_state"] = (LLSD::Integer)getShowFolderState();
- data["permissions"] = (LLSD::Integer)getFilterPermissions();
- data["substring"] = (LLSD::String)getFilterSubString();
- data["sort_order"] = (LLSD::Integer)getSortOrder();
- data["since_logoff"] = (LLSD::Boolean)isSinceLogoff();
-}
-
-void LLInventoryFilter::fromLLSD(LLSD& data)
-{
- if(data.has("filter_types"))
- {
- setFilterObjectTypes((U64)data["filter_types"].asInteger());
- }
-
- if(data.has("min_date") && data.has("max_date"))
- {
- setDateRange(data["min_date"].asInteger(), data["max_date"].asInteger());
- }
-
- if(data.has("hours_ago"))
- {
- setHoursAgo((U32)data["hours_ago"].asInteger());
- }
- if(data.has("show_folder_state"))
- {
- setShowFolderState((EFolderShow)data["show_folder_state"].asInteger());
- }
+LLInventoryFilter& LLInventoryFilter::operator=( const LLInventoryFilter& other )
+{
+ setFilterObjectTypes(other.getFilterObjectTypes());
+ setDateRange(other.getMinDate(), other.getMaxDate());
+ setHoursAgo(other.getHoursAgo());
+ setShowFolderState(other.getShowFolderState());
+ setFilterPermissions(other.getFilterPermissions());
+ setFilterSubString(other.getFilterSubString());
+ setSortOrder(other.getSortOrder());
+ setDateRangeLastLogoff(other.isSinceLogoff());
+ return *this;
+}
- if(data.has("permissions"))
- {
- setFilterPermissions((PermissionMask)data["permissions"].asInteger());
- }
- if(data.has("substring"))
- {
- setFilterSubString(std::string(data["substring"].asString()));
- }
+void LLInventoryFilter::toParams(Params& params) const
+{
+ params.filter_ops.types = getFilterObjectTypes();
+ params.filter_ops.category_types = getFilterCategoryTypes();
+ params.filter_ops.wearable_types = getFilterWearableTypes();
+ params.filter_ops.date_range.min_date = getMinDate();
+ params.filter_ops.date_range.max_date = getMaxDate();
+ params.filter_ops.hours_ago = getHoursAgo();
+ params.filter_ops.show_folder_state = getShowFolderState();
+ params.filter_ops.permissions = getFilterPermissions();
+ params.substring = getFilterSubString();
+ params.sort_order = getSortOrder();
+ params.since_logoff = isSinceLogoff();
+}
- if(data.has("sort_order"))
+void LLInventoryFilter::fromParams(const Params& params)
+{
+ if (!params.validateBlock())
{
- setSortOrder((U32)data["sort_order"].asInteger());
+ return;
}
- if(data.has("since_logoff"))
- {
- setDateRangeLastLogoff((bool)data["since_logoff"].asBoolean());
- }
+ setFilterObjectTypes(params.filter_ops.types);
+ setFilterCategoryTypes(params.filter_ops.category_types);
+ setFilterWearableTypes(params.filter_ops.wearable_types);
+ setDateRange(params.filter_ops.date_range.min_date, params.filter_ops.date_range.max_date);
+ setHoursAgo(params.filter_ops.hours_ago);
+ setShowFolderState(params.filter_ops.show_folder_state);
+ setFilterPermissions(params.filter_ops.permissions);
+ setFilterSubString(params.substring);
+ setSortOrder(params.sort_order);
+ setDateRangeLastLogoff(params.since_logoff);
}
U64 LLInventoryFilter::getFilterObjectTypes() const
@@ -1057,7 +994,12 @@ 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;
}
@@ -1092,10 +1034,6 @@ U32 LLInventoryFilter::getSortOrder() const
{
return mOrder;
}
-const std::string& LLInventoryFilter::getName() const
-{
- return mName;
-}
void LLInventoryFilter::setFilterCount(S32 count)
{
@@ -1113,15 +1051,15 @@ 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;
}
void LLInventoryFilter::setEmptyLookupMessage(const std::string& message)
@@ -1129,9 +1067,12 @@ void LLInventoryFilter::setEmptyLookupMessage(const std::string& message)
mEmptyLookupMessage = message;
}
-const std::string& LLInventoryFilter::getEmptyLookupMessage() const
+std::string LLInventoryFilter::getEmptyLookupMessage() const
{
- return mEmptyLookupMessage;
+ LLStringUtil::format_map_t args;
+ args["[SEARCH_TERM]"] = LLURI::escape(getFilterSubStringOrig());
+
+ return LLTrans::getString(mEmptyLookupMessage, args);
}
@@ -1141,3 +1082,27 @@ bool LLInventoryFilter::areDateLimitsSet()
|| mFilterOps.mMaxDate != time_max()
|| mFilterOps.mHoursAgo != 0;
}
+
+bool LLInventoryFilter::showAllResults() const
+{
+ return hasFilterString();
+}
+
+
+
+bool LLInventoryFilter::FilterOps::DateRange::validateBlock( bool emit_errors /*= true*/ ) const
+{
+ bool valid = LLInitParam::Block<DateRange>::validateBlock(emit_errors);
+ if (valid)
+ {
+ if (max_date() < min_date())
+ {
+ if (emit_errors)
+ {
+ llwarns << "max_date should be greater or equal to min_date" << llendl;
+ }
+ valid = false;
+ }
+ }
+ return valid;
+}
diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h
index 9e600c036f..af245a9c3b 100644
--- a/indra/newview/llinventoryfilter.h
+++ b/indra/newview/llinventoryfilter.h
@@ -29,12 +29,13 @@
#include "llinventorytype.h"
#include "llpermissionsflags.h"
+#include "llfolderviewmodel.h"
class LLFolderViewItem;
class LLFolderViewFolder;
class LLInventoryItem;
-class LLInventoryFilter
+class LLInventoryFilter : public LLFolderViewFilter
{
public:
enum EFolderShow
@@ -44,14 +45,6 @@ public:
SHOW_NO_FOLDERS
};
- enum EFilterBehavior
- {
- 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 EFilterType {
FILTERTYPE_NONE = 0,
FILTERTYPE_OBJECT = 0x1 << 0, // normal default search-by-object-type
@@ -59,7 +52,7 @@ public:
FILTERTYPE_UUID = 0x1 << 2, // find the object with UUID and any links to it
FILTERTYPE_DATE = 0x1 << 3, // search by date range
FILTERTYPE_WEARABLE = 0x1 << 4, // search by wearable type
- FILTERTYPE_EMPTYFOLDERS = 0x1 << 5 // pass if folder is not a system folder to be hidden if empty
+ FILTERTYPE_EMPTYFOLDERS = 0x1 << 5 // pass if folder is not a system folder to be hidden if
};
enum EFilterLink
@@ -77,16 +70,94 @@ public:
SO_SYSTEM_FOLDERS_TO_TOP = 0x1 << 2 // Force system folders to be on top
};
- LLInventoryFilter(const std::string& name);
- virtual ~LLInventoryFilter();
+ struct FilterOps
+ {
+ struct DateRange : public LLInitParam::Block<DateRange>
+ {
+ Optional<time_t> min_date;
+ Optional<time_t> max_date;
+
+ DateRange()
+ : min_date("min_date", time_min()),
+ max_date("max_date", time_max())
+ {}
+
+ bool validateBlock(bool emit_errors = true) const;
+ };
+
+ struct Params : public LLInitParam::Block<Params>
+ {
+ Optional<U32> types;
+ Optional<U64> object_types,
+ wearable_types,
+ category_types;
+ Optional<EFilterLink> links;
+ Optional<LLUUID> uuid;
+ Optional<DateRange> date_range;
+ Optional<S32> hours_ago;
+ Optional<EFolderShow> show_folder_state;
+ Optional<PermissionMask> permissions;
+
+ Params()
+ : types("filter_types", FILTERTYPE_OBJECT),
+ object_types("object_types", 0xffffFFFFffffFFFFULL),
+ wearable_types("wearable_types", 0xffffFFFFffffFFFFULL),
+ category_types("category_types", 0xffffFFFFffffFFFFULL),
+ links("links", FILTERLINK_INCLUDE_LINKS),
+ uuid("uuid"),
+ date_range("date_range"),
+ hours_ago("hours_ago", 0),
+ show_folder_state("show_folder_state", SHOW_NON_EMPTY_FOLDERS),
+ permissions("permissions", PERM_NONE)
+ {}
+ };
+
+ FilterOps(const Params& = Params());
+
+ 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;
+ };
+
+ struct Params : public LLInitParam::Block<Params>
+ {
+ Optional<std::string> name;
+ Optional<FilterOps::Params> filter_ops;
+ Optional<std::string> substring;
+ Optional<U32> sort_order;
+ Optional<bool> since_logoff;
+
+ Params()
+ : name("name"),
+ filter_ops(""),
+ substring("substring"),
+ sort_order("sort_order"),
+ since_logoff("since_logoff")
+ {}
+ };
+
+ LLInventoryFilter(const Params& p = Params());
+ LLInventoryFilter(const LLInventoryFilter& other) { *this = other; }
+ virtual ~LLInventoryFilter() {}
// +-------------------------------------------------------------------+
// + Parameters
// +-------------------------------------------------------------------+
- void setFilterObjectTypes(U64 types);
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);
@@ -96,7 +167,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 setFilterPermissions(PermissionMask perms);
PermissionMask getFilterPermissions() const;
@@ -115,19 +186,17 @@ public:
// +-------------------------------------------------------------------+
// + Execution And Results
// +-------------------------------------------------------------------+
- BOOL check(const LLFolderViewItem* item);
+ bool check(const LLFolderViewModelItem* listener);
bool check(const LLInventoryItem* item);
- bool checkFolder(const LLFolderViewFolder* folder) const;
+ bool checkFolder(const LLFolderViewModelItem* listener) const;
bool checkFolder(const LLUUID& folder_id) const;
- BOOL checkAgainstFilterType(const LLFolderViewItem* item) const;
- bool checkAgainstFilterType(const LLInventoryItem* item) const;
- BOOL checkAgainstPermissions(const LLFolderViewItem* item) const;
- bool checkAgainstPermissions(const LLInventoryItem* item) const;
- BOOL checkAgainstFilterLinks(const LLFolderViewItem* item) const;
- bool checkAgainstClipboard(const LLUUID& object_id) const;
+
+ bool showAllResults() const;
+
std::string::size_type getStringMatchOffset() const;
+ std::string::size_type getStringMatchOffset(LLFolderViewItem* item) const;
// +-------------------------------------------------------------------+
// + Presentation
// +-------------------------------------------------------------------+
@@ -138,20 +207,19 @@ public:
U32 getSortOrder() const;
void setEmptyLookupMessage(const std::string& message);
- const std::string& getEmptyLookupMessage() const;
+ std::string getEmptyLookupMessage() const;
// +-------------------------------------------------------------------+
// + Status
// +-------------------------------------------------------------------+
- BOOL isActive() const;
- BOOL isModified() const;
- BOOL isModifiedAndClear();
- BOOL isSinceLogoff() const;
+ bool isActive() 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
@@ -163,8 +231,8 @@ public:
// +-------------------------------------------------------------------+
// + Default
// +-------------------------------------------------------------------+
- BOOL isDefault() const;
- BOOL isNotDefault() const;
+ bool isDefault() const;
+ bool isNotDefault() const;
void markDefault();
void resetDefault();
@@ -172,57 +240,44 @@ public:
// + Generation
// +-------------------------------------------------------------------+
S32 getCurrentGeneration() const;
- S32 getMinRequiredGeneration() const;
- S32 getMustPassGeneration() const;
+ S32 getFirstSuccessGeneration() const;
+ S32 getFirstRequiredGeneration() const;
+
// +-------------------------------------------------------------------+
// + Conversion
// +-------------------------------------------------------------------+
- void toLLSD(LLSD& data) const;
- void fromLLSD(LLSD& data);
+ void toParams(Params& params) const;
+ void fromParams(const Params& p);
+
+ LLInventoryFilter& operator =(const LLInventoryFilter& other);
private:
bool areDateLimitsSet();
-
- 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 checkAgainstFilterType(const class LLFolderViewModelItemInventory* listener) const;
+ bool checkAgainstFilterType(const LLInventoryItem* item) const;
+ bool checkAgainstPermissions(const class LLFolderViewModelItemInventory* listener) const;
+ bool checkAgainstPermissions(const LLInventoryItem* item) const;
+ bool checkAgainstFilterLinks(const class LLFolderViewModelItemInventory* listener) const;
+ bool checkAgainstClipboard(const LLUUID& object_id) const;
U32 mOrder;
- U32 mLastLogoff;
FilterOps mFilterOps;
FilterOps mDefaultFilterOps;
- std::string::size_type mSubStringMatchOffset;
std::string mFilterSubString;
std::string mFilterSubStringOrig;
const std::string mName;
- S32 mFilterGeneration;
- S32 mMustPassGeneration;
- S32 mMinRequiredGeneration;
+ S32 mCurrentGeneration;
+ S32 mFirstRequiredGeneration;
+ S32 mFirstSuccessGeneration;
S32 mNextFilterGeneration;
S32 mFilterCount;
- EFilterBehavior mFilterBehavior;
+ EFilterModified mFilterModified;
- BOOL mModified;
- BOOL mNeedTextRebuild;
std::string mFilterText;
std::string mEmptyLookupMessage;
};
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index ab5b082915..07f3dd8ffb 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -45,7 +45,7 @@
// newview includes
#include "llappearancemgr.h"
#include "llappviewer.h"
-//#include "llfirstuse.h"
+#include "llclipboard.h"
#include "llfloaterinventory.h"
#include "llfloatersidepanelcontainer.h"
#include "llfocusmgr.h"
@@ -74,8 +74,10 @@
#include "llsidepanelinventory.h"
#include "lltabcontainer.h"
#include "lltooldraganddrop.h"
+#include "lltrans.h"
#include "lluictrlfactory.h"
#include "llviewermessage.h"
+#include "llviewerfoldertype.h"
#include "llviewerobjectlist.h"
#include "llviewerregion.h"
#include "llviewerwindow.h"
@@ -948,7 +950,7 @@ void LLSaveFolderState::setApply(BOOL apply)
void LLSaveFolderState::doFolder(LLFolderViewFolder* folder)
{
LLMemType mt(LLMemType::MTYPE_INVENTORY_DO_FOLDER);
- LLInvFVBridge* bridge = (LLInvFVBridge*)folder->getListener();
+ LLInvFVBridge* bridge = (LLInvFVBridge*)folder->getViewModelItem();
if(!bridge) return;
if(mApply)
@@ -983,7 +985,7 @@ void LLSaveFolderState::doFolder(LLFolderViewFolder* folder)
void LLOpenFilteredFolders::doItem(LLFolderViewItem *item)
{
- if (item->getFiltered())
+ if (item->passedFilter())
{
item->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
}
@@ -991,12 +993,12 @@ void LLOpenFilteredFolders::doItem(LLFolderViewItem *item)
void LLOpenFilteredFolders::doFolder(LLFolderViewFolder* folder)
{
- if (folder->getFiltered() && folder->getParentFolder())
+ if (folder->LLFolderViewItem::passedFilter() && folder->getParentFolder())
{
folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
}
// if this folder didn't pass the filter, and none of its descendants did
- else if (!folder->getFiltered() && !folder->hasFilteredDescendants())
+ else if (!folder->getViewModelItem()->passedFilter() && !folder->getViewModelItem()->descendantsPassedFilter())
{
folder->setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_NO);
}
@@ -1004,7 +1006,7 @@ void LLOpenFilteredFolders::doFolder(LLFolderViewFolder* folder)
void LLSelectFirstFilteredItem::doItem(LLFolderViewItem *item)
{
- if (item->getFiltered() && !mItemSelected)
+ if (item->passedFilter() && !mItemSelected)
{
item->getRoot()->setSelection(item, FALSE, FALSE);
if (item->getParentFolder())
@@ -1017,7 +1019,7 @@ void LLSelectFirstFilteredItem::doItem(LLFolderViewItem *item)
void LLSelectFirstFilteredItem::doFolder(LLFolderViewFolder* folder)
{
- if (folder->getFiltered() && !mItemSelected)
+ if (folder->LLFolderViewItem::passedFilter() && !mItemSelected)
{
folder->getRoot()->setSelection(folder, FALSE, FALSE);
if (folder->getParentFolder())
@@ -1044,3 +1046,87 @@ void LLOpenFoldersWithSelection::doFolder(LLFolderViewFolder* folder)
}
}
+void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root, const std::string& action)
+{
+ if ("rename" == action)
+ {
+ root->startRenamingSelectedItem();
+ return;
+ }
+ if ("delete" == action)
+ {
+ LLSD args;
+ args["QUESTION"] = LLTrans::getString(root->getNumSelectedItems() > 1 ? "DeleteItems" : "DeleteItem");
+ LLNotificationsUtil::add("DeleteItems", args, LLSD(), boost::bind(&LLInventoryAction::onItemsRemovalConfirmation, _1, _2, root));
+ return;
+ }
+ if (("copy" == action) || ("cut" == action))
+ {
+ // Clear the clipboard before we start adding things on it
+ LLClipboard::instance().reset();
+ }
+
+ static const std::string change_folder_string = "change_folder_type_";
+ if (action.length() > change_folder_string.length() &&
+ (action.compare(0,change_folder_string.length(),"change_folder_type_") == 0))
+ {
+ LLFolderType::EType new_folder_type = LLViewerFolderType::lookupTypeFromXUIName(action.substr(change_folder_string.length()));
+ LLFolderViewModelItemInventory* inventory_item = static_cast<LLFolderViewModelItemInventory*>(root->getViewModelItem());
+ LLViewerInventoryCategory *cat = model->getCategory(inventory_item->getUUID());
+ if (!cat) return;
+ cat->changeType(new_folder_type);
+ return;
+ }
+
+
+ std::set<LLFolderViewItem*> selected_items = root->getSelectionList();
+
+ LLMultiPreview* multi_previewp = NULL;
+ LLMultiProperties* multi_propertiesp = NULL;
+
+ if (("task_open" == action || "open" == action) && selected_items.size() > 1)
+ {
+ multi_previewp = new LLMultiPreview();
+ gFloaterView->addChild(multi_previewp);
+
+ LLFloater::setFloaterHost(multi_previewp);
+
+ }
+ else if (("task_properties" == action || "properties" == action) && selected_items.size() > 1)
+ {
+ multi_propertiesp = new LLMultiProperties();
+ gFloaterView->addChild(multi_propertiesp);
+
+ LLFloater::setFloaterHost(multi_propertiesp);
+ }
+
+ std::set<LLFolderViewItem*>::iterator set_iter;
+
+ for (set_iter = selected_items.begin(); set_iter != selected_items.end(); ++set_iter)
+ {
+ LLFolderViewItem* folder_item = *set_iter;
+ if(!folder_item) continue;
+ LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getViewModelItem();
+ if(!bridge) continue;
+ bridge->performAction(model, action);
+ }
+
+ LLFloater::setFloaterHost(NULL);
+ if (multi_previewp)
+ {
+ multi_previewp->openFloater(LLSD());
+ }
+ else if (multi_propertiesp)
+ {
+ multi_propertiesp->openFloater(LLSD());
+ }
+}
+
+void LLInventoryAction::onItemsRemovalConfirmation( const LLSD& notification, const LLSD& response, LLFolderView* root )
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option == 0)
+ {
+ root->removeSelectedItems();
+ }
+}
diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h
index 5cf9c528b0..d8d3d9bbbb 100644
--- a/indra/newview/llinventoryfunctions.h
+++ b/indra/newview/llinventoryfunctions.h
@@ -418,21 +418,6 @@ public:
class LLFolderViewItem;
class LLFolderViewFolder;
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLFolderViewFunctor
-//
-// Simple abstract base class for applying a functor to folders and
-// items in a folder view hierarchy. This is suboptimal for algorithms
-// that only work folders or only work on items, but I'll worry about
-// that later when it's determined to be too slow.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLFolderViewFunctor
-{
-public:
- virtual ~LLFolderViewFunctor() {}
- virtual void doFolder(LLFolderViewFolder* folder) = 0;
- virtual void doItem(LLFolderViewItem* item) = 0;
-};
class LLInventoryState
{
@@ -442,49 +427,13 @@ public:
static LLUUID sWearNewClothingTransactionID; // wear all clothing in this transaction
};
-class LLSelectFirstFilteredItem : public LLFolderViewFunctor
+struct LLInventoryAction
{
-public:
- LLSelectFirstFilteredItem() : mItemSelected(FALSE) {}
- virtual ~LLSelectFirstFilteredItem() {}
- virtual void doFolder(LLFolderViewFolder* folder);
- virtual void doItem(LLFolderViewItem* item);
- BOOL wasItemSelected() { return mItemSelected; }
-protected:
- BOOL mItemSelected;
-};
+ static void doToSelected(class LLInventoryModel* model, class LLFolderView* root, const std::string& action);
-class LLOpenFilteredFolders : public LLFolderViewFunctor
-{
-public:
- LLOpenFilteredFolders() {}
- virtual ~LLOpenFilteredFolders() {}
- virtual void doFolder(LLFolderViewFolder* folder);
- virtual void doItem(LLFolderViewItem* item);
+ static void onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response, LLFolderView* root);
};
-class LLSaveFolderState : public LLFolderViewFunctor
-{
-public:
- LLSaveFolderState() : mApply(FALSE) {}
- virtual ~LLSaveFolderState() {}
- virtual void doFolder(LLFolderViewFolder* folder);
- virtual void doItem(LLFolderViewItem* item) {}
- void setApply(BOOL apply);
- void clearOpenFolders() { mOpenFolders.clear(); }
-protected:
- std::set<LLUUID> mOpenFolders;
- BOOL mApply;
-};
-
-class LLOpenFoldersWithSelection : public LLFolderViewFunctor
-{
-public:
- LLOpenFoldersWithSelection() {}
- virtual ~LLOpenFoldersWithSelection() {}
- virtual void doFolder(LLFolderViewFolder* folder);
- virtual void doItem(LLFolderViewItem* item);
-};
#endif // LL_LLINVENTORYFUNCTIONS_H
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 85ecb133d0..9b0d12b353 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -3201,68 +3201,7 @@ void LLInventoryModel::updateItemsOrder(LLInventoryModel::item_array_t& items, c
}
}
-//* @param[in] items vector of items in order to be saved.
-void LLInventoryModel::saveItemsOrder(const LLInventoryModel::item_array_t& items)
-{
- int sortField = 0;
-
- // current order is saved by setting incremental values (1, 2, 3, ...) for the sort field
- for (item_array_t::const_iterator i = items.begin(); i != items.end(); ++i)
- {
- LLViewerInventoryItem* item = *i;
-
- item->setSortField(++sortField);
- item->setComplete(TRUE);
- item->updateServer(FALSE);
-
- updateItem(item);
-
- // Tell the parent folder to refresh its sort order.
- addChangedMask(LLInventoryObserver::SORT, item->getParentUUID());
- }
-
- notifyObservers();
-}
-
-// See also LLInventorySort where landmarks in the Favorites folder are sorted.
-class LLViewerInventoryItemSort
-{
-public:
- bool operator()(const LLPointer<LLViewerInventoryItem>& a, const LLPointer<LLViewerInventoryItem>& b)
- {
- return a->getSortField() < b->getSortField();
- }
-};
-/**
- * Sorts passed items by LLViewerInventoryItem sort field.
- *
- * @param[in, out] items - array of items, not sorted.
- */
-static void rearrange_item_order_by_sort_field(LLInventoryModel::item_array_t& items)
-{
- static LLViewerInventoryItemSort sort_functor;
- std::sort(items.begin(), items.end(), sort_functor);
-}
-
-// * @param source_item_id - LLUUID of the source item to be moved into new position
-// * @param target_item_id - LLUUID of the target item before which source item should be placed.
-void LLInventoryModel::rearrangeFavoriteLandmarks(const LLUUID& source_item_id, const LLUUID& target_item_id)
-{
- LLInventoryModel::cat_array_t cats;
- LLInventoryModel::item_array_t items;
- LLIsType is_type(LLAssetType::AT_LANDMARK);
- LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
- gInventory.collectDescendentsIf(favorites_id, cats, items, LLInventoryModel::EXCLUDE_TRASH, is_type);
-
- // ensure items are sorted properly before changing order. EXT-3498
- rearrange_item_order_by_sort_field(items);
-
- // update order
- updateItemsOrder(items, source_item_id, target_item_id);
-
- saveItemsOrder(items);
-}
//----------------------------------------------------------------------------
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index 8382e875b4..3613bc4917 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -362,15 +362,6 @@ public:
// Returns end() of the vector if not found.
static LLInventoryModel::item_array_t::iterator findItemIterByUUID(LLInventoryModel::item_array_t& items, const LLUUID& id);
- // Saves current order of the passed items using inventory item sort field.
- // Resets 'items' sort fields and saves them on server.
- // Is used to save order for Favorites folder.
- void saveItemsOrder(const LLInventoryModel::item_array_t& items);
-
- // Rearranges Landmarks inside Favorites folder.
- // Moves source landmark before target one.
- void rearrangeFavoriteLandmarks(const LLUUID& source_item_id, const LLUUID& target_item_id);
-
//--------------------------------------------------------------------
// Creation
//--------------------------------------------------------------------
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 71dd963f28..0aa67cddca 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -38,11 +38,13 @@
#include "llfloaterreg.h"
#include "llfloatersidepanelcontainer.h"
#include "llfolderview.h"
+#include "llfolderviewitem.h"
#include "llimfloater.h"
#include "llimview.h"
#include "llinventorybridge.h"
#include "llinventoryfunctions.h"
#include "llinventorymodelbackgroundfetch.h"
+#include "llpreview.h"
#include "llsidepanelinventory.h"
#include "llviewerattachmenu.h"
#include "llviewerfoldertype.h"
@@ -55,7 +57,6 @@ const std::string LLInventoryPanel::RECENTITEMS_SORT_ORDER = std::string("Recent
const std::string LLInventoryPanel::INHERIT_SORT_ORDER = std::string("");
static const LLInventoryFVBridgeBuilder INVENTORY_BRIDGE_BUILDER;
-
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLInventoryPanelObserver
//
@@ -134,7 +135,6 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
mAllowMultiSelect(p.allow_multi_select),
mShowItemLinkOverlays(p.show_item_link_overlays),
mShowEmptyMessage(p.show_empty_message),
- mShowLoadStatus(p.show_load_status),
mViewsInitialized(false),
mInvFVBridgeBuilder(NULL)
{
@@ -183,10 +183,12 @@ void LLInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params)
LLAssetType::AT_CATEGORY,
LLInventoryType::IT_CATEGORY,
this,
+ &mInventoryViewModel,
NULL,
root_id);
mFolderRoot = createFolderView(new_listener, params.use_label_suffix());
+ addItemID(root_id, mFolderRoot);
}
void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
@@ -202,18 +204,16 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
mFolderRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
// Scroller
- {
- LLRect scroller_view_rect = getRect();
- scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
- LLScrollContainer::Params scroller_params(params.scroll());
- scroller_params.rect(scroller_view_rect);
- mScroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params);
- addChild(mScroller);
- mScroller->addChild(mFolderRoot);
- mFolderRoot->setScrollContainer(mScroller);
- mFolderRoot->setFollowsAll();
- mFolderRoot->addChild(mFolderRoot->mStatusTextBox);
- }
+ LLRect scroller_view_rect = getRect();
+ scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
+ LLScrollContainer::Params scroller_params(params.scroll());
+ scroller_params.rect(scroller_view_rect);
+ mScroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params);
+ addChild(mScroller);
+ mScroller->addChild(mFolderRoot);
+ mFolderRoot->setScrollContainer(mScroller);
+ mFolderRoot->setFollowsAll();
+ mFolderRoot->addChild(mFolderRoot->mStatusTextBox);
// Set up the callbacks from the inventory we're viewing, and then build everything.
mInventoryObserver = new LLInventoryPanelObserver(this);
@@ -258,13 +258,12 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
LLInventoryPanel::~LLInventoryPanel()
{
- if (mFolderRoot)
+ gIdleCallbacks.deleteFunction(idle, this);
+
+ U32 sort_order = getFolderViewModel()->getSorter().getSortOrder();
+ if (mSortOrderSetting != INHERIT_SORT_ORDER)
{
- U32 sort_order = mFolderRoot->getSortOrder();
- if (mSortOrderSetting != INHERIT_SORT_ORDER)
- {
- gSavedSettings.setU32(mSortOrderSetting, sort_order);
- }
+ gSavedSettings.setU32(mSortOrderSetting, sort_order);
}
gIdleCallbacks.deleteFunction(onIdle, this);
@@ -281,7 +280,7 @@ LLInventoryPanel::~LLInventoryPanel()
void LLInventoryPanel::draw()
{
// Select the desired item (in case it wasn't loaded when the selection was requested)
- mFolderRoot->updateSelection();
+ updateSelection();
// Nudge the filter if the clipboard state changed
if (mClipboardState != LLClipboard::instance().getGeneration())
@@ -293,22 +292,14 @@ void LLInventoryPanel::draw()
LLPanel::draw();
}
-LLInventoryFilter* LLInventoryPanel::getFilter()
+const LLInventoryFilter* LLInventoryPanel::getFilter() const
{
- if (mFolderRoot)
- {
- return mFolderRoot->getFilter();
- }
- return NULL;
+ return getFolderViewModel()->getFilter();
}
-const LLInventoryFilter* LLInventoryPanel::getFilter() const
+LLInventoryFilter* LLInventoryPanel::getFilter()
{
- if (mFolderRoot)
- {
- return mFolderRoot->getFilter();
- }
- return NULL;
+ return getFolderViewModel()->getFilter();
}
void LLInventoryPanel::setFilterTypes(U64 types, LLInventoryFilter::EFilterType filter_type)
@@ -321,12 +312,12 @@ void LLInventoryPanel::setFilterTypes(U64 types, LLInventoryFilter::EFilterType
U32 LLInventoryPanel::getFilterObjectTypes() const
{
- return mFolderRoot->getFilterObjectTypes();
+ return getFilter()->getFilterObjectTypes();
}
U32 LLInventoryPanel::getFilterPermMask() const
{
- return mFolderRoot->getFilterPermissions();
+ return getFilter()->getFilterPermissions();
}
@@ -347,16 +338,17 @@ void LLInventoryPanel::setFilterSubString(const std::string& string)
const std::string LLInventoryPanel::getFilterSubString()
{
- return mFolderRoot->getFilterSubString();
+ return getFilter()->getFilterSubString();
}
void LLInventoryPanel::setSortOrder(U32 order)
{
+ LLInventorySort sorter(order);
getFilter()->setSortOrder(order);
- if (getFilter()->isModified())
+ if (order != getFolderViewModel()->getSorter().getSortOrder())
{
- mFolderRoot->setSortOrder(order);
+ getFolderViewModel()->setSorter(LLInventorySort(order));
// try to keep selection onscreen, even if it wasn't to start with
mFolderRoot->scrollToShowSelection();
}
@@ -364,12 +356,7 @@ void LLInventoryPanel::setSortOrder(U32 order)
U32 LLInventoryPanel::getSortOrder() const
{
- return mFolderRoot->getSortOrder();
-}
-
-void LLInventoryPanel::requestSort()
-{
- mFolderRoot->requestSort();
+ return getFolderViewModel()->getSorter().getSortOrder();
}
void LLInventoryPanel::setSinceLogoff(BOOL sl)
@@ -418,7 +405,9 @@ void LLInventoryPanel::modelChanged(U32 mask)
{
const LLUUID& item_id = (*items_iter);
const LLInventoryObject* model_item = model->getObject(item_id);
- LLFolderViewItem* view_item = mFolderRoot->getItemByID(item_id);
+ LLFolderViewItem* view_item = getItemByID(item_id);
+ LLFolderViewModelItemInventory* viewmodel_item =
+ static_cast<LLFolderViewModelItemInventory*>(view_item ? view_item->getViewModelItem() : NULL);
// LLFolderViewFolder is derived from LLFolderViewItem so dynamic_cast from item
// to folder is the fast way to get a folder without searching through folders tree.
@@ -433,7 +422,7 @@ void LLInventoryPanel::modelChanged(U32 mask)
if (view_item)
{
// Request refresh on this item (also flags for filtering)
- LLInvFVBridge* bridge = (LLInvFVBridge*)view_item->getListener();
+ LLInvFVBridge* bridge = (LLInvFVBridge*)view_item->getViewModelItem();
if(bridge)
{ // Clear the display name first, so it gets properly re-built during refresh()
bridge->clearDisplayName();
@@ -452,8 +441,11 @@ void LLInventoryPanel::modelChanged(U32 mask)
if (model_item && view_item)
{
view_item->destroyView();
+ removeItemID(viewmodel_item->getUUID());
}
view_item = buildNewViews(item_id);
+ viewmodel_item =
+ static_cast<LLFolderViewModelItemInventory*>(view_item ? view_item->getViewModelItem() : NULL);
view_folder = dynamic_cast<LLFolderViewFolder *>(view_item);
}
@@ -510,23 +502,24 @@ void LLInventoryPanel::modelChanged(U32 mask)
else if (model_item && view_item)
{
// Don't process the item if it is the root
- if (view_item->getRoot() != view_item)
+ if (view_item->getParentFolder())
{
- LLFolderViewFolder* new_parent = (LLFolderViewFolder*)mFolderRoot->getItemByID(model_item->getParentUUID());
+ LLFolderViewFolder* new_parent = (LLFolderViewFolder*)getItemByID(model_item->getParentUUID());
// Item has been moved.
if (view_item->getParentFolder() != new_parent)
{
if (new_parent != NULL)
{
// Item is to be moved and we found its new parent in the panel's directory, so move the item's UI.
- view_item->getParentFolder()->extractItem(view_item);
- view_item->addToFolder(new_parent, mFolderRoot);
+ view_item->addToFolder(new_parent);
+ addItemID(viewmodel_item->getUUID(), view_item);
}
else
{
// Item is to be moved outside the panel's directory (e.g. moved to trash for a panel that
// doesn't include trash). Just remove the item's UI.
view_item->destroyView();
+ removeItemID(viewmodel_item->getUUID());
}
}
}
@@ -538,7 +531,9 @@ void LLInventoryPanel::modelChanged(U32 mask)
else if (!model_item && view_item)
{
// Remove the item's UI.
+ removeItemID(viewmodel_item->getUUID());
view_item->destroyView();
+ removeItemID(viewmodel_item->getUUID());
}
}
}
@@ -549,6 +544,11 @@ LLFolderView* LLInventoryPanel::getRootFolder()
return mFolderRoot;
}
+LLUUID LLInventoryPanel::getRootFolderID()
+{
+ return static_cast<LLFolderViewModelItemInventory*>(mFolderRoot->getViewModelItem())->getUUID();
+}
+
// static
void LLInventoryPanel::onIdle(void *userdata)
@@ -568,16 +568,37 @@ void LLInventoryPanel::onIdle(void *userdata)
}
}
-const LLUUID& LLInventoryPanel::getRootFolderID() const
+void LLInventoryPanel::idle(void* user_data)
{
- return mFolderRoot->getListener()->getUUID();
+ LLInventoryPanel* panel = (LLInventoryPanel*)user_data;
+ panel->mFolderRoot->update();
+ // while dragging, update selection rendering to reflect single/multi drag status
+ if (LLToolDragAndDrop::getInstance()->hasMouseCapture())
+ {
+ EAcceptance last_accept = LLToolDragAndDrop::getInstance()->getLastAccept();
+ if (last_accept == ACCEPT_YES_SINGLE || last_accept == ACCEPT_YES_COPY_SINGLE)
+ {
+ panel->mFolderRoot->setShowSingleSelection(TRUE);
+ }
+ else
+ {
+ panel->mFolderRoot->setShowSingleSelection(FALSE);
+ }
+ }
+ else
+ {
+ panel->mFolderRoot->setShowSingleSelection(FALSE);
+ }
}
+
void LLInventoryPanel::initializeViews()
{
if (!gInventory.isInventoryUsable()) return;
- rebuildViewsFor(getRootFolderID());
+ rebuildViewsFor(gInventory.getRootFolderID());
+
+ gIdleCallbacks.addFunction(idle, this);
mViewsInitialized = true;
@@ -587,14 +608,14 @@ void LLInventoryPanel::initializeViews()
if (gAgent.isFirstLogin())
{
// Auto open the user's library
- LLFolderViewFolder* lib_folder = mFolderRoot->getFolderByID(gInventory.getLibraryRootFolderID());
+ LLFolderViewFolder* lib_folder = getFolderByID(gInventory.getLibraryRootFolderID());
if (lib_folder)
{
lib_folder->setOpen(TRUE);
}
// Auto close the user's my inventory folder
- LLFolderViewFolder* my_inv_folder = mFolderRoot->getFolderByID(gInventory.getRootFolderID());
+ LLFolderViewFolder* my_inv_folder = getFolderByID(gInventory.getRootFolderID());
if (my_inv_folder)
{
my_inv_folder->setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_DOWN);
@@ -605,10 +626,11 @@ void LLInventoryPanel::initializeViews()
LLFolderViewItem* LLInventoryPanel::rebuildViewsFor(const LLUUID& id)
{
// Destroy the old view for this ID so we can rebuild it.
- LLFolderViewItem* old_view = mFolderRoot->getItemByID(id);
+ LLFolderViewItem* old_view = getItemByID(id);
if (old_view)
{
old_view->destroyView();
+ removeItemID(static_cast<LLFolderViewModelItemInventory*>(old_view->getViewModelItem())->getUUID());
}
return buildNewViews(id);
@@ -628,11 +650,12 @@ LLFolderView * LLInventoryPanel::createFolderView(LLInvFVBridge * bridge, bool u
p.rect = folder_rect;
p.parent_panel = this;
p.tool_tip = p.name;
- p.listener = bridge;
+ p.listener = bridge;
+ p.view_model = &mInventoryViewModel;
p.use_label_suffix = useLabelSuffix;
p.allow_multiselect = mAllowMultiSelect;
p.show_empty_message = mShowEmptyMessage;
- p.show_load_status = mShowLoadStatus;
+ p.show_item_link_overlays = mShowItemLinkOverlays;
return LLUICtrlFactory::create<LLFolderView>(p);
}
@@ -642,14 +665,6 @@ LLFolderViewFolder * LLInventoryPanel::createFolderViewFolder(LLInvFVBridge * br
LLFolderViewFolder::Params params;
params.name = bridge->getDisplayName();
- params.icon = bridge->getIcon();
- params.icon_open = bridge->getOpenIcon();
-
- if (mShowItemLinkOverlays) // if false, then links show up just like normal items
- {
- params.icon_overlay = LLUI::getUIImage("Inv_Link");
- }
-
params.root = mFolderRoot;
params.listener = bridge;
params.tool_tip = params.name;
@@ -662,14 +677,6 @@ LLFolderViewItem * LLInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge
LLFolderViewItem::Params params;
params.name = bridge->getDisplayName();
- params.icon = bridge->getIcon();
- params.icon_open = bridge->getOpenIcon();
-
- if (mShowItemLinkOverlays) // if false, then links show up just like normal items
- {
- params.icon_overlay = LLUI::getUIImage("Inv_Link");
- }
-
params.creation_date = bridge->getCreationDate();
params.root = mFolderRoot;
params.listener = bridge;
@@ -682,79 +689,69 @@ LLFolderViewItem * LLInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge
LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
{
LLInventoryObject const* objectp = gInventory.getObject(id);
- LLUUID root_id = mFolderRoot->getListener()->getUUID();
- LLFolderViewFolder* parent_folder = NULL;
- LLFolderViewItem* itemp = NULL;
- if (id == root_id)
- {
- parent_folder = mFolderRoot;
- }
- else if (objectp)
- {
- const LLUUID &parent_id = objectp->getParentUUID();
- parent_folder = (LLFolderViewFolder*)mFolderRoot->getItemByID(parent_id);
-
- if (parent_folder)
+ if (!objectp) return NULL;
+
+ LLFolderViewItem* folder_view_item = getItemByID(id);
+
+ const LLUUID &parent_id = objectp->getParentUUID();
+ LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)getItemByID(parent_id);
+
+ if (!folder_view_item && parent_folder)
+ {
+ if (objectp->getType() <= LLAssetType::AT_NONE ||
+ objectp->getType() >= LLAssetType::AT_COUNT)
{
- if (objectp->getType() <= LLAssetType::AT_NONE ||
- objectp->getType() >= LLAssetType::AT_COUNT)
- {
- llwarns << "LLInventoryPanel::buildNewViews called with invalid objectp->mType : "
- << ((S32) objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID()
- << llendl;
- return NULL;
- }
+ llwarns << "LLInventoryPanel::buildNewViews called with invalid objectp->mType : "
+ << ((S32) objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID()
+ << llendl;
+ return NULL;
+ }
- if ((objectp->getType() == LLAssetType::AT_CATEGORY) &&
- (objectp->getActualType() != LLAssetType::AT_LINK_FOLDER))
+ if ((objectp->getType() == LLAssetType::AT_CATEGORY) &&
+ (objectp->getActualType() != LLAssetType::AT_LINK_FOLDER))
+ {
+ LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(objectp->getType(),
+ objectp->getType(),
+ LLInventoryType::IT_CATEGORY,
+ this,
+ &mInventoryViewModel,
+ mFolderRoot,
+ objectp->getUUID());
+ if (new_listener)
{
- LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(objectp->getType(),
- objectp->getType(),
- LLInventoryType::IT_CATEGORY,
- this,
- mFolderRoot,
- objectp->getUUID());
- if (new_listener)
- {
- LLFolderViewFolder* folderp = createFolderViewFolder(new_listener);
- if (folderp)
- {
- folderp->setItemSortOrder(mFolderRoot->getSortOrder());
- }
- itemp = folderp;
- }
+ folder_view_item = createFolderViewFolder(new_listener);
}
- else
- {
- // Build new view for item.
- LLInventoryItem* item = (LLInventoryItem*)objectp;
- LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(item->getType(),
- item->getActualType(),
- item->getInventoryType(),
- this,
- mFolderRoot,
- item->getUUID(),
- item->getFlags());
+ }
+ else
+ {
+ // Build new view for item.
+ LLInventoryItem* item = (LLInventoryItem*)objectp;
+ LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(item->getType(),
+ item->getActualType(),
+ item->getInventoryType(),
+ this,
+ &mInventoryViewModel,
+ mFolderRoot,
+ item->getUUID(),
+ item->getFlags());
- if (new_listener)
- {
- itemp = createFolderViewItem(new_listener);
- }
+ if (new_listener)
+ {
+ folder_view_item = createFolderViewItem(new_listener);
}
+ }
- if (itemp)
- {
- itemp->addToFolder(parent_folder, mFolderRoot);
- }
- }
+ if (folder_view_item)
+ {
+ folder_view_item->addToFolder(parent_folder);
+ addItemID(id, folder_view_item);
+ }
}
// If this is a folder, add the children of the folder and recursively add any
// child folders.
- if (id.isNull()
- || (objectp
- && objectp->getType() == LLAssetType::AT_CATEGORY))
+ if (folder_view_item && objectp->getType() == LLAssetType::AT_CATEGORY)
{
LLViewerInventoryCategory::cat_array_t* categories;
LLViewerInventoryItem::item_array_t* items;
@@ -771,7 +768,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
}
}
- if(items && parent_folder)
+ if(items)
{
for (LLViewerInventoryItem::item_array_t::const_iterator item_iter = items->begin();
item_iter != items->end();
@@ -784,7 +781,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
mInventory->unlockDirectDescendentArrays(id);
}
- return itemp;
+ return folder_view_item;
}
// bit of a hack to make sure the inventory is open.
@@ -795,8 +792,8 @@ void LLInventoryPanel::openStartFolderOrMyInventory()
{
LLFolderViewFolder *fchild = dynamic_cast<LLFolderViewFolder*>(child);
if (fchild
- && fchild->getListener()
- && fchild->getListener()->getUUID() == gInventory.getRootFolderID())
+ && fchild->getViewModelItem()
+ && fchild->getViewModelItem()->getName() == "My Inventory")
{
fchild->setOpen(TRUE);
break;
@@ -813,7 +810,7 @@ void LLInventoryPanel::openSelected()
{
LLFolderViewItem* folder_item = mFolderRoot->getCurSelectedItem();
if(!folder_item) return;
- LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getListener();
+ LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getViewModelItem();
if(!bridge) return;
bridge->openItem();
}
@@ -917,7 +914,7 @@ void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_foc
{
return;
}
- mFolderRoot->setSelectionByID(obj_id, take_keyboard_focus);
+ setSelectionByID(obj_id, take_keyboard_focus);
}
void LLInventoryPanel::setSelectCallback(const boost::function<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb)
@@ -930,7 +927,7 @@ void LLInventoryPanel::setSelectCallback(const boost::function<void (const std::
void LLInventoryPanel::clearSelection()
{
- mFolderRoot->clearSelection();
+ mSelectThisID.setNull();
}
void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& items, BOOL user_action)
@@ -939,7 +936,7 @@ void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& it
mCompletionObserver->reset();
for (std::deque<LLFolderViewItem*>::const_iterator it = items.begin(); it != items.end(); ++it)
{
- LLUUID id = (*it)->getListener()->getUUID();
+ LLUUID id = static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID();
LLViewerInventoryItem* inv_item = mInventory->getItem(id);
if (inv_item && !inv_item->isFinished())
@@ -959,19 +956,14 @@ void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& it
}
}
-void LLInventoryPanel::doToSelected(const LLSD& userdata)
-{
- mFolderRoot->doToSelected(&gInventory, userdata);
-}
-
void LLInventoryPanel::doCreate(const LLSD& userdata)
{
- menu_create_inventory_item(mFolderRoot, LLFolderBridge::sSelf.get(), userdata);
+ menu_create_inventory_item(this, LLFolderBridge::sSelf.get(), userdata);
}
bool LLInventoryPanel::beginIMSession()
{
- std::set<LLUUID> selected_items = mFolderRoot->getSelectionList();
+ std::set<LLFolderViewItem*> selected_items = mFolderRoot->getSelectionList();
std::string name;
static int session_num = 1;
@@ -979,20 +971,19 @@ bool LLInventoryPanel::beginIMSession()
LLDynamicArray<LLUUID> members;
EInstantMessage type = IM_SESSION_CONFERENCE_START;
- std::set<LLUUID>::const_iterator iter;
+ std::set<LLFolderViewItem*>::const_iterator iter;
for (iter = selected_items.begin(); iter != selected_items.end(); iter++)
{
- LLUUID item = *iter;
- LLFolderViewItem* folder_item = mFolderRoot->getItemByID(item);
+ LLFolderViewItem* folder_item = (*iter);
if(folder_item)
{
- LLFolderViewEventListener* fve_listener = folder_item->getListener();
+ LLFolderViewModelItemInventory* fve_listener = static_cast<LLFolderViewModelItemInventory*>(folder_item->getViewModelItem());
if (fve_listener && (fve_listener->getInventoryType() == LLInventoryType::IT_CATEGORY))
{
- LLFolderBridge* bridge = (LLFolderBridge*)folder_item->getListener();
+ LLFolderBridge* bridge = (LLFolderBridge*)folder_item->getViewModelItem();
if(!bridge) return true;
LLViewerInventoryCategory* cat = bridge->getCategory();
if(!cat) return true;
@@ -1026,9 +1017,7 @@ bool LLInventoryPanel::beginIMSession()
}
else
{
- LLFolderViewItem* folder_item = mFolderRoot->getItemByID(item);
- if(!folder_item) return true;
- LLInvFVBridge* listenerp = (LLInvFVBridge*)folder_item->getListener();
+ LLInvFVBridge* listenerp = (LLInvFVBridge*)folder_item->getViewModelItem();
if (listenerp->getInventoryType() == LLInventoryType::IT_CALLINGCARD)
{
@@ -1069,13 +1058,13 @@ bool LLInventoryPanel::beginIMSession()
bool LLInventoryPanel::attachObject(const LLSD& userdata)
{
// Copy selected item UUIDs to a vector.
- std::set<LLUUID> selected_items = mFolderRoot->getSelectionList();
+ std::set<LLFolderViewItem*> selected_items = mFolderRoot->getSelectionList();
uuid_vec_t items;
- for (std::set<LLUUID>::const_iterator set_iter = selected_items.begin();
+ for (std::set<LLFolderViewItem*>::const_iterator set_iter = selected_items.begin();
set_iter != selected_items.end();
++set_iter)
{
- items.push_back(*set_iter);
+ items.push_back(static_cast<LLFolderViewModelItemInventory*>((*set_iter)->getViewModelItem())->getUUID());
}
// Attach selected items.
@@ -1222,6 +1211,87 @@ BOOL LLInventoryPanel::getIsHiddenFolderType(LLFolderType::EType folder_type) co
return !(getFilter()->getFilterCategoryTypes() & (1ULL << folder_type));
}
+void LLInventoryPanel::addItemID( const LLUUID& id, LLFolderViewItem* itemp )
+{
+ mItemMap[id] = itemp;
+}
+
+void LLInventoryPanel::removeItemID(const LLUUID& id)
+{
+ LLInventoryModel::cat_array_t categories;
+ LLInventoryModel::item_array_t items;
+ gInventory.collectDescendents(id, categories, items, TRUE);
+
+ mItemMap.erase(id);
+
+ for (LLInventoryModel::cat_array_t::iterator it = categories.begin(), end_it = categories.end();
+ it != end_it;
+ ++it)
+ {
+ mItemMap.erase((*it)->getUUID());
+ }
+
+ for (LLInventoryModel::item_array_t::iterator it = items.begin(), end_it = items.end();
+ it != end_it;
+ ++it)
+ {
+ mItemMap.erase((*it)->getUUID());
+ }
+}
+
+LLFastTimer::DeclareTimer FTM_GET_ITEM_BY_ID("Get FolderViewItem by ID");
+LLFolderViewItem* LLInventoryPanel::getItemByID(const LLUUID& id)
+{
+ LLFastTimer _(FTM_GET_ITEM_BY_ID);
+
+ std::map<LLUUID, LLFolderViewItem*>::iterator map_it;
+ map_it = mItemMap.find(id);
+ if (map_it != mItemMap.end())
+ {
+ return map_it->second;
+ }
+
+ return NULL;
+}
+
+LLFolderViewFolder* LLInventoryPanel::getFolderByID(const LLUUID& id)
+{
+ LLFolderViewItem* item = getItemByID(id);
+ return dynamic_cast<LLFolderViewFolder*>(item);
+}
+
+
+void LLInventoryPanel::setSelectionByID( const LLUUID& obj_id, BOOL take_keyboard_focus )
+{
+ LLFolderViewItem* itemp = getItemByID(obj_id);
+ if(itemp && itemp->getViewModelItem())
+ {
+ itemp->arrangeAndSet(TRUE, take_keyboard_focus);
+ mSelectThisID.setNull();
+ return;
+ }
+ else
+ {
+ // save the desired item to be selected later (if/when ready)
+ mSelectThisID = obj_id;
+ }
+}
+
+void LLInventoryPanel::updateSelection()
+{
+ if (mSelectThisID.notNull())
+ {
+ setSelectionByID(mSelectThisID, false);
+ }
+}
+
+void LLInventoryPanel::doToSelected(const LLSD& userdata)
+{
+ LLInventoryAction::doToSelected(mInventory, mFolderRoot, userdata.asString());
+
+ return;
+}
+
/************************************************************************/
/* Recent Inventory Panel related class */
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 6db59afb9b..465ccdd582 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -30,6 +30,8 @@
#include "llassetstorage.h"
#include "lldarray.h"
+#include "llfolderviewitem.h"
+#include "llfolderviewmodelinventory.h"
#include "llfloater.h"
#include "llinventory.h"
#include "llinventoryfilter.h"
@@ -38,22 +40,10 @@
#include "lluictrlfactory.h"
#include <set>
-class LLFolderView;
-class LLFolderViewFolder;
-class LLFolderViewItem;
-class LLInventoryFilter;
-class LLInventoryModel;
class LLInvFVBridge;
class LLInventoryFVBridgeBuilder;
-class LLMenuBarGL;
-class LLCheckBoxCtrl;
-class LLSpinCtrl;
-class LLTextBox;
-class LLIconCtrl;
-class LLSaveFolderState;
-class LLFilterEditor;
-class LLTabContainer;
class LLInvPanelComplObserver;
+class LLFolderViewModelInventory;
class LLInventoryPanel : public LLPanel
{
@@ -85,7 +75,6 @@ public:
Optional<std::string> start_folder;
Optional<bool> use_label_suffix;
Optional<bool> show_empty_message;
- Optional<bool> show_load_status;
Optional<LLScrollContainer::Params> scroll;
Optional<bool> accepts_drag_and_drop;
@@ -98,7 +87,6 @@ public:
start_folder("start_folder"),
use_label_suffix("use_label_suffix", true),
show_empty_message("show_empty_message", true),
- show_load_status("show_load_status"),
scroll("scroll"),
accepts_drag_and_drop("accepts_drag_and_drop")
{}
@@ -156,6 +144,7 @@ public:
// This method is called when something has changed about the inventory.
void modelChanged(U32 mask);
LLFolderView* getRootFolder();
+ LLUUID getRootFolderID();
LLScrollContainer* getScrollableContainer() { return mScroller; }
void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);
@@ -167,7 +156,8 @@ public:
void doCreate(const LLSD& userdata);
bool beginIMSession();
bool attachObject(const LLSD& userdata);
-
+ static void idle(void* user_data);
+
// DEBUG ONLY:
static void dumpSelectionInformation(void* user_data);
@@ -182,10 +172,21 @@ public:
static void openInventoryPanelAndSetSelection(BOOL auto_open, const LLUUID& obj_id);
+ void addItemID(const LLUUID& id, LLFolderViewItem* itemp);
+ void removeItemID(const LLUUID& id);
+ LLFolderViewItem* getItemByID(const LLUUID& id);
+ LLFolderViewFolder* getFolderByID(const LLUUID& id);
+ void setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus);
+ void updateSelection();
+
+ LLFolderViewModelInventory* getFolderViewModel();
+ const LLFolderViewModelInventory* getFolderViewModel() const;
+
protected:
void openStartFolderOrMyInventory(); // open the first level of inventory
void onItemsCompletion(); // called when selected items are complete
+ LLUUID mSelectThisID;
LLInventoryModel* mInventory;
LLInventoryObserver* mInventoryObserver;
LLInvPanelComplObserver* mCompletionObserver;
@@ -193,11 +194,13 @@ protected:
BOOL mAllowMultiSelect;
BOOL mShowItemLinkOverlays; // Shows link graphic over inventory item icons
BOOL mShowEmptyMessage;
- BOOL mShowLoadStatus;
LLFolderView* mFolderRoot;
LLScrollContainer* mScroller;
+ LLFolderViewModelInventory mInventoryViewModel;
+
+ std::map<LLUUID, LLFolderViewItem*> mItemMap;
/**
* Pointer to LLInventoryFVBridgeBuilder.
*
@@ -218,7 +221,6 @@ public:
void setSortOrder(U32 order);
U32 getSortOrder() const;
- void requestSort();
private:
std::string mSortOrderSetting;
@@ -231,8 +233,7 @@ public:
void addHideFolderType(LLFolderType::EType folder_type);
public:
- BOOL getIsViewsInitialized() const { return mViewsInitialized; }
- const LLUUID& getRootFolderID() const;
+ BOOL getIsViewsInitialized() const { return mViewsInitialized; }
protected:
// Builds the UI. Call this once the inventory is usable.
void initializeViews();
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index 68a3b6d1cd..faef923338 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -102,7 +102,7 @@ void LLCheckFolderState::doFolder(LLFolderViewFolder* folder)
// Counting only folders that pass the filter.
// The listener check allow us to avoid counting the folder view
// object itself because it has no listener assigned.
- if (folder->hasFilteredDescendants() && folder->getListener())
+ if (folder->getViewModelItem()->descendantsPassedFilter())
{
if (folder->isOpen())
{
@@ -138,7 +138,7 @@ private:
// virtual
void LLOpenFolderByID::doFolder(LLFolderViewFolder* folder)
{
- if (folder->getListener() && folder->getListener()->getUUID() == mFolderID)
+ if (folder->getViewModelItem() && static_cast<LLFolderViewModelItemInventory*>(folder->getViewModelItem())->getUUID() == mFolderID)
{
if (!folder->isOpen())
{
@@ -281,28 +281,21 @@ void LLLandmarksPanel::onShowOnMap()
//virtual
void LLLandmarksPanel::onShowProfile()
{
- LLFolderViewItem* cur_item = getCurSelectedItem();
+ LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem();
if(!cur_item)
return;
- cur_item->getListener()->performAction(mCurrentSelectedList->getModel(),"about");
+ cur_item->performAction(mCurrentSelectedList->getModel(),"about");
}
// virtual
void LLLandmarksPanel::onTeleport()
{
- LLFolderViewItem* current_item = getCurSelectedItem();
- if (!current_item)
- {
- llwarns << "There are no selected list. No actions are performed." << llendl;
- return;
- }
-
- LLFolderViewEventListener* listenerp = current_item->getListener();
- if (listenerp && listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK)
+ LLFolderViewModelItemInventory* view_model_item = getCurSelectedViewModelItem();
+ if (view_model_item && view_model_item->getInventoryType() == LLInventoryType::IT_LANDMARK)
{
- listenerp->openItem();
+ view_model_item->openItem();
}
}
@@ -360,7 +353,7 @@ void LLLandmarksPanel::onSelectorButtonClicked()
LLFolderViewItem* cur_item = mFavoritesInventoryPanel->getRootFolder()->getCurSelectedItem();
if (!cur_item) return;
- LLFolderViewEventListener* listenerp = cur_item->getListener();
+ LLFolderViewModelItemInventory* listenerp = static_cast<LLFolderViewModelItemInventory*>(cur_item->getViewModelItem());
if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK)
{
LLSD key;
@@ -376,7 +369,7 @@ void LLLandmarksPanel::updateShowFolderState()
if (!mLandmarksInventoryPanel->getFilter())
return;
- bool show_all_folders = mLandmarksInventoryPanel->getRootFolder()->getFilterSubString().empty();
+ bool show_all_folders = mLandmarksInventoryPanel->getFilterSubString().empty();
if (show_all_folders)
{
show_all_folders = category_has_descendents(mLandmarksInventoryPanel);
@@ -417,8 +410,9 @@ void LLLandmarksPanel::setItemSelected(const LLUUID& obj_id, BOOL take_keyboard_
bool LLLandmarksPanel::isLandmarkSelected() const
{
- LLFolderViewItem* current_item = getCurSelectedItem();
- if(current_item && current_item->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK)
+ LLFolderViewModelItemInventory* current_item = getCurSelectedViewModelItem();
+
+ if(current_item && current_item->getInventoryType() == LLInventoryType::IT_LANDMARK)
{
return true;
}
@@ -440,10 +434,10 @@ bool LLLandmarksPanel::isReceivedFolderSelected() const
void LLLandmarksPanel::doActionOnCurSelectedLandmark(LLLandmarkList::loaded_callback_t cb)
{
- LLFolderViewItem* cur_item = getCurSelectedItem();
- if(cur_item && cur_item->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK)
+ LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem();
+ if(cur_item && cur_item->getInventoryType() == LLInventoryType::IT_LANDMARK)
{
- LLLandmark* landmark = LLLandmarkActions::getLandmark(cur_item->getListener()->getUUID(), cb);
+ LLLandmark* landmark = LLLandmarkActions::getLandmark(cur_item->getUUID(), cb);
if (landmark)
{
cb(landmark);
@@ -456,6 +450,17 @@ LLFolderViewItem* LLLandmarksPanel::getCurSelectedItem() const
return mCurrentSelectedList ? mCurrentSelectedList->getRootFolder()->getCurSelectedItem() : NULL;
}
+LLFolderViewModelItemInventory* LLLandmarksPanel::getCurSelectedViewModelItem() const
+{
+ LLFolderViewItem* cur_item = getCurSelectedItem();
+ if (cur_item)
+ {
+ return static_cast<LLFolderViewModelItemInventory*>(cur_item->getViewModelItem());
+ }
+ return NULL;
+}
+
+
LLFolderViewItem* LLLandmarksPanel::selectItemInAccordionTab(LLPlacesInventoryPanel* inventory_list,
const std::string& tab_name,
const LLUUID& obj_id,
@@ -466,7 +471,7 @@ LLFolderViewItem* LLLandmarksPanel::selectItemInAccordionTab(LLPlacesInventoryPa
LLFolderView* root = inventory_list->getRootFolder();
- LLFolderViewItem* item = root->getItemByID(obj_id);
+ LLFolderViewItem* item = inventory_list->getItemByID(obj_id);
if (!item)
return NULL;
@@ -508,12 +513,12 @@ void LLLandmarksPanel::processParcelInfo(const LLParcelData& parcel_data)
// We have to make request to sever to get parcel_id and snaption_id.
if(isLandmarkSelected())
{
- LLFolderViewItem* cur_item = getCurSelectedItem();
+ LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem();
if (!cur_item) return;
- LLUUID id = cur_item->getListener()->getUUID();
+ LLUUID id = cur_item->getUUID();
LLInventoryItem* inv_item = mCurrentSelectedList->getModel()->getItem(id);
doActionOnCurSelectedLandmark(boost::bind(
- &LLLandmarksPanel::doProcessParcelInfo, this, _1, cur_item, inv_item, parcel_data));
+ &LLLandmarksPanel::doProcessParcelInfo, this, _1, getCurSelectedItem(), inv_item, parcel_data));
}
}
@@ -646,7 +651,7 @@ void LLLandmarksPanel::onAccordionExpandedCollapsed(const LLSD& param, LLPlacesI
// Start background fetch, mostly for My Inventory and Library
if (expanded)
{
- const LLUUID &cat_id = inventory_list->getRootFolderID();
+ const LLUUID &cat_id = mCurrentSelectedList->getRootFolderID();
// Just because the category itself has been fetched, doesn't mean its child folders have.
/*
if (!gInventory.isCategoryComplete(cat_id))
@@ -665,20 +670,20 @@ void LLLandmarksPanel::deselectOtherThan(const LLPlacesInventoryPanel* inventory
{
if (inventory_list != mFavoritesInventoryPanel)
{
- mFavoritesInventoryPanel->getRootFolder()->clearSelection();
+ mFavoritesInventoryPanel->clearSelection();
}
if (inventory_list != mLandmarksInventoryPanel)
{
- mLandmarksInventoryPanel->getRootFolder()->clearSelection();
+ mLandmarksInventoryPanel->clearSelection();
}
if (inventory_list != mMyInventoryPanel)
{
- mMyInventoryPanel->getRootFolder()->clearSelection();
+ mMyInventoryPanel->clearSelection();
}
if (inventory_list != mLibraryInventoryPanel)
{
- mLibraryInventoryPanel->getRootFolder()->clearSelection();
+ mLibraryInventoryPanel->clearSelection();
}
}
@@ -731,14 +736,9 @@ void LLLandmarksPanel::onActionsButtonClick()
{
LLToggleableMenu* menu = mGearFolderMenu;
- LLFolderViewItem* cur_item = NULL;
if(mCurrentSelectedList)
{
- cur_item = mCurrentSelectedList->getRootFolder()->getCurSelectedItem();
- if(!cur_item)
- return;
-
- LLFolderViewEventListener* listenerp = cur_item->getListener();
+ LLFolderViewModelItemInventory* listenerp = getCurSelectedViewModelItem();
if(!listenerp)
return;
@@ -776,6 +776,9 @@ void LLLandmarksPanel::onTrashButtonClick() const
void LLLandmarksPanel::onAddAction(const LLSD& userdata) const
{
+ LLFolderViewModelItemInventory* view_model = getCurSelectedViewModelItem();
+ LLFolderViewItem* item = getCurSelectedItem();
+
std::string command_name = userdata.asString();
if("add_landmark" == command_name)
{
@@ -791,24 +794,24 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const
}
else if ("category" == command_name)
{
- LLFolderViewItem* item = getCurSelectedItem();
if (item && mCurrentSelectedList == mLandmarksInventoryPanel)
{
- LLFolderViewEventListener* folder_bridge = NULL;
- if (item-> getListener()->getInventoryType()
+ LLFolderViewModelItem* folder_bridge = NULL;
+
+ if (view_model->getInventoryType()
== LLInventoryType::IT_LANDMARK)
{
// for a landmark get parent folder bridge
- folder_bridge = item->getParentFolder()->getListener();
+ folder_bridge = item->getParentFolder()->getViewModelItem();
}
- else if (item-> getListener()->getInventoryType()
+ else if (view_model->getInventoryType()
== LLInventoryType::IT_CATEGORY)
{
// for a folder get its own bridge
- folder_bridge = item->getListener();
+ folder_bridge = view_model;
}
- menu_create_inventory_item(mCurrentSelectedList->getRootFolder(),
+ menu_create_inventory_item(mCurrentSelectedList,
dynamic_cast<LLFolderBridge*> (folder_bridge), LLSD(
"category"), gInventory.findCategoryUUIDForType(
LLFolderType::FT_LANDMARK));
@@ -816,7 +819,7 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const
else
{
//in case My Landmarks tab is completely empty (thus cannot be determined as being selected)
- menu_create_inventory_item(mLandmarksInventoryPanel->getRootFolder(), NULL, LLSD("category"),
+ menu_create_inventory_item(mLandmarksInventoryPanel, NULL, LLSD("category"),
gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK));
if (mMyLandmarksAccordionTab)
@@ -834,9 +837,9 @@ void LLLandmarksPanel::onClipboardAction(const LLSD& userdata) const
std::string command_name = userdata.asString();
if("copy_slurl" == command_name)
{
- LLFolderViewItem* cur_item = getCurSelectedItem();
+ LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem();
if(cur_item)
- LLLandmarkActions::copySLURLtoClipboard(cur_item->getListener()->getUUID());
+ LLLandmarkActions::copySLURLtoClipboard(cur_item->getUUID());
}
else if ( "paste" == command_name)
{
@@ -848,7 +851,7 @@ void LLLandmarksPanel::onClipboardAction(const LLSD& userdata) const
}
else
{
- mCurrentSelectedList->getRootFolder()->doToSelected(mCurrentSelectedList->getModel(),command_name);
+ mCurrentSelectedList->doToSelected(command_name);
}
}
@@ -893,7 +896,7 @@ void LLLandmarksPanel::onFoldingAction(const LLSD& userdata)
{
if(mCurrentSelectedList)
{
- mCurrentSelectedList->getRootFolder()->doToSelected(&gInventory, userdata);
+ mCurrentSelectedList->doToSelected(userdata);
}
}
}
@@ -977,18 +980,13 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
{
if (!root_folder_view) return false;
- std::set<LLUUID> selected_uuids = root_folder_view->getSelectionList();
+ std::set<LLFolderViewItem*> selected_uuids = root_folder_view->getSelectionList();
// Allow to execute the command only if it can be applied to all selected items.
- for (std::set<LLUUID>::const_iterator iter = selected_uuids.begin(); iter != selected_uuids.end(); ++iter)
+ for (std::set<LLFolderViewItem*>::const_iterator iter = selected_uuids.begin(); iter != selected_uuids.end(); ++iter)
{
- LLFolderViewItem* item = root_folder_view->getItemByID(*iter);
+ LLFolderViewItem* item = *iter;
- // If no item is found it might be a folder id.
- if (!item)
- {
- item = root_folder_view->getFolderByID(*iter);
- }
if (!item) return false;
if (!canItemBeModified(command_name, item)) return false;
@@ -1012,10 +1010,10 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
if ("show_on_map" == command_name)
{
- LLFolderViewItem* cur_item = root_folder_view->getCurSelectedItem();
+ LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem();
if (!cur_item) return false;
- LLViewerInventoryItem* inv_item = cur_item->getInventoryItem();
+ LLViewerInventoryItem* inv_item = dynamic_cast<LLViewerInventoryItem*>(cur_item->getInventoryObject());
if (!inv_item) return false;
LLUUID asset_uuid = inv_item->getAssetUUID();
@@ -1049,7 +1047,7 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
{
if (mCurrentSelectedList)
{
- std::set<LLUUID> selection = mCurrentSelectedList->getRootFolder()->getSelectionList();
+ std::set<LLFolderViewItem*> selection = mCurrentSelectedList->getRootFolder()->getSelectionList();
if (!selection.empty())
{
return ( 1 == selection.size() && !LLAgentPicksInfo::getInstance()->isPickLimitReached() );
@@ -1105,27 +1103,23 @@ void LLLandmarksPanel::onMenuVisibilityChange(LLUICtrl* ctrl, const LLSD& param)
{
const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
- std::set<LLUUID> selected_uuids = root_folder_view->getSelectionList();
+ std::set<LLFolderViewItem*> selected_items = root_folder_view->getSelectionList();
// Iterate through selected items to find out if any of these items are in Trash
// or all the items are in Trash category.
- for (std::set<LLUUID>::const_iterator iter = selected_uuids.begin(); iter != selected_uuids.end(); ++iter)
+ for (std::set<LLFolderViewItem*>::const_iterator iter = selected_items.begin(); iter != selected_items.end(); ++iter)
{
- LLFolderViewItem* item = root_folder_view->getItemByID(*iter);
+ LLFolderViewItem* item = *iter;
// If no item is found it might be a folder id.
- if (!item)
- {
- item = root_folder_view->getFolderByID(*iter);
- }
if (!item) continue;
- LLFolderViewEventListener* listenerp = item->getListener();
+ LLFolderViewModelItemInventory* listenerp = static_cast<LLFolderViewModelItemInventory*>(item->getViewModelItem());
if(!listenerp) continue;
// Trash category itself should not be included because it can't be
// actually restored from trash.
- are_all_items_in_trash &= listenerp->isItemInTrash() && *iter != trash_id;
+ are_all_items_in_trash &= listenerp->isItemInTrash() && listenerp->getUUID() != trash_id;
// If there are any selected items in Trash including the Trash category itself
// we show "Restore Item" in context menu and hide other irrelevant items.
@@ -1164,7 +1158,7 @@ bool LLLandmarksPanel::canItemBeModified(const std::string& command_name, LLFold
bool can_be_modified = false;
// landmarks can be modified in any other accordion...
- if (item->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK)
+ if (static_cast<LLFolderViewModelItemInventory*>(item->getViewModelItem())->getInventoryType() == LLInventoryType::IT_LANDMARK)
{
can_be_modified = true;
@@ -1202,7 +1196,7 @@ bool LLLandmarksPanel::canItemBeModified(const std::string& command_name, LLFold
if (can_be_modified)
{
- LLFolderViewEventListener* listenerp = item->getListener();
+ LLFolderViewModelItemInventory* listenerp = static_cast<LLFolderViewModelItemInventory*>(item->getViewModelItem());
if ("cut" == command_name)
{
@@ -1262,8 +1256,9 @@ bool LLLandmarksPanel::handleDragAndDropToTrash(BOOL drop, EDragAndDropType carg
LLInventoryItem* item = static_cast<LLInventoryItem*>(cargo_data);
if (item)
{
- LLFolderViewItem* fv_item = (mCurrentSelectedList && mCurrentSelectedList->getRootFolder()) ?
- mCurrentSelectedList->getRootFolder()->getItemByID(item->getUUID()) : NULL;
+ LLFolderViewItem* fv_item = mCurrentSelectedList
+ ? mCurrentSelectedList->getItemByID(item->getUUID())
+ : NULL;
if (fv_item)
{
@@ -1391,7 +1386,7 @@ void LLLandmarksPanel::doCreatePick(LLLandmark* landmark)
static void filter_list(LLPlacesInventoryPanel* inventory_list, const std::string& string)
{
// When search is cleared, restore the old folder state.
- if (!inventory_list->getRootFolder()->getFilterSubString().empty() && string == "")
+ if (!inventory_list->getFilterSubString().empty() && string == "")
{
inventory_list->setFilterSubString(LLStringUtil::null);
// Re-open folders that were open before
@@ -1405,7 +1400,7 @@ static void filter_list(LLPlacesInventoryPanel* inventory_list, const std::strin
}
// save current folder open state if no filter currently applied
- if (inventory_list->getRootFolder()->getFilterSubString().empty())
+ if (inventory_list->getFilterSubString().empty())
{
inventory_list->saveFolderState();
}
diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h
index b2f4e92473..aa5f69739d 100644
--- a/indra/newview/llpanellandmarks.h
+++ b/indra/newview/llpanellandmarks.h
@@ -44,6 +44,7 @@ class LLMenuGL;
class LLToggleableMenu;
class LLInventoryPanel;
class LLPlacesInventoryPanel;
+class LLFolderViewModelItemInventory;
class LLLandmarksPanel : public LLPanelPlacesTab, LLRemoteParcelInfoObserver
{
@@ -87,6 +88,7 @@ protected:
bool isReceivedFolderSelected() const;
void doActionOnCurSelectedLandmark(LLLandmarkList::loaded_callback_t cb);
LLFolderViewItem* getCurSelectedItem() const;
+ LLFolderViewModelItemInventory* getCurSelectedViewModelItem() const;
/**
* Selects item with "obj_id" in "inventory_list" and scrolls accordion
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index c11597f532..fea27b37d3 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -47,12 +47,14 @@
#include "llresmgr.h"
#include "llscrollcontainer.h"
#include "llsdserialize.h"
+#include "llsdparam.h"
#include "llspinctrl.h"
#include "lltoggleablemenu.h"
#include "lltooldraganddrop.h"
#include "llviewermenu.h"
#include "llviewertexturelist.h"
#include "llsidepanelinventory.h"
+#include "llfolderview.h"
const std::string FILTERS_FILENAME("filters.xml");
@@ -171,7 +173,10 @@ BOOL LLPanelMainInventory::postBuild()
{
LLSD recent_items = savedFilterState.get(
recent_items_panel->getFilter()->getName());
- recent_items_panel->getFilter()->fromLLSD(recent_items);
+ LLInventoryFilter::Params p;
+ LLParamSDParser parser;
+ parser.readSD(recent_items, p);
+ recent_items_panel->getFilter()->fromParams(p);
}
}
@@ -212,21 +217,25 @@ LLPanelMainInventory::~LLPanelMainInventory( void )
if (filter)
{
LLSD filterState;
- filter->toLLSD(filterState);
- filterRoot[filter->getName()] = filterState;
+ LLInventoryFilter::Params p;
+ filter->toParams(p);
+ if (p.validateBlock(false))
+ {
+ LLParamSDParser().writeSD(filterState, p);
+ filterRoot[filter->getName()] = filterState;
+ }
}
}
- LLInventoryPanel* recent_items_panel = getChild<LLInventoryPanel>("Recent Items");
- if (recent_items_panel)
+ LLInventoryFilter* filter = findChild<LLInventoryPanel>("Recent Items")->getFilter();
+ if (filter)
{
- LLInventoryFilter* filter = recent_items_panel->getFilter();
- if (filter)
- {
- LLSD filterState;
- filter->toLLSD(filterState);
- filterRoot[filter->getName()] = filterState;
- }
+ LLSD filterState;
+ LLInventoryFilter::Params p;
+ filter->toParams(p);
+ LLParamSDParser parser;
+ parser.writeSD(filterState, p);
+ filterRoot[filter->getName()] = filterState;
}
std::ostringstream filterSaveName;
@@ -285,7 +294,7 @@ BOOL LLPanelMainInventory::handleKeyHere(KEY key, MASK mask)
void LLPanelMainInventory::doToSelected(const LLSD& userdata)
{
- getPanel()->getRootFolder()->doToSelected(&gInventory, userdata);
+ getPanel()->doToSelected(userdata);
}
void LLPanelMainInventory::closeAllFolders()
@@ -306,7 +315,7 @@ void LLPanelMainInventory::newWindow()
void LLPanelMainInventory::doCreate(const LLSD& userdata)
{
- menu_create_inventory_item(getPanel()->getRootFolder(), NULL, userdata);
+ menu_create_inventory_item(getPanel(), NULL, userdata);
}
void LLPanelMainInventory::resetFilters()
@@ -417,7 +426,7 @@ void LLPanelMainInventory::onFilterEdit(const std::string& search_string )
}
// save current folder open state if no filter currently applied
- if (!mActivePanel->getRootFolder()->isFilterModified())
+ if (!mActivePanel->getFilter()->isNotDefault())
{
mSavedFolderState->setApply(FALSE);
mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
@@ -961,7 +970,7 @@ void LLPanelMainInventory::onTrashButtonClick()
void LLPanelMainInventory::onClipboardAction(const LLSD& userdata)
{
std::string command_name = userdata.asString();
- getActivePanel()->getRootFolder()->doToSelected(getActivePanel()->getModel(),command_name);
+ getActivePanel()->doToSelected(command_name);
}
void LLPanelMainInventory::saveTexture(const LLSD& userdata)
@@ -972,7 +981,7 @@ void LLPanelMainInventory::saveTexture(const LLSD& userdata)
return;
}
- const LLUUID& item_id = current_item->getListener()->getUUID();
+ const LLUUID& item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
LLPreviewTexture* preview_texture = LLFloaterReg::showTypedInstance<LLPreviewTexture>("preview_texture", LLSD(item_id), TAKE_FOCUS_YES);
if (preview_texture)
{
@@ -1045,7 +1054,7 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
{
return;
}
- const LLUUID item_id = current_item->getListener()->getUUID();
+ const LLUUID item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
LLViewerInventoryItem *item = gInventory.getItem(item_id);
if (item)
{
@@ -1060,7 +1069,7 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
{
return;
}
- current_item->getListener()->performAction(getActivePanel()->getModel(), "goto");
+ static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->performAction(getActivePanel()->getModel(), "goto");
}
if (command_name == "find_links")
@@ -1070,8 +1079,8 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
{
return;
}
- const LLUUID& item_id = current_item->getListener()->getUUID();
- const std::string &item_name = current_item->getListener()->getName();
+ const LLUUID& item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
+ const std::string &item_name = current_item->getViewModelItem()->getName();
mFilterSubString = item_name;
LLInventoryFilter *filter = mActivePanel->getFilter();
filter->setFilterSubString(item_name);
@@ -1089,11 +1098,11 @@ bool LLPanelMainInventory::isSaveTextureEnabled(const LLSD& userdata)
LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
if (current_item)
{
- LLViewerInventoryItem *inv_item = current_item->getInventoryItem();
+ LLViewerInventoryItem *inv_item = dynamic_cast<LLViewerInventoryItem*>(static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getInventoryObject());
if(inv_item)
{
bool can_save = inv_item->checkPermissionsSet(PERM_ITEM_UNRESTRICTED);
- LLInventoryType::EType curr_type = current_item->getListener()->getInventoryType();
+ LLInventoryType::EType curr_type = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getInventoryType();
return can_save && (curr_type == LLInventoryType::IT_TEXTURE || curr_type == LLInventoryType::IT_SNAPSHOT);
}
}
@@ -1110,15 +1119,14 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
if (root)
{
can_delete = TRUE;
- std::set<LLUUID> selection_set = root->getSelectionList();
+ std::set<LLFolderViewItem*> selection_set = root->getSelectionList();
if (selection_set.empty()) return FALSE;
- for (std::set<LLUUID>::iterator iter = selection_set.begin();
+ for (std::set<LLFolderViewItem*>::iterator iter = selection_set.begin();
iter != selection_set.end();
++iter)
{
- const LLUUID &item_id = (*iter);
- LLFolderViewItem *item = root->getItemByID(item_id);
- const LLFolderViewEventListener *listener = item->getListener();
+ LLFolderViewItem *item = *iter;
+ const LLFolderViewModelItemInventory *listener = static_cast<const LLFolderViewModelItemInventory*>(item->getViewModelItem());
llassert(listener);
if (!listener) return FALSE;
can_delete &= listener->isItemRemovable();
@@ -1136,7 +1144,7 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
{
LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
if (!current_item) return FALSE;
- const LLUUID& item_id = current_item->getListener()->getUUID();
+ const LLUUID& item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
const LLViewerInventoryItem *item = gInventory.getItem(item_id);
if (item && item->getIsLinkType() && !item->getIsBrokenLink())
{
@@ -1148,11 +1156,11 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
if (command_name == "find_links")
{
LLFolderView* root = getActivePanel()->getRootFolder();
- std::set<LLUUID> selection_set = root->getSelectionList();
+ std::set<LLFolderViewItem*> selection_set = root->getSelectionList();
if (selection_set.size() != 1) return FALSE;
LLFolderViewItem* current_item = root->getCurSelectedItem();
if (!current_item) return FALSE;
- const LLUUID& item_id = current_item->getListener()->getUUID();
+ const LLUUID& item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
const LLInventoryObject *obj = gInventory.getObject(item_id);
if (obj && !obj->getIsLinkType() && LLAssetType::lookupCanLink(obj->getType()))
{
@@ -1165,7 +1173,7 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
{
LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
if (!current_item) return FALSE;
- const LLUUID& item_id = current_item->getListener()->getUUID();
+ const LLUUID& item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
const LLViewerInventoryItem *item = gInventory.getItem(item_id);
if (item && item->getIsBrokenLink())
{
diff --git a/indra/newview/llpanelmarketplaceinbox.cpp b/indra/newview/llpanelmarketplaceinbox.cpp
index 66c9c323cb..3547156197 100644
--- a/indra/newview/llpanelmarketplaceinbox.cpp
+++ b/indra/newview/llpanelmarketplaceinbox.cpp
@@ -94,7 +94,7 @@ LLInventoryPanel * LLPanelMarketplaceInbox::setupInventoryPanel()
mInventoryPanel->setShape(inventory_placeholder_rect);
// Set the sort order newest to oldest
- mInventoryPanel->setSortOrder(LLInventoryFilter::SO_DATE);
+ mInventoryPanel->getFolderViewModel()->setSorter(LLInventoryFilter::SO_DATE);
mInventoryPanel->getFilter()->markDefault();
// Set selection callback for proper update of inventory status buttons
@@ -139,7 +139,7 @@ U32 LLPanelMarketplaceInbox::getFreshItemCount() const
if (mInventoryPanel)
{
- const LLFolderViewFolder * inbox_folder = mInventoryPanel->getRootFolder();
+ LLFolderViewFolder * inbox_folder = mInventoryPanel->getRootFolder();
if (inbox_folder)
{
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.cpp b/indra/newview/llpanelmarketplaceinboxinventory.cpp
index 678e4f2843..6e5a522297 100644
--- a/indra/newview/llpanelmarketplaceinboxinventory.cpp
+++ b/indra/newview/llpanelmarketplaceinboxinventory.cpp
@@ -29,7 +29,8 @@
#include "llpanelmarketplaceinboxinventory.h"
#include "llfolderview.h"
-#include "llfoldervieweventlistener.h"
+#include "llfolderviewitem.h"
+#include "llfolderviewmodel.h"
#include "llinventorybridge.h"
#include "llinventoryfunctions.h"
#include "llpanellandmarks.h"
@@ -110,6 +111,7 @@ void LLInboxInventoryPanel::buildFolderView(const LLInventoryPanel::Params& para
LLAssetType::AT_CATEGORY,
LLInventoryType::IT_CATEGORY,
this,
+ &mInventoryViewModel,
NULL,
root_id);
@@ -121,14 +123,6 @@ LLFolderViewFolder * LLInboxInventoryPanel::createFolderViewFolder(LLInvFVBridge
LLInboxFolderViewFolder::Params params;
params.name = bridge->getDisplayName();
- params.icon = bridge->getIcon();
- params.icon_open = bridge->getOpenIcon();
-
- if (mShowItemLinkOverlays) // if false, then links show up just like normal items
- {
- params.icon_overlay = LLUI::getUIImage("Inv_Link");
- }
-
params.root = mFolderRoot;
params.listener = bridge;
params.tool_tip = params.name;
@@ -141,14 +135,6 @@ LLFolderViewItem * LLInboxInventoryPanel::createFolderViewItem(LLInvFVBridge * b
LLInboxFolderViewItem::Params params;
params.name = bridge->getDisplayName();
- params.icon = bridge->getIcon();
- params.icon_open = bridge->getOpenIcon();
-
- if (mShowItemLinkOverlays) // if false, then links show up just like normal items
- {
- params.icon_overlay = LLUI::getUIImage("Inv_Link");
- }
-
params.creation_date = bridge->getCreationDate();
params.root = mFolderRoot;
params.listener = bridge;
@@ -207,7 +193,7 @@ void LLInboxFolderViewFolder::computeFreshness()
if (last_expansion_utc > 0)
{
- mFresh = (mCreationDate > last_expansion_utc);
+ mFresh = (static_cast<LLFolderViewModelItemInventory*>(getViewModelItem())->getCreationDate() > last_expansion_utc);
#if DEBUGGING_FRESHNESS
if (mFresh)
@@ -229,15 +215,16 @@ void LLInboxFolderViewFolder::deFreshify()
gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected());
}
-void LLInboxFolderViewFolder::setCreationDate(time_t creation_date_utc)
-{
- mCreationDate = creation_date_utc;
-
- if (mParentFolder == mRoot)
- {
- computeFreshness();
- }
-}
+// TODO RN: move this behavior to modelview?
+//void LLInboxFolderViewFolder::setCreationDate(time_t creation_date_utc)
+//{
+// mCreationDate = creation_date_utc;
+//
+// if (LLFolderViewItem::mParentFolder == mRoot)
+// {
+// computeFreshness();
+// }
+//}
//
// LLInboxFolderViewItem Implementation
@@ -253,9 +240,9 @@ LLInboxFolderViewItem::LLInboxFolderViewItem(const Params& p)
#endif
}
-BOOL LLInboxFolderViewItem::addToFolder(LLFolderViewFolder* folder, LLFolderView* root)
+BOOL LLInboxFolderViewItem::addToFolder(LLFolderViewFolder* folder)
{
- BOOL retval = LLFolderViewItem::addToFolder(folder, root);
+ BOOL retval = LLFolderViewItem::addToFolder(folder);
#if SUPPORTING_FRESH_ITEM_COUNT
// Compute freshness if our parent is the root folder for the inbox
@@ -303,7 +290,7 @@ void LLInboxFolderViewItem::computeFreshness()
if (last_expansion_utc > 0)
{
- mFresh = (mCreationDate > last_expansion_utc);
+ mFresh = (static_cast<LLFolderViewModelItemInventory*>(getViewModelItem())->getCreationDate() > last_expansion_utc);
#if DEBUGGING_FRESHNESS
if (mFresh)
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.h b/indra/newview/llpanelmarketplaceinboxinventory.h
index d6b827ee3e..209f3a4098 100644
--- a/indra/newview/llpanelmarketplaceinboxinventory.h
+++ b/indra/newview/llpanelmarketplaceinboxinventory.h
@@ -81,8 +81,6 @@ public:
bool isFresh() const { return mFresh; }
protected:
- void setCreationDate(time_t creation_date_utc);
-
bool mFresh;
};
@@ -102,7 +100,7 @@ public:
LLInboxFolderViewItem(const Params& p);
- BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root);
+ BOOL addToFolder(LLFolderViewFolder* folder);
BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
void draw();
diff --git a/indra/newview/llpanelmarketplaceoutboxinventory.cpp b/indra/newview/llpanelmarketplaceoutboxinventory.cpp
index ff62cb23db..2885dd6266 100644
--- a/indra/newview/llpanelmarketplaceoutboxinventory.cpp
+++ b/indra/newview/llpanelmarketplaceoutboxinventory.cpp
@@ -28,8 +28,8 @@
#include "llpanelmarketplaceoutboxinventory.h"
-#include "llfolderview.h"
-#include "llfoldervieweventlistener.h"
+#include "llfolderviewitem.h"
+#include "llfolderviewmodel.h"
#include "llinventorybridge.h"
#include "llinventoryfunctions.h"
#include "llpanellandmarks.h"
@@ -77,6 +77,7 @@ void LLOutboxInventoryPanel::buildFolderView(const LLInventoryPanel::Params& par
LLAssetType::AT_CATEGORY,
LLInventoryType::IT_CATEGORY,
this,
+ &mInventoryViewModel,
NULL,
root_id);
@@ -88,14 +89,6 @@ LLFolderViewFolder * LLOutboxInventoryPanel::createFolderViewFolder(LLInvFVBridg
LLOutboxFolderViewFolder::Params params;
params.name = bridge->getDisplayName();
- params.icon = bridge->getIcon();
- params.icon_open = bridge->getOpenIcon();
-
- if (mShowItemLinkOverlays) // if false, then links show up just like normal items
- {
- params.icon_overlay = LLUI::getUIImage("Inv_Link");
- }
-
params.root = mFolderRoot;
params.listener = bridge;
params.tool_tip = params.name;
@@ -108,14 +101,6 @@ LLFolderViewItem * LLOutboxInventoryPanel::createFolderViewItem(LLInvFVBridge *
LLFolderViewItem::Params params;
params.name = bridge->getDisplayName();
- params.icon = bridge->getIcon();
- params.icon_open = bridge->getOpenIcon();
-
- if (mShowItemLinkOverlays) // if false, then links show up just like normal items
- {
- params.icon_overlay = LLUI::getUIImage("Inv_Link");
- }
-
params.creation_date = bridge->getCreationDate();
params.root = mFolderRoot;
params.listener = bridge;
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index f84d6e5cc1..ca20051a51 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -71,12 +71,13 @@
/// Class LLTaskInvFVBridge
///----------------------------------------------------------------------------
-class LLTaskInvFVBridge : public LLFolderViewEventListener
+class LLTaskInvFVBridge : public LLFolderViewModelItemInventory
{
protected:
LLUUID mUUID;
std::string mName;
mutable std::string mDisplayName;
+ mutable std::string mSearchableName;
LLPanelObjectInventory* mPanel;
U32 mFlags;
LLAssetType::EType mAssetType;
@@ -102,26 +103,29 @@ public:
S32 getPrice();
static bool commitBuyItem(const LLSD& notification, const LLSD& response);
- // LLFolderViewEventListener functionality
+ // LLFolderViewModelItemInventory functionality
virtual const std::string& getName() const;
virtual const std::string& getDisplayName() const;
+ virtual const std::string& getSearchableName() const;
+
virtual PermissionMask getPermissionMask() const { return PERM_NONE; }
/*virtual*/ LLFolderType::EType getPreferredType() const { return LLFolderType::FT_NONE; }
virtual const LLUUID& getUUID() const { return mUUID; }
virtual time_t getCreationDate() const;
+ virtual void setCreationDate(time_t creation_date_utc);
+
virtual LLUIImagePtr getIcon() const;
virtual void openItem();
virtual BOOL canOpenItem() const { return FALSE; }
virtual void closeItem() {}
- virtual void previewItem();
virtual void selectItem() {}
virtual BOOL isItemRenameable() const;
virtual BOOL renameItem(const std::string& new_name);
virtual BOOL isItemMovable() const;
virtual BOOL isItemRemovable() const;
virtual BOOL removeItem();
- virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch);
- virtual void move(LLFolderViewEventListener* parent_listener);
+ virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch);
+ virtual void move(LLFolderViewModelItem* parent_listener);
virtual BOOL isItemCopyable() const;
virtual BOOL copyToClipboard() const;
virtual BOOL cutToClipboard() const;
@@ -131,11 +135,15 @@ public:
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
virtual void performAction(LLInventoryModel* model, std::string action);
virtual BOOL isUpToDate() const { return TRUE; }
- virtual BOOL hasChildren() const { return FALSE; }
+ virtual bool hasChildren() const { return FALSE; }
virtual LLInventoryType::EType getInventoryType() const { return LLInventoryType::IT_NONE; }
virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_NONE; }
+ virtual EInventorySortGroup getSortGroup() const { return SG_ITEM; }
+ virtual LLInventoryObject* getInventoryObject() const { return findInvObject(); }
+
// LLDragAndDropBridge functionality
+ virtual LLToolDragAndDrop::ESource getDragSource() const { return LLToolDragAndDrop::SOURCE_WORLD; }
virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const;
virtual BOOL dragOrDrop(MASK mask, BOOL drop,
EDragAndDropType cargo_type,
@@ -330,15 +338,27 @@ const std::string& LLTaskInvFVBridge::getDisplayName() const
}
}
+ mSearchableName.assign(mDisplayName + getLabelSuffix());
+
return mDisplayName;
}
+const std::string& LLTaskInvFVBridge::getSearchableName() const
+{
+ return mSearchableName;
+}
+
+
// BUG: No creation dates for task inventory
time_t LLTaskInvFVBridge::getCreationDate() const
{
return 0;
}
+void LLTaskInvFVBridge::setCreationDate(time_t creation_date_utc)
+{}
+
+
LLUIImagePtr LLTaskInvFVBridge::getIcon() const
{
const BOOL item_is_multi = (mFlags & LLInventoryItemFlags::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS);
@@ -352,11 +372,6 @@ void LLTaskInvFVBridge::openItem()
lldebugs << "LLTaskInvFVBridge::openItem()" << llendl;
}
-void LLTaskInvFVBridge::previewItem()
-{
- openItem();
-}
-
BOOL LLTaskInvFVBridge::isItemRenameable() const
{
if(gAgent.isGodlike()) return TRUE;
@@ -467,7 +482,7 @@ BOOL LLTaskInvFVBridge::removeItem()
return FALSE;
}
-void LLTaskInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch)
+void LLTaskInvFVBridge::removeBatch(std::vector<LLFolderViewModelItem*>& batch)
{
if (!mPanel)
{
@@ -507,7 +522,7 @@ void LLTaskInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>&
}
}
-void LLTaskInvFVBridge::move(LLFolderViewEventListener* parent_listener)
+void LLTaskInvFVBridge::move(LLFolderViewModelItem* parent_listener)
{
}
@@ -709,7 +724,7 @@ public:
virtual BOOL renameItem(const std::string& new_name);
virtual BOOL isItemRemovable() const;
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
- virtual BOOL hasChildren() const;
+ virtual bool hasChildren() const;
virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const;
virtual BOOL dragOrDrop(MASK mask, BOOL drop,
EDragAndDropType cargo_type,
@@ -717,6 +732,7 @@ public:
std::string& tooltip_msg);
virtual BOOL canOpenItem() const { return TRUE; }
virtual void openItem();
+ virtual EInventorySortGroup getSortGroup() const { return SG_NORMAL_FOLDER; }
};
LLTaskCategoryBridge::LLTaskCategoryBridge(
@@ -767,7 +783,7 @@ void LLTaskCategoryBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
hide_context_entries(menu, items, disabled_items);
}
-BOOL LLTaskCategoryBridge::hasChildren() const
+bool LLTaskCategoryBridge::hasChildren() const
{
// return TRUE if we have or do know know if we have children.
// *FIX: For now, return FALSE - we will know for sure soon enough.
@@ -1506,7 +1522,7 @@ BOOL LLPanelObjectInventory::postBuild()
void LLPanelObjectInventory::doToSelected(const LLSD& userdata)
{
- mFolders->doToSelected(&gInventory, userdata);
+ LLInventoryAction::doToSelected(&gInventory, mFolders, userdata.asString());
}
void LLPanelObjectInventory::clearContents()
@@ -1541,14 +1557,15 @@ void LLPanelObjectInventory::reset()
LLFolderView::Params p;
p.name = "task inventory";
p.title = "task inventory";
- p.task_id = getTaskUUID();
p.parent_panel = this;
p.tool_tip= LLTrans::getString("PanelContentsTooltip");
p.listener = LLTaskInvFVBridge::createObjectBridge(this, NULL);
p.folder_indentation = -14; // subtract space normally reserved for folder expanders
+ p.view_model = &mInventoryViewModel;
mFolders = LLUICtrlFactory::create<LLFolderView>(p);
// this ensures that we never say "searching..." or "no items found"
- mFolders->getFilter()->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
+ //TODO RN: make this happen by manipulating filter object directly
+ static_cast<LLInventoryFilter*>(mFolders->getFolderViewModel()->getFilter())->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
mFolders->setCallbackRegistrar(&mCommitCallbackRegistrar);
if (hasFocus())
@@ -1608,7 +1625,7 @@ void LLPanelObjectInventory::updateInventory()
// << " panel UUID: " << panel->mTaskUUID << "\n"
// << " task UUID: " << object->mID << llendl;
// We're still interested in this task's inventory.
- std::set<LLUUID> selected_items;
+ std::set<LLFolderViewItem*> selected_items;
BOOL inventory_has_focus = FALSE;
if (mHaveInventory)
{
@@ -1646,11 +1663,11 @@ void LLPanelObjectInventory::updateInventory()
}
// restore previous selection
- std::set<LLUUID>::iterator selection_it;
+ std::set<LLFolderViewItem*>::iterator selection_it;
BOOL first_item = TRUE;
for (selection_it = selected_items.begin(); selection_it != selected_items.end(); ++selection_it)
{
- LLFolderViewItem* selected_item = mFolders->getItemByID(*selection_it);
+ LLFolderViewItem* selected_item = (*selection_it);
if (selected_item)
{
//HACK: "set" first item then "change" each other one to get keyboard focus right
@@ -1687,18 +1704,6 @@ void LLPanelObjectInventory::createFolderViews(LLInventoryObject* inventory_root
bridge = LLTaskInvFVBridge::createObjectBridge(this, inventory_root);
if(bridge)
{
- //LLFolderViewFolder* new_folder = NULL;
- //LLFolderViewFolder::Params p;
- //p.name = inventory_root->getName();
- //p.icon = LLUI::getUIImage("Inv_FolderClosed");
- //p.icon_open = LLUI::getUIImage("Inv_FolderOpen");
- //p.root = mFolders;
- //p.listener = bridge;
- //p.tool_tip = p.name;
- //new_folder = LLUICtrlFactory::create<LLFolderViewFolder>(p);
- //new_folder->addToFolder(mFolders, mFolders);
- //new_folder->toggleOpen();
-
createViewsForCategory(&contents, inventory_root, mFolders);
}
}
@@ -1731,8 +1736,6 @@ void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_li
{
LLFolderViewFolder::Params p;
p.name = obj->getName();
- p.icon = LLUI::getUIImage("Inv_FolderClosed");
- p.icon_open = LLUI::getUIImage("Inv_FolderOpen");
p.root = mFolders;
p.listener = bridge;
p.tool_tip = p.name;
@@ -1744,7 +1747,6 @@ void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_li
{
LLFolderViewItem::Params params;
params.name(obj->getName());
- params.icon(bridge->getIcon());
params.creation_date(bridge->getCreationDate());
params.root(mFolders);
params.listener(bridge);
@@ -1752,7 +1754,7 @@ void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_li
params.tool_tip = params.name;
view = LLUICtrlFactory::create<LLFolderViewItem> (params);
}
- view->addToFolder(folder, mFolders);
+ view->addToFolder(folder);
}
}
@@ -1820,6 +1822,7 @@ void LLPanelObjectInventory::refresh()
removeVOInventoryListener();
clearContents();
}
+ mInventoryViewModel.setTaskID(mTaskUUID);
//llinfos << "LLPanelObjectInventory::refresh() " << mTaskUUID << llendl;
}
diff --git a/indra/newview/llpanelobjectinventory.h b/indra/newview/llpanelobjectinventory.h
index 607b705f7f..7e857f8b31 100644
--- a/indra/newview/llpanelobjectinventory.h
+++ b/indra/newview/llpanelobjectinventory.h
@@ -29,6 +29,7 @@
#include "llvoinventorylistener.h"
#include "llpanel.h"
+#include "llinventorypanel.h" // for LLFolderViewModelInventory
#include "llinventory.h"
@@ -94,6 +95,7 @@ private:
BOOL mHaveInventory;
BOOL mIsInventoryEmpty;
BOOL mInventoryNeedsUpdate;
+ LLFolderViewModelInventory mInventoryViewModel;
};
#endif // LL_LLPANELOBJECTINVENTORY_H
diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index 35e2e96bab..d690a18477 100644
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -270,7 +270,7 @@ private:
if (inventory_panel->getVisible())
{
- inventory_panel->setSortOrder(sort_order);
+ inventory_panel->getFolderViewModel()->setSorter(sort_order);
}
else
{
@@ -738,7 +738,7 @@ void LLPanelOutfitEdit::onSearchEdit(const std::string& string)
}
// save current folder open state if no filter currently applied
- if (mInventoryItemsPanel->getRootFolder()->getFilterSubString().empty())
+ if (mInventoryItemsPanel->getFilterSubString().empty())
{
mSavedFolderState->setApply(FALSE);
mInventoryItemsPanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
@@ -885,13 +885,13 @@ LLPanelOutfitEdit::selection_info_t LLPanelOutfitEdit::getAddMorePanelSelectionT
{
if (mInventoryItemsPanel != NULL && mInventoryItemsPanel->getVisible())
{
- std::set<LLUUID> selected_uuids = mInventoryItemsPanel->getRootFolder()->getSelectionList();
+ std::set<LLFolderViewItem*> selected_items = mInventoryItemsPanel->getRootFolder()->getSelectionList();
- result.second = selected_uuids.size();
+ result.second = selected_items.size();
if (result.second == 1)
{
- result.first = getWearableTypeByItemUUID(*(selected_uuids.begin()));
+ result.first = getWearableTypeByItemUUID(static_cast<LLFolderViewModelItemInventory*>((*selected_items.begin())->getViewModelItem())->getUUID());
}
}
else if (mWearableItemsList != NULL && mWearableItemsList->getVisible())
@@ -1310,7 +1310,7 @@ void LLPanelOutfitEdit::getCurrentItemUUID(LLUUID& selected_id)
LLFolderViewItem* curr_item = mInventoryItemsPanel->getRootFolder()->getCurSelectedItem();
if (!curr_item) return;
- LLFolderViewEventListener* listenerp = curr_item->getListener();
+ LLFolderViewModelItemInventory* listenerp = static_cast<LLFolderViewModelItemInventory*>(curr_item->getViewModelItem());
if (!listenerp) return;
selected_id = listenerp->getUUID();
@@ -1327,9 +1327,13 @@ void LLPanelOutfitEdit::getSelectedItemsUUID(uuid_vec_t& uuid_list)
void (uuid_vec_t::* tmp)(LLUUID const &) = &uuid_vec_t::push_back;
if (mInventoryItemsPanel->getVisible())
{
- std::set<LLUUID> item_set = mInventoryItemsPanel->getRootFolder()->getSelectionList();
-
- std::for_each(item_set.begin(), item_set.end(), boost::bind( tmp, &uuid_list, _1));
+ std::set<LLFolderViewItem*> item_set = mInventoryItemsPanel->getRootFolder()->getSelectionList();
+ for (std::set<LLFolderViewItem*>::iterator it = item_set.begin(), end_it = item_set.end();
+ it != end_it;
+ ++it)
+ {
+ uuid_list.push_back(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID());
+ }
}
else if (mWearablesListViewPanel->getVisible())
{
@@ -1374,13 +1378,13 @@ void LLPanelOutfitEdit::saveListSelection()
{
if(mWearablesListViewPanel->getVisible())
{
- std::set<LLUUID> selected_ids = mInventoryItemsPanel->getRootFolder()->getSelectionList();
+ std::set<LLFolderViewItem*> selected_ids = mInventoryItemsPanel->getRootFolder()->getSelectionList();
if(!selected_ids.size()) return;
- for (std::set<LLUUID>::const_iterator item_id = selected_ids.begin(); item_id != selected_ids.end(); ++item_id)
+ for (std::set<LLFolderViewItem*>::const_iterator item_id = selected_ids.begin(); item_id != selected_ids.end(); ++item_id)
{
- mWearableItemsList->selectItemByUUID(*item_id, true);
+ mWearableItemsList->selectItemByUUID(static_cast<LLFolderViewModelItemInventory*>((*item_id)->getViewModelItem())->getUUID(), true);
}
mWearableItemsList->scrollToShowFirstSelectedItem();
}
@@ -1398,7 +1402,7 @@ void LLPanelOutfitEdit::saveListSelection()
for(std::vector<LLUUID>::const_iterator item_id = selected_ids.begin(); item_id != selected_ids.end(); ++item_id)
{
- LLFolderViewItem* item = root->getItemByID(*item_id);
+ LLFolderViewItem* item = mInventoryItemsPanel->getItemByID(*item_id);
if (!item) continue;
LLFolderViewFolder* parent = item->getParentFolder();
diff --git a/indra/newview/llplacesinventorybridge.cpp b/indra/newview/llplacesinventorybridge.cpp
index fe4cc0f55f..af29ab7ea9 100644
--- a/indra/newview/llplacesinventorybridge.cpp
+++ b/indra/newview/llplacesinventorybridge.cpp
@@ -85,34 +85,33 @@ void LLPlacesLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
void LLPlacesFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
+ std::vector<std::string> items;
+ std::vector<std::string> disabled_items;
+
+ LLInventoryPanel* inv_panel = mInventoryPanel.get();
+ bool is_open = false;
+ if (inv_panel)
{
- std::vector<std::string> items;
- std::vector<std::string> disabled_items;
+ LLFolderViewFolder* folder = dynamic_cast<LLFolderViewFolder*>(inv_panel->getItemByID(mUUID));
+ is_open = (NULL != folder) && folder->isOpen();
+ }
- LLInventoryPanel* inv_panel = mInventoryPanel.get();
- bool is_open = false;
- if (inv_panel)
- {
- LLFolderViewFolder* folder = dynamic_cast<LLFolderViewFolder*>(inv_panel->getRootFolder()->getItemByID(mUUID));
- is_open = (NULL != folder) && folder->isOpen();
- }
+ // collect all items' names
+ fill_items_with_menu_items(items, menu);
- // collect all items' names
- fill_items_with_menu_items(items, menu);
+ // remove expand or collapse menu item depend on folder state
+ std::string collapse_expand_item_to_hide(is_open ? "expand" : "collapse");
+ std::vector<std::string>::iterator it = std::find(items.begin(), items.end(), collapse_expand_item_to_hide);
+ if (it != items.end()) items.erase(it);
- // remove expand or collapse menu item depend on folder state
- std::string collapse_expand_item_to_hide(is_open ? "expand" : "collapse");
- std::vector<std::string>::iterator it = std::find(items.begin(), items.end(), collapse_expand_item_to_hide);
- if (it != items.end()) items.erase(it);
- // Disabled items are processed via LLLandmarksPanel::isActionEnabled()
- // they should be synchronized with Places/My Landmarks/Gear menu. See EXT-1601
+ // Disabled items are processed via LLLandmarksPanel::isActionEnabled()
+ // they should be synchronized with Places/My Landmarks/Gear menu. See EXT-1601
- // repeat parent functionality
- sSelf = getHandle(); // necessary for "New Folder" functionality
+ // repeat parent functionality
+ sSelf = getHandle(); // necessary for "New Folder" functionality
- hide_context_entries(menu, items, disabled_items);
- }
+ hide_context_entries(menu, items, disabled_items);
}
//virtual
@@ -140,7 +139,7 @@ LLFolderViewFolder* LLPlacesFolderBridge::getFolder()
LLInventoryPanel* inv_panel = mInventoryPanel.get();
if (inv_panel)
{
- folder = dynamic_cast<LLFolderViewFolder*>(inv_panel->getRootFolder()->getItemByID(mUUID));
+ folder = dynamic_cast<LLFolderViewFolder*>(inv_panel->getItemByID(mUUID));
}
return folder;
@@ -152,6 +151,7 @@ LLInvFVBridge* LLPlacesInventoryBridgeBuilder::createBridge(
LLAssetType::EType actual_asset_type,
LLInventoryType::EType inv_type,
LLInventoryPanel* inventory,
+ LLFolderViewModelInventory* view_model,
LLFolderView* root,
const LLUUID& uuid,
U32 flags/* = 0x00*/) const
@@ -165,6 +165,7 @@ LLInvFVBridge* LLPlacesInventoryBridgeBuilder::createBridge(
llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << LLInventoryType::lookupHumanReadable(inv_type) << " on uuid " << uuid << llendl;
}
new_listener = new LLPlacesLandmarkBridge(inv_type, inventory, root, uuid, flags);
+ new_listener->setRootViewModel(view_model);
break;
case LLAssetType::AT_CATEGORY:
if (actual_asset_type == LLAssetType::AT_LINK_FOLDER)
@@ -175,12 +176,14 @@ LLInvFVBridge* LLPlacesInventoryBridgeBuilder::createBridge(
actual_asset_type,
inv_type,
inventory,
+ view_model,
root,
uuid,
flags);
break;
}
new_listener = new LLPlacesFolderBridge(inv_type, inventory, root, uuid);
+ new_listener->setRootViewModel(view_model);
break;
default:
new_listener = LLInventoryFVBridgeBuilder::createBridge(
@@ -188,6 +191,7 @@ LLInvFVBridge* LLPlacesInventoryBridgeBuilder::createBridge(
actual_asset_type,
inv_type,
inventory,
+ view_model,
root,
uuid,
flags);
diff --git a/indra/newview/llplacesinventorybridge.h b/indra/newview/llplacesinventorybridge.h
index 52beacef9c..791502990b 100644
--- a/indra/newview/llplacesinventorybridge.h
+++ b/indra/newview/llplacesinventorybridge.h
@@ -89,6 +89,7 @@ public:
LLAssetType::EType actual_asset_type,
LLInventoryType::EType inv_type,
LLInventoryPanel* inventory,
+ LLFolderViewModelInventory* view_model,
LLFolderView* root,
const LLUUID& uuid,
U32 flags = 0x00) const;
diff --git a/indra/newview/llplacesinventorypanel.cpp b/indra/newview/llplacesinventorypanel.cpp
index f7823f4fe8..d95d5eac19 100644
--- a/indra/newview/llplacesinventorypanel.cpp
+++ b/indra/newview/llplacesinventorypanel.cpp
@@ -30,7 +30,8 @@
#include "llplacesinventorypanel.h"
-#include "llfoldervieweventlistener.h"
+#include "llfolderviewmodel.h"
+#include "llfolderview.h"
#include "llinventorybridge.h"
#include "llinventoryfunctions.h"
#include "llpanellandmarks.h"
@@ -86,12 +87,13 @@ void LLPlacesInventoryPanel::buildFolderView(const LLInventoryPanel::Params& par
LLAssetType::AT_CATEGORY,
LLInventoryType::IT_CATEGORY,
this,
+ &mInventoryViewModel,
NULL,
root_id);
p.parent_panel = this;
p.allow_multiselect = mAllowMultiSelect;
p.use_ellipses = true; // truncate inventory item text so remove horizontal scroller
- mFolderRoot = (LLFolderView*)LLUICtrlFactory::create<LLPlacesFolderView>(p);
+ mFolderRoot = LLUICtrlFactory::create<LLPlacesFolderView>(p);
}
@@ -161,7 +163,7 @@ BOOL LLPlacesFolderView::handleRightMouseDown(S32 x, S32 y, MASK mask)
// then determine its type and set necessary menu handle
if (getCurSelectedItem())
{
- LLInventoryType::EType inventory_type = getCurSelectedItem()->getListener()->getInventoryType();
+ LLInventoryType::EType inventory_type = static_cast<LLFolderViewModelItemInventory*>(getCurSelectedItem()->getViewModelItem())->getInventoryType();
inventory_type_menu_handle_t::iterator it_handle = mMenuHandlesByInventoryType.find(inventory_type);
if (it_handle != mMenuHandlesByInventoryType.end())
diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp
index 853656905c..b143240187 100644
--- a/indra/newview/llsidepanelappearance.cpp
+++ b/indra/newview/llsidepanelappearance.cpp
@@ -38,7 +38,7 @@
#include "llfiltereditor.h"
#include "llfloaterreg.h"
#include "llfloaterworldmap.h"
-#include "llfoldervieweventlistener.h"
+#include "llfolderviewmodel.h"
#include "lloutfitobserver.h"
#include "llpaneleditwearable.h"
#include "llpaneloutfitsinventory.h"
@@ -267,11 +267,11 @@ void LLSidepanelAppearance::onOpenOutfitButtonClicked()
if (inventory_panel)
{
LLFolderView* root = inventory_panel->getRootFolder();
- LLFolderViewItem *outfit_folder = root->getItemByID(outfit_link->getLinkedUUID());
+ LLFolderViewItem *outfit_folder = inventory_panel->getItemByID(outfit_link->getLinkedUUID());
if (outfit_folder)
{
outfit_folder->setOpen(!outfit_folder->isOpen());
- root->setSelectionFromRoot(outfit_folder,TRUE);
+ root->setSelection(outfit_folder,TRUE);
root->scrollToShowSelection();
}
}
diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp
index 4f9ab318a5..47bd620fc6 100644
--- a/indra/newview/llsidepanelinventory.cpp
+++ b/indra/newview/llsidepanelinventory.cpp
@@ -36,6 +36,7 @@
#include "llfirstuse.h"
#include "llfloatersidepanelcontainer.h"
#include "llfoldertype.h"
+#include "llfolderview.h"
#include "llhttpclient.h"
#include "llinventorybridge.h"
#include "llinventoryfunctions.h"
@@ -383,10 +384,10 @@ void LLSidepanelInventory::onToggleInboxBtn()
{
inboxPanel->setTargetDim(gSavedPerAccountSettings.getS32("InventoryInboxHeight"));
if (inboxPanel->isInVisibleChain())
- {
- gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected());
- }
+ {
+ gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected());
}
+}
else
{
gSavedPerAccountSettings.setS32("InventoryInboxHeight", inboxPanel->getTargetDim());
@@ -472,7 +473,7 @@ void LLSidepanelInventory::performActionOnSelection(const std::string &action)
}
}
- current_item->getListener()->performAction(mPanelMainInventory->getActivePanel()->getModel(), action);
+ static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->performAction(mPanelMainInventory->getActivePanel()->getModel(), action);
}
void LLSidepanelInventory::onWearButtonClicked()
@@ -662,7 +663,7 @@ LLInventoryItem *LLSidepanelInventory::getSelectedItem()
return NULL;
}
}
- const LLUUID &item_id = current_item->getListener()->getUUID();
+ const LLUUID &item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
LLInventoryItem *item = gInventory.getItem(item_id);
return item;
}
@@ -671,7 +672,7 @@ U32 LLSidepanelInventory::getSelectedCount()
{
int count = 0;
- std::set<LLUUID> selection_list = mPanelMainInventory->getActivePanel()->getRootFolder()->getSelectionList();
+ std::set<LLFolderViewItem*> selection_list = mPanelMainInventory->getActivePanel()->getRootFolder()->getSelectionList();
count += selection_list.size();
if ((count == 0) && mInboxEnabled && (mInventoryPanelInbox != NULL))
@@ -722,9 +723,9 @@ void LLSidepanelInventory::clearSelections(bool clearMain, bool clearInbox)
updateVerbs();
}
-std::set<LLUUID> LLSidepanelInventory::getInboxSelectionList()
+std::set<LLFolderViewItem*> LLSidepanelInventory::getInboxSelectionList()
{
- std::set<LLUUID> inventory_selected_uuids;
+ std::set<LLFolderViewItem*> inventory_selected_uuids;
if (mInboxEnabled && (mInventoryPanelInbox != NULL))
{
diff --git a/indra/newview/llsidepanelinventory.h b/indra/newview/llsidepanelinventory.h
index a33607f50d..e8b2808d4f 100644
--- a/indra/newview/llsidepanelinventory.h
+++ b/indra/newview/llsidepanelinventory.h
@@ -63,7 +63,7 @@ public:
BOOL isMainInventoryPanelActive() const;
void clearSelections(bool clearMain, bool clearInbox);
- std::set<LLUUID> getInboxSelectionList();
+ std::set<LLFolderViewItem*> getInboxSelectionList();
void showItemInfoPanel();
void showTaskInfoPanel();
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index ed9faa0706..cb59f704a5 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -39,7 +39,7 @@
#include "llfocusmgr.h"
#include "llviewertexture.h"
#include "llfolderview.h"
-#include "llfoldervieweventlistener.h"
+#include "llfolderviewmodel.h"
#include "llinventory.h"
#include "llinventoryfunctions.h"
#include "llinventorymodelbackgroundfetch.h"
@@ -58,6 +58,7 @@
#include "lltoolmgr.h"
#include "lltoolpipette.h"
#include "llfiltereditor.h"
+#include "llwindow.h"
#include "lltool.h"
#include "llviewerwindow.h"
@@ -181,7 +182,7 @@ protected:
F32 mContextConeOpacity;
LLSaveFolderState mSavedFolderState;
BOOL mSelectedItemPinned;
-
+
LLRadioGroup* mModeSelector;
LLScrollListCtrl* mLocalScrollCtrl;
};
@@ -358,7 +359,7 @@ BOOL LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask)
{
if (!root_folder->getCurSelectedItem())
{
- LLFolderViewItem* itemp = root_folder->getItemByID(gInventory.getRootFolderID());
+ LLFolderViewItem* itemp = mInventoryPanel->getItemByID(gInventory.getRootFolderID());
if (itemp)
{
root_folder->setSelection(itemp, FALSE, FALSE);
@@ -623,10 +624,9 @@ void LLFloaterTexturePicker::draw()
LLFolderView* folder_view = mInventoryPanel->getRootFolder();
if (!folder_view) return;
- LLInventoryFilter* filter = folder_view->getFilter();
- if (!filter) return;
+ LLFolderViewFilter* filter = static_cast<LLFolderViewModelInventory*>(folder_view->getFolderViewModel())->getFilter();
- bool is_filter_active = folder_view->getCompletedFilterGeneration() < filter->getCurrentGeneration() &&
+ bool is_filter_active = folder_view->getViewModelItem()->getLastFilterGeneration() < filter->getCurrentGeneration() &&
filter->isNotDefault();
// After inventory panel filter is applied we have to update
@@ -637,8 +637,9 @@ void LLFloaterTexturePicker::draw()
if (!is_filter_active && !mSelectedItemPinned)
{
folder_view->setPinningSelectedItem(mSelectedItemPinned);
- folder_view->dirtyFilter();
- folder_view->arrangeFromRoot();
+ folder_view->getViewModelItem()->dirtyFilter();
+ //TODO RN: test..still works without this?
+ //folder_view->arrangeFromRoot();
mSelectedItemPinned = TRUE;
}
@@ -800,7 +801,7 @@ void LLFloaterTexturePicker::onSelectionChange(const std::deque<LLFolderViewItem
if (items.size())
{
LLFolderViewItem* first_item = items.front();
- LLInventoryItem* itemp = gInventory.getItem(first_item->getListener()->getUUID());
+ LLInventoryItem* itemp = gInventory.getItem(static_cast<LLFolderViewModelItemInventory*>(first_item->getViewModelItem())->getUUID());
mNoCopyTextureSelected = FALSE;
if (itemp)
{
@@ -982,7 +983,7 @@ void LLFloaterTexturePicker::onFilterEdit(const std::string& search_string )
else if (mInventoryPanel->getFilterSubString().empty())
{
// first letter in search term, save existing folder open state
- if (!mInventoryPanel->getRootFolder()->isFilterModified())
+ if (!mInventoryPanel->getFilter()->isNotDefault())
{
mSavedFolderState.setApply(FALSE);
mInventoryPanel->getRootFolder()->applyFunctorRecursively(mSavedFolderState);
@@ -1280,7 +1281,7 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLUUID id)
// (i.e. op == TEXTURE_SELECT) or texture changes via DnD.
else if (mCommitOnSelection || op == TEXTURE_SELECT)
mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
-
+
if(floaterp->isDirty() || id.notNull()) // mModelView->setDirty does not work.
{
setTentative( FALSE );
@@ -1292,10 +1293,10 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLUUID id)
}
else
{
- mImageItemID = floaterp->findItemID(floaterp->getAssetID(), FALSE);
- lldebugs << "mImageItemID: " << mImageItemID << llendl;
- mImageAssetID = floaterp->getAssetID();
- lldebugs << "mImageAssetID: " << mImageAssetID << llendl;
+ mImageItemID = floaterp->findItemID(floaterp->getAssetID(), FALSE);
+ lldebugs << "mImageItemID: " << mImageItemID << llendl;
+ mImageAssetID = floaterp->getAssetID();
+ lldebugs << "mImageAssetID: " << mImageAssetID << llendl;
}
if (op == TEXTURE_SELECT && mOnSelectCallback)
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 45ca23cdfe..d81b016fc1 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -1030,12 +1030,7 @@ void CreateGestureCallback::fire(const LLUUID& inv_item)
gFloaterView->adjustToFitScreen(preview, FALSE);
}
-void AddFavoriteLandmarkCallback::fire(const LLUUID& inv_item_id)
-{
- if (mTargetLandmarkId.isNull()) return;
- gInventory.rearrangeFavoriteLandmarks(inv_item_id, mTargetLandmarkId);
-}
LLInventoryCallbackManager gInventoryCallbacks;
@@ -1308,7 +1303,7 @@ const std::string NEW_NOTECARD_NAME = "New Note"; // *TODO:Translate? (probably
const std::string NEW_GESTURE_NAME = "New Gesture"; // *TODO:Translate? (probably not)
// ! REFACTOR ! Really need to refactor this so that it's not a bunch of if-then statements...
-void menu_create_inventory_item(LLFolderView* root, LLFolderBridge *bridge, const LLSD& userdata, const LLUUID& default_parent_uuid)
+void menu_create_inventory_item(LLInventoryPanel* panel, LLFolderBridge *bridge, const LLSD& userdata, const LLUUID& default_parent_uuid)
{
std::string type_name = userdata.asString();
@@ -1332,7 +1327,7 @@ void menu_create_inventory_item(LLFolderView* root, LLFolderBridge *bridge, cons
LLUUID category = gInventory.createNewCategory(parent_id, preferred_type, LLStringUtil::null);
gInventory.notifyObservers();
- root->setSelectionByID(category, TRUE);
+ panel->setSelectionByID(category, TRUE);
}
else if ("lsl" == type_name)
{
@@ -1375,7 +1370,7 @@ void menu_create_inventory_item(LLFolderView* root, LLFolderBridge *bridge, cons
llwarns << "Can't create unrecognized type " << type_name << llendl;
}
}
- root->setNeedsAutoRename(TRUE);
+ panel->getRootFolder()->setNeedsAutoRename(TRUE);
}
LLAssetType::EType LLViewerInventoryItem::getType() const
@@ -1449,348 +1444,6 @@ const std::string& LLViewerInventoryItem::getName() const
return LLInventoryItem::getName();
}
-/**
- * Class to store sorting order of favorites landmarks in a local file. EXT-3985.
- * It replaced previously implemented solution to store sort index in landmark's name as a "<N>@" prefix.
- * Data are stored in user home directory.
- */
-class LLFavoritesOrderStorage : public LLSingleton<LLFavoritesOrderStorage>
- , public LLDestroyClass<LLFavoritesOrderStorage>
-{
- LOG_CLASS(LLFavoritesOrderStorage);
-public:
- /**
- * Sets sort index for specified with LLUUID favorite landmark
- */
- void setSortIndex(const LLUUID& inv_item_id, S32 sort_index);
-
- /**
- * Gets sort index for specified with LLUUID favorite landmark
- */
- S32 getSortIndex(const LLUUID& inv_item_id);
- void removeSortIndex(const LLUUID& inv_item_id);
-
- void getSLURL(const LLUUID& asset_id);
-
- /**
- * Implementation of LLDestroyClass. Calls cleanup() instance method.
- *
- * It is important this callback is called before gInventory is cleaned.
- * For now it is called from LLAppViewer::cleanup() -> LLAppViewer::disconnectViewer(),
- * Inventory is cleaned later from LLAppViewer::cleanup() after LLAppViewer::disconnectViewer() is called.
- * @see cleanup()
- */
- static void destroyClass();
-
- const static S32 NO_INDEX;
-private:
- friend class LLSingleton<LLFavoritesOrderStorage>;
- LLFavoritesOrderStorage() : mIsDirty(false) { load(); }
- ~LLFavoritesOrderStorage() { save(); }
-
- /**
- * Removes sort indexes for items which are not in Favorites bar for now.
- */
- void cleanup();
-
- const static std::string SORTING_DATA_FILE_NAME;
-
- void load();
- void save();
-
- void saveFavoritesSLURLs();
-
- // Remove record of current user's favorites from file on disk.
- void removeFavoritesRecordOfUser();
-
- void onLandmarkLoaded(const LLUUID& asset_id, LLLandmark* landmark);
- void storeFavoriteSLURL(const LLUUID& asset_id, std::string& slurl);
-
- typedef std::map<LLUUID, S32> sort_index_map_t;
- sort_index_map_t mSortIndexes;
-
- typedef std::map<LLUUID, std::string> slurls_map_t;
- slurls_map_t mSLURLs;
-
- bool mIsDirty;
-
- struct IsNotInFavorites
- {
- IsNotInFavorites(const LLInventoryModel::item_array_t& items)
- : mFavoriteItems(items)
- {
-
- }
-
- /**
- * Returns true if specified item is not found among inventory items
- */
- bool operator()(const sort_index_map_t::value_type& id_index_pair) const
- {
- LLPointer<LLViewerInventoryItem> item = gInventory.getItem(id_index_pair.first);
- if (item.isNull()) return true;
-
- LLInventoryModel::item_array_t::const_iterator found_it =
- std::find(mFavoriteItems.begin(), mFavoriteItems.end(), item);
-
- return found_it == mFavoriteItems.end();
- }
- private:
- LLInventoryModel::item_array_t mFavoriteItems;
- };
-
-};
-
-const std::string LLFavoritesOrderStorage::SORTING_DATA_FILE_NAME = "landmarks_sorting.xml";
-const S32 LLFavoritesOrderStorage::NO_INDEX = -1;
-
-void LLFavoritesOrderStorage::setSortIndex(const LLUUID& inv_item_id, S32 sort_index)
-{
- mSortIndexes[inv_item_id] = sort_index;
- mIsDirty = true;
-}
-
-S32 LLFavoritesOrderStorage::getSortIndex(const LLUUID& inv_item_id)
-{
- sort_index_map_t::const_iterator it = mSortIndexes.find(inv_item_id);
- if (it != mSortIndexes.end())
- {
- return it->second;
- }
- return NO_INDEX;
-}
-
-void LLFavoritesOrderStorage::removeSortIndex(const LLUUID& inv_item_id)
-{
- mSortIndexes.erase(inv_item_id);
- mIsDirty = true;
-}
-
-void LLFavoritesOrderStorage::getSLURL(const LLUUID& asset_id)
-{
- slurls_map_t::iterator slurl_iter = mSLURLs.find(asset_id);
- if (slurl_iter != mSLURLs.end()) return; // SLURL for current landmark is already cached
-
- LLLandmark* lm = gLandmarkList.getAsset(asset_id,
- boost::bind(&LLFavoritesOrderStorage::onLandmarkLoaded, this, asset_id, _1));
- if (lm)
- {
- onLandmarkLoaded(asset_id, lm);
- }
-}
-
-// static
-void LLFavoritesOrderStorage::destroyClass()
-{
- LLFavoritesOrderStorage::instance().cleanup();
- if (gSavedPerAccountSettings.getBOOL("ShowFavoritesOnLogin"))
- {
- LLFavoritesOrderStorage::instance().saveFavoritesSLURLs();
- }
- else
- {
- LLFavoritesOrderStorage::instance().removeFavoritesRecordOfUser();
- }
-}
-
-void LLFavoritesOrderStorage::load()
-{
- // load per-resident sorting information
- std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SORTING_DATA_FILE_NAME);
-
- LLSD settings_llsd;
- llifstream file;
- file.open(filename);
- if (file.is_open())
- {
- LLSDSerialize::fromXML(settings_llsd, file);
- }
-
- for (LLSD::map_const_iterator iter = settings_llsd.beginMap();
- iter != settings_llsd.endMap(); ++iter)
- {
- mSortIndexes.insert(std::make_pair(LLUUID(iter->first), (S32)iter->second.asInteger()));
- }
-}
-
-void LLFavoritesOrderStorage::saveFavoritesSLURLs()
-{
- // Do not change the file if we are not logged in yet.
- if (!LLLoginInstance::getInstance()->authSuccess())
- {
- llwarns << "Cannot save favorites: not logged in" << llendl;
- return;
- }
-
- std::string user_dir = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "");
- if (user_dir.empty())
- {
- llwarns << "Cannot save favorites: empty user dir name" << llendl;
- return;
- }
-
- std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
- llifstream in_file;
- in_file.open(filename);
- LLSD fav_llsd;
- if (in_file.is_open())
- {
- LLSDSerialize::fromXML(fav_llsd, in_file);
- }
-
- const LLUUID fav_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
- LLInventoryModel::cat_array_t cats;
- LLInventoryModel::item_array_t items;
- gInventory.collectDescendents(fav_id, cats, items, LLInventoryModel::EXCLUDE_TRASH);
-
- LLSD user_llsd;
- for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); it++)
- {
- LLSD value;
- value["name"] = (*it)->getName();
- value["asset_id"] = (*it)->getAssetUUID();
-
- slurls_map_t::iterator slurl_iter = mSLURLs.find(value["asset_id"]);
- if (slurl_iter != mSLURLs.end())
- {
- lldebugs << "Saving favorite: idx=" << (*it)->getSortField() << ", SLURL=" << slurl_iter->second << ", value=" << value << llendl;
- value["slurl"] = slurl_iter->second;
- user_llsd[(*it)->getSortField()] = value;
- }
- else
- {
- llwarns << "Not saving favorite " << value["name"] << ": no matching SLURL" << llendl;
- }
- }
-
- LLAvatarName av_name;
- LLAvatarNameCache::get( gAgentID, &av_name );
- lldebugs << "Saved favorites for " << av_name.getLegacyName() << llendl;
- fav_llsd[av_name.getLegacyName()] = user_llsd;
-
- llofstream file;
- file.open(filename);
- LLSDSerialize::toPrettyXML(fav_llsd, file);
-}
-
-void LLFavoritesOrderStorage::removeFavoritesRecordOfUser()
-{
- std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
- LLSD fav_llsd;
- llifstream file;
- file.open(filename);
- if (!file.is_open()) return;
- LLSDSerialize::fromXML(fav_llsd, file);
-
- LLAvatarName av_name;
- LLAvatarNameCache::get( gAgentID, &av_name );
- lldebugs << "Removed favorites for " << av_name.getLegacyName() << llendl;
- if (fav_llsd.has(av_name.getLegacyName()))
- {
- fav_llsd.erase(av_name.getLegacyName());
- }
-
- llofstream out_file;
- out_file.open(filename);
- LLSDSerialize::toPrettyXML(fav_llsd, out_file);
-
-}
-
-void LLFavoritesOrderStorage::onLandmarkLoaded(const LLUUID& asset_id, LLLandmark* landmark)
-{
- if (!landmark) return;
-
- LLVector3d pos_global;
- if (!landmark->getGlobalPos(pos_global))
- {
- // If global position was unknown on first getGlobalPos() call
- // it should be set for the subsequent calls.
- landmark->getGlobalPos(pos_global);
- }
-
- if (!pos_global.isExactlyZero())
- {
- LLLandmarkActions::getSLURLfromPosGlobal(pos_global,
- boost::bind(&LLFavoritesOrderStorage::storeFavoriteSLURL, this, asset_id, _1));
- }
-}
-
-void LLFavoritesOrderStorage::storeFavoriteSLURL(const LLUUID& asset_id, std::string& slurl)
-{
- lldebugs << "Saving landmark SLURL: " << slurl << llendl;
- mSLURLs[asset_id] = slurl;
-}
-
-void LLFavoritesOrderStorage::save()
-{
- // nothing to save if clean
- if (!mIsDirty) return;
-
- // If we quit from the login screen we will not have an SL account
- // name. Don't try to save, otherwise we'll dump a file in
- // C:\Program Files\SecondLife\ or similar. JC
- std::string user_dir = gDirUtilp->getLindenUserDir();
- if (!user_dir.empty())
- {
- std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SORTING_DATA_FILE_NAME);
- LLSD settings_llsd;
-
- for(sort_index_map_t::const_iterator iter = mSortIndexes.begin(); iter != mSortIndexes.end(); ++iter)
- {
- settings_llsd[iter->first.asString()] = iter->second;
- }
-
- llofstream file;
- file.open(filename);
- LLSDSerialize::toPrettyXML(settings_llsd, file);
- }
-}
-
-void LLFavoritesOrderStorage::cleanup()
-{
- // nothing to clean
- if (!mIsDirty) return;
-
- const LLUUID fav_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
- LLInventoryModel::cat_array_t cats;
- LLInventoryModel::item_array_t items;
- gInventory.collectDescendents(fav_id, cats, items, LLInventoryModel::EXCLUDE_TRASH);
-
- IsNotInFavorites is_not_in_fav(items);
-
- sort_index_map_t aTempMap;
- //copy unremoved values from mSortIndexes to aTempMap
- std::remove_copy_if(mSortIndexes.begin(), mSortIndexes.end(),
- inserter(aTempMap, aTempMap.begin()),
- is_not_in_fav);
-
- //Swap the contents of mSortIndexes and aTempMap
- mSortIndexes.swap(aTempMap);
-}
-
-
-S32 LLViewerInventoryItem::getSortField() const
-{
- return LLFavoritesOrderStorage::instance().getSortIndex(mUUID);
-}
-
-void LLViewerInventoryItem::setSortField(S32 sortField)
-{
- LLFavoritesOrderStorage::instance().setSortIndex(mUUID, sortField);
- getSLURL();
-}
-
-void LLViewerInventoryItem::getSLURL()
-{
- LLFavoritesOrderStorage::instance().getSLURL(mAssetUUID);
-}
-
-const LLPermissions& LLViewerInventoryItem::getPermissions() const
-{
- // Use the actual permissions of the symlink, not its parent.
- return LLInventoryItem::getPermissions();
-}
-
const LLUUID& LLViewerInventoryItem::getCreatorUUID() const
{
if (const LLViewerInventoryItem *linked_item = getLinkedItem())
@@ -1861,17 +1514,6 @@ LLWearableType::EType LLViewerInventoryItem::getWearableType() const
return LLWearableType::EType(getFlags() & LLInventoryItemFlags::II_FLAGS_WEARABLES_MASK);
}
-
-time_t LLViewerInventoryItem::getCreationDate() const
-{
- return LLInventoryItem::getCreationDate();
-}
-
-U32 LLViewerInventoryItem::getCRC32() const
-{
- return LLInventoryItem::getCRC32();
-}
-
// *TODO: mantipov: should be removed with LMSortPrefix patch in llinventorymodel.cpp, EXT-3985
static char getSeparator() { return '@'; }
BOOL LLViewerInventoryItem::extractSortFieldAndDisplayName(const std::string& name, S32* sortField, std::string* displayName)
diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h
index 7822ef4da6..3cf03c3bc5 100644
--- a/indra/newview/llviewerinventory.h
+++ b/indra/newview/llviewerinventory.h
@@ -34,7 +34,7 @@
#include <boost/signals2.hpp> // boost::signals2::trackable
-class LLFolderView;
+class LLInventoryPanel;
class LLFolderBridge;
class LLViewerInventoryCategory;
@@ -60,10 +60,6 @@ public:
virtual const LLUUID& getAssetUUID() const;
virtual const LLUUID& getProtectedAssetUUID() const; // returns LLUUID::null if current agent does not have permission to expose this asset's UUID to the user
virtual const std::string& getName() const;
- virtual S32 getSortField() const;
- virtual void setSortField(S32 sortField);
- virtual void getSLURL(); //Caches SLURL for landmark. //*TODO: Find a better way to do it and remove this method from here.
- virtual const LLPermissions& getPermissions() const;
virtual const bool getIsFullPerm() const; // 'fullperm' in the popular sense: modify-ok & copy-ok & transfer-ok, no special god rules applied
virtual const LLUUID& getCreatorUUID() const;
virtual const std::string& getDescription() const;
@@ -72,8 +68,11 @@ public:
virtual bool isWearableType() const;
virtual LLWearableType::EType getWearableType() const;
virtual U32 getFlags() const;
- virtual time_t getCreationDate() const;
- virtual U32 getCRC32() const; // really more of a checksum.
+
+ using LLInventoryItem::getPermissions;
+ using LLInventoryItem::getCreationDate;
+ using LLInventoryItem::setCreationDate;
+ using LLInventoryItem::getCRC32;
static BOOL extractSortFieldAndDisplayName(const std::string& name, S32* sortField, std::string* displayName);
@@ -285,18 +284,6 @@ public:
void fire(const LLUUID& inv_item);
};
-class AddFavoriteLandmarkCallback : public LLInventoryCallback
-{
-public:
- AddFavoriteLandmarkCallback() : mTargetLandmarkId(LLUUID::null) {}
- void setTargetLandmarkId(const LLUUID& target_uuid) { mTargetLandmarkId = target_uuid; }
-
-private:
- void fire(const LLUUID& inv_item);
-
- LLUUID mTargetLandmarkId;
-};
-
// misc functions
//void inventory_reliable_callback(void**, S32 status);
@@ -372,7 +359,7 @@ void copy_inventory_from_notecard(const LLUUID& destination_id,
U32 callback_id = 0);
-void menu_create_inventory_item(LLFolderView* root,
+void menu_create_inventory_item(LLInventoryPanel* root,
LLFolderBridge* bridge,
const LLSD& userdata,
const LLUUID& default_parent_uuid = LLUUID::null);
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 7e1f186769..03c113ecb3 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -728,7 +728,7 @@ static void highlight_inventory_objects_in_panel(const std::vector<LLUUID>& item
LLFolderView* fv = inventory_panel->getRootFolder();
if (fv)
{
- LLFolderViewItem* fv_item = fv->getItemByID(item_id);
+ LLFolderViewItem* fv_item = inventory_panel->getItemByID(item_id);
if (fv_item)
{
LLFolderViewItem* fv_folder = fv_item->getParentFolder();
@@ -816,7 +816,13 @@ private:
mSelectedItems.clear();
if (LLInventoryPanel::getActiveInventoryPanel())
{
- mSelectedItems = LLInventoryPanel::getActiveInventoryPanel()->getRootFolder()->getSelectionList();
+ std::set<LLFolderViewItem*> selection = LLInventoryPanel::getActiveInventoryPanel()->getRootFolder()->getSelectionList();
+ for (std::set<LLFolderViewItem*>::iterator it = selection.begin(), end_it = selection.end();
+ it != end_it;
+ ++it)
+ {
+ mSelectedItems.insert(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID());
+ }
}
mSelectedItems.erase(mMoveIntoFolderID);
}
@@ -851,7 +857,15 @@ private:
}
// get selected items (without destination folder)
- selected_items_t selected_items = active_panel->getRootFolder()->getSelectionList();
+ selected_items_t selected_items;
+
+ std::set<LLFolderViewItem*> selection = LLInventoryPanel::getActiveInventoryPanel()->getRootFolder()->getSelectionList();
+ for (std::set<LLFolderViewItem*>::iterator it = selection.begin(), end_it = selection.end();
+ it != end_it;
+ ++it)
+ {
+ selected_items.insert(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID());
+ }
selected_items.erase(mMoveIntoFolderID);
// compare stored & current sets of selected items