From a2626f0ee8c723781419ae9722e52872c754e0ba Mon Sep 17 00:00:00 2001 From: Seth ProductEngine Date: Thu, 26 Jan 2012 01:41:14 +0200 Subject: EXP-1335 FIXED Enabled DnD and sorting items in Recent tab of My inventory. Added filtering the items on DnD, allowing to drop only the items which pass the filter in the destinatination inventory panel. Added filtering the items from object contents and notecards. Changed handle type for LLInventoryPanel in LLInvFVBridge to remove some extra dynamic casts. --- indra/newview/llinventorybridge.cpp | 74 +++++++++++++++++++++++++++++-------- 1 file changed, 59 insertions(+), 15 deletions(-) (limited to 'indra/newview/llinventorybridge.cpp') diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index c0065a94e6..ff321f77fd 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -148,7 +148,7 @@ LLInvFVBridge::LLInvFVBridge(LLInventoryPanel* inventory, mInvType(LLInventoryType::IT_NONE), mIsLink(FALSE) { - mInventoryPanel = inventory->getHandle(); + mInventoryPanel = inventory->getInventoryPanelHandle(); const LLInventoryObject* obj = getInventoryObject(); mIsLink = obj && obj->getIsLinkType(); } @@ -798,7 +798,7 @@ LLInventoryObject* LLInvFVBridge::getInventoryObject() const LLInventoryModel* LLInvFVBridge::getInventoryModel() const { - LLInventoryPanel* panel = dynamic_cast(mInventoryPanel.get()); + LLInventoryPanel* panel = mInventoryPanel.get(); return panel ? panel->getModel() : NULL; } @@ -1738,7 +1738,7 @@ BOOL LLFolderBridge::isItemRemovable() const return FALSE; } - LLInventoryPanel* panel = dynamic_cast(mInventoryPanel.get()); + LLInventoryPanel* panel = mInventoryPanel.get(); LLFolderViewFolder* folderp = dynamic_cast(panel ? panel->getRootFolder()->getItemByID(mUUID) : NULL); if (folderp) { @@ -3290,7 +3290,7 @@ void LLFolderBridge::createNewCategory(void* user_data) { LLFolderBridge* bridge = (LLFolderBridge*)user_data; if(!bridge) return; - LLInventoryPanel* panel = dynamic_cast(bridge->mInventoryPanel.get()); + LLInventoryPanel* panel = bridge->mInventoryPanel.get(); if (!panel) return; LLInventoryModel* model = panel->getModel(); if(!model) return; @@ -3470,7 +3470,7 @@ void LLFolderBridge::dropToFavorites(LLInventoryItem* inv_item) // use callback to rearrange favorite landmarks after adding // to have new one placed before target (on which it was dropped). See EXT-4312. LLPointer cb = new AddFavoriteLandmarkCallback(); - LLInventoryPanel* panel = dynamic_cast(mInventoryPanel.get()); + LLInventoryPanel* panel = mInventoryPanel.get(); LLFolderViewItem* drag_over_item = panel ? panel->getRootFolder()->getDraggingOverItem() : NULL; if (drag_over_item && drag_over_item->getListener()) { @@ -3520,6 +3520,12 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, if (!isAgentInventory()) return FALSE; // cannot drag into library if (!isAgentAvatarValid()) return FALSE; + LLInventoryPanel* destination_panel = mInventoryPanel.get(); + if (!destination_panel) return false; + + LLInventoryFilter* filter = destination_panel->getFilter(); + if (!filter) return false; + const LLUUID ¤t_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false); const LLUUID &favorites_id = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE, false); const LLUUID &landmarks_id = model->findCategoryUUIDForType(LLFolderType::FT_LANDMARK, false); @@ -3628,6 +3634,21 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, } } + LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); + + // Check whether the item being dragged from active inventory panel + // passes the filter of the destination panel. + if (accept && active_panel) + { + LLFolderView* active_folder_viev = active_panel->getRootFolder(); + if (!active_folder_viev) return false; + + LLFolderViewItem* fv_item = active_folder_viev->getItemByID(inv_item->getUUID()); + if (!fv_item) return false; + + accept = filter->check(fv_item); + } + if (accept && drop) { if (inv_item->getType() == LLAssetType::AT_GESTURE @@ -3637,14 +3658,9 @@ 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). - LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); - if (active_panel) + if (active_panel && (destination_panel != active_panel)) { - LLInventoryPanel* panel = dynamic_cast(mInventoryPanel.get()); - if (active_panel && (panel != active_panel)) - { - active_panel->unSelectAll(); - } + active_panel->unSelectAll(); } //-------------------------------------------------------------------------------- @@ -3655,8 +3671,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, // (only reorder the item in Favorites folder) if ((mUUID == inv_item->getParentUUID()) && move_is_into_favorites) { - LLInventoryPanel* panel = dynamic_cast(mInventoryPanel.get()); - LLFolderViewItem* itemp = panel ? panel->getRootFolder()->getDraggingOverItem() : NULL; + LLFolderViewItem* itemp = destination_panel->getRootFolder()->getDraggingOverItem(); if (itemp) { LLUUID srcItemId = inv_item->getUUID(); @@ -3760,6 +3775,13 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, accept = FALSE; } + // Check whether the item being dragged from in world + // passes the filter of the destination panel. + if (accept) + { + accept = filter->check(inv_item); + } + if (accept && drop) { LLMoveInv* move_inv = new LLMoveInv; @@ -3797,6 +3819,13 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, accept = !(move_is_into_current_outfit || move_is_into_outfit); } + // Check whether the item being dragged from notecard + // passes the filter of the destination panel. + if (accept) + { + accept = filter->check(inv_item); + } + if (accept && drop) { copy_inventory_from_notecard(mUUID, // Drop to the chosen destination folder @@ -3828,6 +3857,21 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, accept = can_move_to_landmarks(inv_item); } + LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); + + // Check whether the item being dragged from the library + // passes the filter of the destination panel. + if (accept && active_panel) + { + LLFolderView* active_folder_viev = active_panel->getRootFolder(); + if (!active_folder_viev) return false; + + LLFolderViewItem* fv_item = active_folder_viev->getItemByID(inv_item->getUUID()); + if (!fv_item) return false; + + accept = filter->check(fv_item); + } + if (accept && drop) { // FAVORITES folder @@ -4184,7 +4228,7 @@ LLCallingCardBridge::~LLCallingCardBridge() void LLCallingCardBridge::refreshFolderViewItem() { - LLInventoryPanel* panel = dynamic_cast(mInventoryPanel.get()); + LLInventoryPanel* panel = mInventoryPanel.get(); LLFolderViewItem* itemp = panel ? panel->getRootFolder()->getItemByID(mUUID) : NULL; if (itemp) { -- cgit v1.3 From ce9ff40c64929cef8c8f422723ce631735774c9a Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 26 Jan 2012 12:11:22 -0800 Subject: EXP-1844 FIX Selecting a large number of inventory items can block the viewer for a long time. --- indra/newview/llinventorybridge.cpp | 3 +- indra/newview/llinventorymodelbackgroundfetch.cpp | 283 +++++++++++++++------- indra/newview/llinventorymodelbackgroundfetch.h | 16 +- 3 files changed, 205 insertions(+), 97 deletions(-) (limited to 'indra/newview/llinventorybridge.cpp') diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index ff321f77fd..869cb735d5 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -1324,8 +1324,7 @@ void LLItemBridge::selectItem() LLViewerInventoryItem* item = static_cast(getItem()); if(item && !item->isFinished()) { - item->fetchFromServer(); - //LLInventoryModelBackgroundFetch::instance().start(item->getUUID(), false); + LLInventoryModelBackgroundFetch::instance().start(item->getUUID(), false); } } diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 91fdd67806..cb140cf15c 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -50,7 +50,7 @@ LLInventoryModelBackgroundFetch::LLInventoryModelBackgroundFetch() : mMinTimeBetweenFetches(0.3f), mMaxTimeBetweenFetches(10.f), mTimelyFetchPending(FALSE), - mBulkFetchCount(0) + mFetchCount(0) { } @@ -60,7 +60,7 @@ LLInventoryModelBackgroundFetch::~LLInventoryModelBackgroundFetch() bool LLInventoryModelBackgroundFetch::isBulkFetchProcessingComplete() const { - return mFetchQueue.empty() && mBulkFetchCount<=0; + return mFetchQueue.empty() && mFetchCount<=0; } bool LLInventoryModelBackgroundFetch::libraryFetchStarted() const @@ -103,14 +103,15 @@ BOOL LLInventoryModelBackgroundFetch::backgroundFetchActive() const return mBackgroundFetchActive; } -void LLInventoryModelBackgroundFetch::start(const LLUUID& cat_id, BOOL recursive) +void LLInventoryModelBackgroundFetch::start(const LLUUID& id, BOOL recursive) { - if (!mAllFoldersFetched || cat_id.notNull()) - { - LL_DEBUGS("InventoryFetch") << "Start fetching category: " << cat_id << ", recursive: " << recursive << LL_ENDL; + LLViewerInventoryCategory* cat = gInventory.getCategory(id); + if (cat || (id.isNull() && !mAllFoldersFetched)) + { // it's a folder, do a bulk fetch + LL_DEBUGS("InventoryFetch") << "Start fetching category: " << id << ", recursive: " << recursive << LL_ENDL; mBackgroundFetchActive = TRUE; - if (cat_id.isNull()) + if (id.isNull()) { if (!mRecursiveInventoryFetchStarted) { @@ -128,21 +129,31 @@ void LLInventoryModelBackgroundFetch::start(const LLUUID& cat_id, BOOL recursive else { // Specific folder requests go to front of queue. - if (mFetchQueue.empty() || mFetchQueue.front().mCatUUID != cat_id) + if (mFetchQueue.empty() || mFetchQueue.front().mUUID != id) { - mFetchQueue.push_front(FetchQueueInfo(cat_id, recursive)); + mFetchQueue.push_front(FetchQueueInfo(id, recursive)); gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } - if (cat_id == gInventory.getLibraryRootFolderID()) + if (id == gInventory.getLibraryRootFolderID()) { mRecursiveLibraryFetchStarted |= recursive; } - if (cat_id == gInventory.getRootFolderID()) + if (id == gInventory.getRootFolderID()) { mRecursiveInventoryFetchStarted |= recursive; } } } + else if (LLViewerInventoryItem* itemp = gInventory.getItem(id)) + { + if (!itemp->mIsComplete && (mFetchQueue.empty() || mFetchQueue.front().mUUID != id)) + { + mBackgroundFetchActive = TRUE; + + mFetchQueue.push_front(FetchQueueInfo(id, false, false)); + gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); + } + } } void LLInventoryModelBackgroundFetch::findLostItems() @@ -158,7 +169,7 @@ void LLInventoryModelBackgroundFetch::stopBackgroundFetch() { mBackgroundFetchActive = FALSE; gIdleCallbacks.deleteFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); - mBulkFetchCount=0; + mFetchCount=0; mMinTimeBetweenFetches=0.0f; } } @@ -183,10 +194,9 @@ void LLInventoryModelBackgroundFetch::backgroundFetch() if (mBackgroundFetchActive && gAgent.getRegion()) { // If we'll be using the capability, we'll be sending batches and the background thing isn't as important. - std::string url = gAgent.getRegion()->getCapability("FetchInventoryDescendents2"); - if (gSavedSettings.getBOOL("UseHTTPInventory") && !url.empty()) + if (gSavedSettings.getBOOL("UseHTTPInventory")) { - bulkFetch(url); + bulkFetch(); return; } @@ -230,7 +240,7 @@ void LLInventoryModelBackgroundFetch::backgroundFetch() } const FetchQueueInfo info = mFetchQueue.front(); - LLViewerInventoryCategory* cat = gInventory.getCategory(info.mCatUUID); + LLViewerInventoryCategory* cat = gInventory.getCategory(info.mUUID); // Category has been deleted, remove from queue. if (!cat) @@ -258,7 +268,7 @@ void LLInventoryModelBackgroundFetch::backgroundFetch() } } // Do I have all my children? - else if (gInventory.isCategoryComplete(info.mCatUUID)) + else if (gInventory.isCategoryComplete(info.mUUID)) { // Finished with this category, remove from queue. mFetchQueue.pop_front(); @@ -313,15 +323,35 @@ void LLInventoryModelBackgroundFetch::backgroundFetch() } } -void LLInventoryModelBackgroundFetch::incrBulkFetch(S16 fetching) +void LLInventoryModelBackgroundFetch::incrFetchCount(S16 fetching) { - mBulkFetchCount += fetching; - if (mBulkFetchCount < 0) + mFetchCount += fetching; + if (mFetchCount < 0) { - mBulkFetchCount = 0; + mFetchCount = 0; } } +class LLInventoryModelFetchItemResponder : public LLInventoryModel::fetchInventoryResponder +{ +public: + LLInventoryModelFetchItemResponder(const LLSD& request_sd) : LLInventoryModel::fetchInventoryResponder(request_sd) {}; + void result(const LLSD& content); + void error(U32 status, const std::string& reason); +}; + +void LLInventoryModelFetchItemResponder::result( const LLSD& content ) +{ + LLInventoryModel::fetchInventoryResponder::result(content); + LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1); +} + +void LLInventoryModelFetchItemResponder::error( U32 status, const std::string& reason ) +{ + LLInventoryModel::fetchInventoryResponder::error(status, reason); + LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1); +} + class LLInventoryModelFetchDescendentsResponder: public LLHTTPClient::Responder { @@ -458,7 +488,7 @@ void LLInventoryModelFetchDescendentsResponder::result(const LLSD& content) } } - fetcher->incrBulkFetch(-1); + fetcher->incrFetchCount(-1); if (fetcher->isBulkFetchProcessingComplete()) { @@ -477,7 +507,7 @@ void LLInventoryModelFetchDescendentsResponder::error(U32 status, const std::str llinfos << "LLInventoryModelFetchDescendentsResponder::error " << status << ": " << reason << llendl; - fetcher->incrBulkFetch(-1); + fetcher->incrFetchCount(-1); if (status==499) // timed out { @@ -508,12 +538,14 @@ BOOL LLInventoryModelFetchDescendentsResponder::getIsRecursive(const LLUUID& cat // Bundle up a bunch of requests to send all at once. // static -void LLInventoryModelBackgroundFetch::bulkFetch(std::string url) +void LLInventoryModelBackgroundFetch::bulkFetch() { //Background fetch is called from gIdleCallbacks in a loop until background fetch is stopped. //If there are items in mFetchQueue, we want to check the time since the last bulkFetch was //sent. If it exceeds our retry time, go ahead and fire off another batch. //Stopbackgroundfetch will be run from the Responder instead of here. + LLViewerRegion* region = gAgent.getRegion(); + if (!region) return; S16 max_concurrent_fetches=8; F32 new_min_time = 0.5f; //HACK! Clean this up when old code goes away entirely. @@ -523,12 +555,13 @@ void LLInventoryModelBackgroundFetch::bulkFetch(std::string url) } if (gDisconnected || - (mBulkFetchCount > max_concurrent_fetches) || + (mFetchCount > max_concurrent_fetches) || (mFetchTimer.getElapsedTimeF32() < mMinTimeBetweenFetches)) { return; // just bail if we are disconnected } + U32 item_count=0; U32 folder_count=0; U32 max_batch_size=5; @@ -536,83 +569,159 @@ void LLInventoryModelBackgroundFetch::bulkFetch(std::string url) uuid_vec_t recursive_cats; - LLSD body; - LLSD body_lib; + LLSD folder_request_body; + LLSD folder_request_body_lib; + LLSD item_request_body; + LLSD item_request_body_lib; - while (!(mFetchQueue.empty()) && (folder_count < max_batch_size)) + while (!(mFetchQueue.empty()) && ((item_count + folder_count) < max_batch_size)) { const FetchQueueInfo& fetch_info = mFetchQueue.front(); - const LLUUID &cat_id = fetch_info.mCatUUID; - if (cat_id.isNull()) //DEV-17797 - { - LLSD folder_sd; - folder_sd["folder_id"] = LLUUID::null.asString(); - folder_sd["owner_id"] = gAgent.getID(); - folder_sd["sort_order"] = (LLSD::Integer)sort_order; - folder_sd["fetch_folders"] = (LLSD::Boolean)FALSE; - folder_sd["fetch_items"] = (LLSD::Boolean)TRUE; - body["folders"].append(folder_sd); - folder_count++; - } - else - { - const LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id); + if (fetch_info.mIsCategory) + { + + const LLUUID &cat_id = fetch_info.mUUID; + if (cat_id.isNull()) //DEV-17797 + { + LLSD folder_sd; + folder_sd["folder_id"] = LLUUID::null.asString(); + folder_sd["owner_id"] = gAgent.getID(); + folder_sd["sort_order"] = (LLSD::Integer)sort_order; + folder_sd["fetch_folders"] = (LLSD::Boolean)FALSE; + folder_sd["fetch_items"] = (LLSD::Boolean)TRUE; + folder_request_body["folders"].append(folder_sd); + folder_count++; + } + else + { + const LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id); - if (cat) - { - if (LLViewerInventoryCategory::VERSION_UNKNOWN == cat->getVersion()) - { - LLSD folder_sd; - folder_sd["folder_id"] = cat->getUUID(); - folder_sd["owner_id"] = cat->getOwnerID(); - folder_sd["sort_order"] = (LLSD::Integer)sort_order; - folder_sd["fetch_folders"] = TRUE; //(LLSD::Boolean)sFullFetchStarted; - folder_sd["fetch_items"] = (LLSD::Boolean)TRUE; - - if (ALEXANDRIA_LINDEN_ID == cat->getOwnerID()) - body_lib["folders"].append(folder_sd); - else - body["folders"].append(folder_sd); - folder_count++; - } - // May already have this folder, but append child folders to list. - if (fetch_info.mRecursive) - { - LLInventoryModel::cat_array_t* categories; - LLInventoryModel::item_array_t* items; - gInventory.getDirectDescendentsOf(cat->getUUID(), categories, items); - for (LLInventoryModel::cat_array_t::const_iterator it = categories->begin(); - it != categories->end(); - ++it) + if (cat) + { + if (LLViewerInventoryCategory::VERSION_UNKNOWN == cat->getVersion()) { - mFetchQueue.push_back(FetchQueueInfo((*it)->getUUID(), fetch_info.mRecursive)); - } - } - } - } - if (fetch_info.mRecursive) - recursive_cats.push_back(cat_id); + LLSD folder_sd; + folder_sd["folder_id"] = cat->getUUID(); + folder_sd["owner_id"] = cat->getOwnerID(); + folder_sd["sort_order"] = (LLSD::Integer)sort_order; + folder_sd["fetch_folders"] = TRUE; //(LLSD::Boolean)sFullFetchStarted; + folder_sd["fetch_items"] = (LLSD::Boolean)TRUE; + + if (ALEXANDRIA_LINDEN_ID == cat->getOwnerID()) + folder_request_body_lib["folders"].append(folder_sd); + else + folder_request_body["folders"].append(folder_sd); + folder_count++; + } + // May already have this folder, but append child folders to list. + if (fetch_info.mRecursive) + { + LLInventoryModel::cat_array_t* categories; + LLInventoryModel::item_array_t* items; + gInventory.getDirectDescendentsOf(cat->getUUID(), categories, items); + for (LLInventoryModel::cat_array_t::const_iterator it = categories->begin(); + it != categories->end(); + ++it) + { + mFetchQueue.push_back(FetchQueueInfo((*it)->getUUID(), fetch_info.mRecursive)); + } + } + } + } + if (fetch_info.mRecursive) + recursive_cats.push_back(cat_id); + } + else + { + LLViewerInventoryItem* itemp = gInventory.getItem(fetch_info.mUUID); + if (itemp) + { + LLSD item_sd; + item_sd["owner_id"] = itemp->getPermissions().getOwner(); + item_sd["item_id"] = itemp->getUUID(); + if (itemp->getPermissions().getOwner() == gAgent.getID()) + { + item_request_body.append(item_sd); + } + else + { + item_request_body_lib.append(item_sd); + } + //itemp->fetchFromServer(); + item_count++; + } + } mFetchQueue.pop_front(); } - if (folder_count > 0) + if (item_count + folder_count > 0) { - mBulkFetchCount++; - if (body["folders"].size()) + if (folder_count) { - LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(body, recursive_cats); - LLHTTPClient::post(url, body, fetcher, 300.0); + std::string url = region->getCapability("FetchInventoryDescendents2"); + mFetchCount++; + if (folder_request_body["folders"].size()) + { + LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body, recursive_cats); + LLHTTPClient::post(url, folder_request_body, fetcher, 300.0); + } + if (folder_request_body_lib["folders"].size()) + { + std::string url_lib = gAgent.getRegion()->getCapability("FetchLibDescendents2"); + + LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body_lib, recursive_cats); + LLHTTPClient::post(url_lib, folder_request_body_lib, fetcher, 300.0); + } } - if (body_lib["folders"].size()) + if (item_count) { - std::string url_lib = gAgent.getRegion()->getCapability("FetchLibDescendents2"); - - LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(body_lib, recursive_cats); - LLHTTPClient::post(url_lib, body_lib, fetcher, 300.0); + std::string url; + + if (item_request_body.size()) + { + mFetchCount++; + url = region->getCapability("FetchInventory2"); + if (!url.empty()) + { + LLSD body; + body["agent_id"] = gAgent.getID(); + body["items"] = item_request_body; + + LLHTTPClient::post(url, body, new LLInventoryModelFetchItemResponder(body)); + } + //else + //{ + // LLMessageSystem* msg = gMessageSystem; + // msg->newMessage("FetchInventory"); + // msg->nextBlock("AgentData"); + // msg->addUUID("AgentID", gAgent.getID()); + // msg->addUUID("SessionID", gAgent.getSessionID()); + // msg->nextBlock("InventoryData"); + // msg->addUUID("OwnerID", mPermissions.getOwner()); + // msg->addUUID("ItemID", mUUID); + // gAgent.sendReliableMessage(); + //} + } + + if (item_request_body_lib.size()) + { + mFetchCount++; + + url = region->getCapability("FetchLib2"); + if (!url.empty()) + { + LLSD body; + body["agent_id"] = gAgent.getID(); + body["items"] = item_request_body_lib; + + LLHTTPClient::post(url, body, new LLInventoryModelFetchItemResponder(body)); + } + } } mFetchTimer.reset(); } + else if (isBulkFetchProcessingComplete()) { setAllFoldersFetched(); @@ -624,7 +733,7 @@ bool LLInventoryModelBackgroundFetch::fetchQueueContainsNoDescendentsOf(const LL for (fetch_queue_t::const_iterator it = mFetchQueue.begin(); it != mFetchQueue.end(); ++it) { - const LLUUID& fetch_id = (*it).mCatUUID; + const LLUUID& fetch_id = (*it).mUUID; if (gInventory.isObjectDescendentOf(fetch_id, cat_id)) return false; } diff --git a/indra/newview/llinventorymodelbackgroundfetch.h b/indra/newview/llinventorymodelbackgroundfetch.h index c35c785ceb..0745407a8c 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.h +++ b/indra/newview/llinventorymodelbackgroundfetch.h @@ -60,10 +60,10 @@ public: bool inventoryFetchInProgress() const; void findLostItems(); + void incrFetchCount(S16 fetching); protected: - void incrBulkFetch(S16 fetching); bool isBulkFetchProcessingComplete() const; - void bulkFetch(std::string url); + void bulkFetch(); void backgroundFetch(); static void backgroundFetchCB(void*); // background fetch idle function @@ -77,7 +77,7 @@ private: BOOL mAllFoldersFetched; BOOL mBackgroundFetchActive; - S16 mBulkFetchCount; + S16 mFetchCount; BOOL mTimelyFetchPending; S32 mNumFetchRetries; @@ -87,11 +87,11 @@ private: struct FetchQueueInfo { - FetchQueueInfo(const LLUUID& id, BOOL recursive) : - mCatUUID(id), mRecursive(recursive) - { - } - LLUUID mCatUUID; + FetchQueueInfo(const LLUUID& id, BOOL recursive, bool is_category = true) : + mUUID(id), mRecursive(recursive), mIsCategory(is_category) + {} + LLUUID mUUID; + bool mIsCategory; BOOL mRecursive; }; typedef std::deque fetch_queue_t; -- cgit v1.3 From c1e47e0acab0d82ae25d65d64ac22afca6f2bd12 Mon Sep 17 00:00:00 2001 From: Leslie Linden Date: Thu, 2 Feb 2012 12:22:00 -0800 Subject: EXP-1856 FIX -- Calling cards, library items, 'no transfer' objects can be copied to Merchant outbox via ctrl-v * Viewer now applies the same logic as inventory drag and drop to clipboard paste operations. --- indra/newview/llinventorybridge.cpp | 63 ++++++++++++++++++++++++++++++++++--- indra/newview/lltooldraganddrop.cpp | 17 +++++----- indra/newview/lltooldraganddrop.h | 9 ++++-- 3 files changed, 74 insertions(+), 15 deletions(-) (limited to 'indra/newview/llinventorybridge.cpp') diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 869cb735d5..76576f7b75 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -2095,7 +2095,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, // NOTE: The cargo id's count is a total of categories AND items but we err on the side of // prevention rather than letting too many folders into the hierarchy of the outbox, // when we're dragging the item to a new parent - dragged_folder_count += LLToolDragAndDrop::instance().getCargoIDsCount(); + dragged_folder_count += LLToolDragAndDrop::instance().getCargoCount(); } } @@ -2819,18 +2819,62 @@ void LLFolderBridge::pasteFromClipboard() if(model && isClipboardPasteable()) { const LLUUID ¤t_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false); + const LLUUID &outbox_id = model->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false); + const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id); const BOOL move_is_into_outfit = (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT); - - const LLUUID parent_id(mUUID); + const BOOL move_is_into_outbox = model->isObjectDescendentOf(mUUID, outbox_id); LLDynamicArray objects; LLInventoryClipboard::instance().retrieve(objects); + + if (move_is_into_outbox) + { + LLFolderViewItem * outbox_itemp = mRoot->getItemByID(mUUID); + + if (outbox_itemp) + { + LLToolDragAndDrop::instance().setCargoCount(objects.size()); + + BOOL can_list = TRUE; + + for (LLDynamicArray::const_iterator iter = objects.begin(); + (iter != objects.end()) && (can_list == TRUE); + ++iter) + { + const LLUUID& item_id = (*iter); + LLInventoryItem *item = model->getItem(item_id); + + if (item) + { + MASK mask = 0x0; + BOOL drop = FALSE; + EDragAndDropType cargo_type = LLViewerAssetType::lookupDragAndDropType(item->getActualType()); + void * cargo_data = (void *) item; + std::string tooltip_msg; + + can_list = outbox_itemp->getListener()->dragOrDrop(mask, drop, cargo_type, cargo_data, tooltip_msg); + } + } + + LLToolDragAndDrop::instance().resetCargoCount(); + + if (can_list == FALSE) + { + // Notify user of failure somehow -- play error sound? modal dialog? + return; + } + } + } + + const LLUUID parent_id(mUUID); + for (LLDynamicArray::const_iterator iter = objects.begin(); iter != objects.end(); ++iter) { const LLUUID& item_id = (*iter); + LLInventoryItem *item = model->getItem(item_id); if (item) { @@ -2873,8 +2917,17 @@ void LLFolderBridge::pasteLinkFromClipboard() if(model) { const LLUUID ¤t_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false); + const LLUUID &outbox_id = model->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false); + const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id); const BOOL move_is_into_outfit = (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT); + const BOOL move_is_into_outbox = model->isObjectDescendentOf(mUUID, outbox_id); + + if (move_is_into_outbox) + { + // Notify user of failure somehow -- play error sound? modal dialog? + return; + } const LLUUID parent_id(mUUID); @@ -3534,7 +3587,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, const BOOL move_is_into_favorites = (mUUID == favorites_id); const BOOL move_is_into_outfit = (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT); const BOOL move_is_into_landmarks = (mUUID == landmarks_id) || model->isObjectDescendentOf(mUUID, landmarks_id); - const BOOL move_is_into_outbox = model->isObjectDescendentOf(mUUID, outbox_id); //(mUUID == outbox_id); + const BOOL move_is_into_outbox = model->isObjectDescendentOf(mUUID, outbox_id); const BOOL move_is_from_outbox = model->isObjectDescendentOf(inv_item->getUUID(), outbox_id); LLToolDragAndDrop::ESource source = LLToolDragAndDrop::getInstance()->getSource(); @@ -3613,7 +3666,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, { const LLViewerInventoryCategory * master_folder = model->getFirstDescendantOf(outbox_id, mUUID); - int existing_item_count = LLToolDragAndDrop::instance().getCargoIDsCount(); + int existing_item_count = LLToolDragAndDrop::instance().getCargoCount(); if (master_folder != NULL) { diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 8c32dfcb4d..c7ab934f9e 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -333,14 +333,15 @@ LLToolDragAndDrop::LLDragAndDropDictionary::LLDragAndDropDictionary() }; LLToolDragAndDrop::LLToolDragAndDrop() -: LLTool(std::string("draganddrop"), NULL), - mDragStartX(0), - mDragStartY(0), - mSource(SOURCE_AGENT), - mCursor(UI_CURSOR_NO), - mLastAccept(ACCEPT_NO), - mDrop(FALSE), - mCurItemIndex(0) +: LLTool(std::string("draganddrop"), NULL), + mCargoCount(0), + mDragStartX(0), + mDragStartY(0), + mSource(SOURCE_AGENT), + mCursor(UI_CURSOR_NO), + mLastAccept(ACCEPT_NO), + mDrop(FALSE), + mCurItemIndex(0) { } diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h index 188d36cd1b..245c2a23e6 100644 --- a/indra/newview/lltooldraganddrop.h +++ b/indra/newview/lltooldraganddrop.h @@ -86,8 +86,11 @@ public: EAcceptance getLastAccept() { return mLastAccept; } boost::signals2::connection setEndDragCallback( const enddrag_signal_t::slot_type& cb ) { return mEndDragSignal.connect(cb); } - - uuid_vec_t::size_type getCargoIDsCount() const { return mCargoIDs.size(); } + + void setCargoCount(U32 count) { mCargoCount = count; } + void resetCargoCount() { mCargoCount = 0; } + U32 getCargoCount() const { return (mCargoCount > 0) ? mCargoCount : mCargoIDs.size(); } + static S32 getOperationId() { return sOperationId; } protected: @@ -118,6 +121,8 @@ protected: protected: + U32 mCargoCount; + S32 mDragStartX; S32 mDragStartY; -- cgit v1.3 From 039c50f2b4831a4caad3313b3e8e1c992793ae90 Mon Sep 17 00:00:00 2001 From: Jonathan Yap Date: Wed, 8 Feb 2012 15:41:27 -0500 Subject: STORM-1807 Play animation floater 2nd play button active while animation is playing --- doc/contributions.txt | 1 + indra/newview/llinventorybridge.cpp | 8 +- indra/newview/llpreviewanim.cpp | 140 +++++++++------------ indra/newview/llpreviewanim.h | 20 ++- .../default/xui/en/floater_preview_animation.xml | 16 ++- 5 files changed, 86 insertions(+), 99 deletions(-) (limited to 'indra/newview/llinventorybridge.cpp') diff --git a/doc/contributions.txt b/doc/contributions.txt index c5db396c97..434e7626fc 100644 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -610,6 +610,7 @@ Jonathan Yap STORM-1788 STORM-1799 STORM-1796 + STORM-1807 Kadah Coba STORM-1060 Jondan Lundquist diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index cebe93f042..654ebe78fa 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -4633,14 +4633,14 @@ void LLAnimationBridge::performAction(LLInventoryModel* model, std::string actio { if (getItem()) { - LLPreviewAnim::e_activation_type activate = LLPreviewAnim::NONE; - if ("playworld" == action) activate = LLPreviewAnim::PLAY; - if ("playlocal" == action) activate = LLPreviewAnim::AUDITION; + LLSD::String activate = "NONE"; + if ("playworld" == action) activate = "Inworld"; + if ("playlocal" == action) activate = "Locally"; LLPreviewAnim* preview = LLFloaterReg::showTypedInstance("preview_anim", LLSD(mUUID)); if (preview) { - preview->activate(activate); + preview->play(activate); } } } diff --git a/indra/newview/llpreviewanim.cpp b/indra/newview/llpreviewanim.cpp index 8e8b530e13..dcb8bca512 100644 --- a/indra/newview/llpreviewanim.cpp +++ b/indra/newview/llpreviewanim.cpp @@ -43,19 +43,7 @@ extern LLAgent gAgent; LLPreviewAnim::LLPreviewAnim(const LLSD& key) : LLPreview( key ) { -} - -// static -void LLPreviewAnim::endAnimCallback( void *userdata ) -{ - LLHandle* handlep = ((LLHandle*)userdata); - LLFloater* self = handlep->get(); - delete handlep; // done with the handle - if (self) - { - self->getChild("Anim play btn")->setValue(FALSE); - self->getChild("Anim audition btn")->setValue(FALSE); - } + mCommitCallbackRegistrar.add("PreviewAnim.Play", boost::bind(&LLPreviewAnim::play, this, _2)); } // virtual @@ -68,105 +56,108 @@ BOOL LLPreviewAnim::postBuild() getChild("desc")->setValue(item->getDescription()); } - childSetAction("Anim play btn",playAnim, this); - childSetAction("Anim audition btn",auditionAnim, this); - childSetCommitCallback("desc", LLPreview::onText, this); getChild("desc")->setPrevalidate(&LLTextValidate::validateASCIIPrintableNoPipe); - + return LLPreview::postBuild(); } -void LLPreviewAnim::activate(e_activation_type type) +// static +// llinventorybridge also calls into here +void LLPreviewAnim::play(const LLSD& param) { - switch ( type ) + const LLInventoryItem *item = getItem(); + + if(item) { - case PLAY: + LLUUID itemID=item->getAssetUUID(); + + std::string btn_name = param.asString(); + LLButton* btn_inuse; + LLButton* btn_other; + + if ("Inworld" == btn_name) { - playAnim( (void *) this ); - break; + btn_inuse = getChild("Inworld"); + btn_other = getChild("Locally"); } - case AUDITION: + else if ("Locally" == btn_name) { - auditionAnim( (void *) this ); - break; + btn_inuse = getChild("Locally"); + btn_other = getChild("Inworld"); } - default: + else { - //do nothing + return; } - } -} -// static -void LLPreviewAnim::playAnim( void *userdata ) -{ - LLPreviewAnim* self = (LLPreviewAnim*) userdata; - const LLInventoryItem *item = self->getItem(); - - if(item) - { - LLUUID itemID=item->getAssetUUID(); + if (btn_inuse) + { + btn_inuse->toggleState(); + } - LLButton* btn = self->getChild("Anim play btn"); - if (btn) + if (btn_other) { - btn->toggleState(); + btn_other->setEnabled(false); } - if (self->getChild("Anim play btn")->getValue().asBoolean() ) + if (getChild(btn_name)->getValue().asBoolean() ) { - self->mPauseRequest = NULL; - gAgent.sendAnimationRequest(itemID, ANIM_REQUEST_START); + "Inworld" == btn_name ? gAgent.sendAnimationRequest(itemID, ANIM_REQUEST_START) : + gAgentAvatarp->startMotion(item->getAssetUUID()); + LLMotion* motion = gAgentAvatarp->findMotion(itemID); if (motion) { - motion->setDeactivateCallback(&endAnimCallback, (void *)(new LLHandle(self->getHandle()))); + mItemID = itemID; + mDidStart = false; } } else { gAgentAvatarp->stopMotion(itemID); gAgent.sendAnimationRequest(itemID, ANIM_REQUEST_STOP); + + if (btn_other) + { + btn_other->setEnabled(true); + } } } } -// static -void LLPreviewAnim::auditionAnim( void *userdata ) +// virtual +void LLPreviewAnim::draw() { - LLPreviewAnim* self = (LLPreviewAnim*) userdata; - const LLInventoryItem *item = self->getItem(); - - if(item) + LLPreview::draw(); + if (!this->mItemID.isNull()) { - LLUUID itemID=item->getAssetUUID(); - - LLButton* btn = self->getChild("Anim audition btn"); - if (btn) - { - btn->toggleState(); - } - - if (self->getChild("Anim audition btn")->getValue().asBoolean() ) + LLMotion* motion = gAgentAvatarp->findMotion(this->mItemID); + if (motion) { - self->mPauseRequest = NULL; - gAgentAvatarp->startMotion(item->getAssetUUID()); - LLMotion* motion = gAgentAvatarp->findMotion(itemID); - - if (motion) + if (motion->isStopped() && this->mDidStart) { - motion->setDeactivateCallback(&endAnimCallback, (void *)(new LLHandle(self->getHandle()))); + cleanup(); + } + if(gAgentAvatarp->isMotionActive(this->mItemID) && !this->mDidStart) + { + this->mDidStart = true; } - } - else - { - gAgentAvatarp->stopMotion(itemID); - gAgent.sendAnimationRequest(itemID, ANIM_REQUEST_STOP); } } } +// virtual +void LLPreviewAnim::cleanup() +{ + this->mItemID = LLUUID::null; + this->mDidStart = false; + getChild("Inworld")->setValue(FALSE); + getChild("Locally")->setValue(FALSE); + getChild("Inworld")->setEnabled(true); + getChild("Locally")->setEnabled(true); +} + // virtual void LLPreviewAnim::onClose(bool app_quitting) { @@ -176,12 +167,5 @@ void LLPreviewAnim::onClose(bool app_quitting) { gAgentAvatarp->stopMotion(item->getAssetUUID()); gAgent.sendAnimationRequest(item->getAssetUUID(), ANIM_REQUEST_STOP); - LLMotion* motion = gAgentAvatarp->findMotion(item->getAssetUUID()); - - if (motion) - { - // *TODO: minor memory leak here, user data is never deleted (Use real callbacks) - motion->setDeactivateCallback(NULL, (void *)NULL); - } } } diff --git a/indra/newview/llpreviewanim.h b/indra/newview/llpreviewanim.h index 32e07ee33a..8eaed6ca1f 100644 --- a/indra/newview/llpreviewanim.h +++ b/indra/newview/llpreviewanim.h @@ -33,24 +33,18 @@ class LLPreviewAnim : public LLPreview { public: - enum e_activation_type { NONE = 0, PLAY = 1, AUDITION = 2 }; - LLPreviewAnim(const LLSD& key); - static void playAnim( void* userdata ); - static void auditionAnim( void* userdata ); - static void endAnimCallback( void *userdata ); + LLPreviewAnim(const LLSD& key); /*virtual*/ BOOL postBuild(); /*virtual*/ void onClose(bool app_quitting); - void activate(e_activation_type type); + void draw(); + void cleanup(); + void play(const LLSD& param); protected: - LLAnimPauseRequest mPauseRequest; - LLUUID mItemID; - std::string mTitle; - LLUUID mObjectID; - LLButton* mPlayBtn; - LLButton* mAuditionBtn; + LLUUID mItemID; + bool mDidStart; }; -#endif // LL_LLPREVIEWSOUND_H +#endif // LL_LLPREVIEWANIM_H diff --git a/indra/newview/skins/default/xui/en/floater_preview_animation.xml b/indra/newview/skins/default/xui/en/floater_preview_animation.xml index 8427c7b06f..3ea5f54f2c 100644 --- a/indra/newview/skins/default/xui/en/floater_preview_animation.xml +++ b/indra/newview/skins/default/xui/en/floater_preview_animation.xml @@ -41,18 +41,26 @@ label_selected="Stop" layout="topleft" left="10" - name="Anim play btn" + name="Inworld" tool_tip="Play this animation so that others can see it" top="47" - width="125" /> + width="125"> + + -- cgit v1.3 From 4523b3137850df8922b12cc966633a3d5bb84374 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 9 Feb 2012 12:58:43 -0800 Subject: EXP-1844 FIX Selecting a large number of inventory items can block the viewer for a long time. only show hourglass and fetching text when downloading folders, not item metadata --- indra/newview/llfolderview.cpp | 4 +- indra/newview/llfolderviewitem.cpp | 2 +- indra/newview/llinventorybridge.cpp | 1 + indra/newview/llinventoryfilter.cpp | 2 +- indra/newview/llinventorymodelbackgroundfetch.cpp | 170 +++++++++++++--------- indra/newview/llinventorymodelbackgroundfetch.h | 4 +- indra/newview/llinventorypanel.cpp | 2 +- indra/newview/llpanelmaininventory.cpp | 2 +- indra/newview/llviewerinventory.cpp | 5 - 9 files changed, 108 insertions(+), 84 deletions(-) (limited to 'indra/newview/llinventorybridge.cpp') diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index 2249f61435..86001e4146 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -912,7 +912,7 @@ void LLFolderView::draw() } else if (mShowEmptyMessage) { - if (LLInventoryModelBackgroundFetch::instance().backgroundFetchActive() || mCompletedFilterGeneration < mFilter->getMinRequiredGeneration()) + if (LLInventoryModelBackgroundFetch::instance().folderFetchActive() || mCompletedFilterGeneration < mFilter->getMinRequiredGeneration()) { mStatusText = LLTrans::getString("Searching"); } @@ -1966,7 +1966,7 @@ void LLFolderView::scrollToShowSelection() // However we allow scrolling for folder views with mAutoSelectOverride // (used in Places SP) as an exception because the selection in them // is not reset during items filtering. See STORM-133. - if ( (!LLInventoryModelBackgroundFetch::instance().backgroundFetchActive() || mAutoSelectOverride) + if ( (!LLInventoryModelBackgroundFetch::instance().folderFetchActive() || mAutoSelectOverride) && mSelectedItems.size() ) { mNeedsScroll = TRUE; diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp index 734adbc648..afad27b4e0 100644 --- a/indra/newview/llfolderviewitem.cpp +++ b/indra/newview/llfolderviewitem.cpp @@ -1045,7 +1045,7 @@ void LLFolderViewItem::draw() } if ((mIsLoading && mTimeSinceRequestStart.getElapsedTimeF32() >= gSavedSettings.getF32("FolderLoadingMessageWaitTime")) - || (LLInventoryModelBackgroundFetch::instance().backgroundFetchActive() + || (LLInventoryModelBackgroundFetch::instance().folderFetchActive() && root_is_loading && mShowLoadStatus)) { diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 257ceed912..daebfb5c86 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -1324,6 +1324,7 @@ void LLItemBridge::selectItem() LLViewerInventoryItem* item = static_cast(getItem()); if(item && !item->isFinished()) { + //item->fetchFromServer(); LLInventoryModelBackgroundFetch::instance().start(item->getUUID(), false); } } diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index 796251cae5..f818e33726 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -888,7 +888,7 @@ const std::string& LLInventoryFilter::getFilterText() filtered_by_all_types = FALSE; } - if (!LLInventoryModelBackgroundFetch::instance().backgroundFetchActive() + if (!LLInventoryModelBackgroundFetch::instance().folderFetchActive() && filtered_by_type && !filtered_by_all_types) { diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index cb140cf15c..f4d0110b0f 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -43,6 +43,7 @@ const S32 MAX_FETCH_RETRIES = 10; LLInventoryModelBackgroundFetch::LLInventoryModelBackgroundFetch() : mBackgroundFetchActive(FALSE), + mFolderFetchActive(false), mAllFoldersFetched(FALSE), mRecursiveInventoryFetchStarted(FALSE), mRecursiveLibraryFetchStarted(FALSE), @@ -98,19 +99,20 @@ bool LLInventoryModelBackgroundFetch::isEverythingFetched() const return mAllFoldersFetched; } -BOOL LLInventoryModelBackgroundFetch::backgroundFetchActive() const +BOOL LLInventoryModelBackgroundFetch::folderFetchActive() const { - return mBackgroundFetchActive; + return mFolderFetchActive; } void LLInventoryModelBackgroundFetch::start(const LLUUID& id, BOOL recursive) { LLViewerInventoryCategory* cat = gInventory.getCategory(id); - if (cat || (id.isNull() && !mAllFoldersFetched)) + if (cat || (id.isNull() && !isEverythingFetched())) { // it's a folder, do a bulk fetch LL_DEBUGS("InventoryFetch") << "Start fetching category: " << id << ", recursive: " << recursive << LL_ENDL; mBackgroundFetchActive = TRUE; + mFolderFetchActive = true; if (id.isNull()) { if (!mRecursiveInventoryFetchStarted) @@ -159,21 +161,11 @@ void LLInventoryModelBackgroundFetch::start(const LLUUID& id, BOOL recursive) void LLInventoryModelBackgroundFetch::findLostItems() { mBackgroundFetchActive = TRUE; + mFolderFetchActive = true; mFetchQueue.push_back(FetchQueueInfo(LLUUID::null, TRUE)); gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } -void LLInventoryModelBackgroundFetch::stopBackgroundFetch() -{ - if (mBackgroundFetchActive) - { - mBackgroundFetchActive = FALSE; - gIdleCallbacks.deleteFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); - mFetchCount=0; - mMinTimeBetweenFetches=0.0f; - } -} - void LLInventoryModelBackgroundFetch::setAllFoldersFetched() { if (mRecursiveInventoryFetchStarted && @@ -181,7 +173,7 @@ void LLInventoryModelBackgroundFetch::setAllFoldersFetched() { mAllFoldersFetched = TRUE; } - stopBackgroundFetch(); + mFolderFetchActive = false; } void LLInventoryModelBackgroundFetch::backgroundFetchCB(void *) @@ -211,6 +203,9 @@ void LLInventoryModelBackgroundFetch::backgroundFetch() llinfos << "Inventory fetch completed" << llendl; setAllFoldersFetched(); + mBackgroundFetchActive = false; + mFolderFetchActive = false; + return; } @@ -240,80 +235,114 @@ void LLInventoryModelBackgroundFetch::backgroundFetch() } const FetchQueueInfo info = mFetchQueue.front(); - LLViewerInventoryCategory* cat = gInventory.getCategory(info.mUUID); - // Category has been deleted, remove from queue. - if (!cat) + if (info.mIsCategory) { - mFetchQueue.pop_front(); - continue; - } + + LLViewerInventoryCategory* cat = gInventory.getCategory(info.mUUID); + + // Category has been deleted, remove from queue. + if (!cat) + { + mFetchQueue.pop_front(); + continue; + } - if (mFetchTimer.getElapsedTimeF32() > mMinTimeBetweenFetches && - LLViewerInventoryCategory::VERSION_UNKNOWN == cat->getVersion()) - { - // Category exists but has no children yet, fetch the descendants - // for now, just request every time and rely on retry timer to throttle. - if (cat->fetch()) + if (mFetchTimer.getElapsedTimeF32() > mMinTimeBetweenFetches && + LLViewerInventoryCategory::VERSION_UNKNOWN == cat->getVersion()) { - mFetchTimer.reset(); - mTimelyFetchPending = TRUE; + // Category exists but has no children yet, fetch the descendants + // for now, just request every time and rely on retry timer to throttle. + if (cat->fetch()) + { + mFetchTimer.reset(); + mTimelyFetchPending = TRUE; + } + else + { + // The catagory also tracks if it has expired and here it says it hasn't + // yet. Get out of here because nothing is going to happen until we + // update the timers. + break; + } } - else + // Do I have all my children? + else if (gInventory.isCategoryComplete(info.mUUID)) { - // The catagory also tracks if it has expired and here it says it hasn't - // yet. Get out of here because nothing is going to happen until we - // update the timers. + // Finished with this category, remove from queue. + mFetchQueue.pop_front(); + + // Add all children to queue. + LLInventoryModel::cat_array_t* categories; + LLInventoryModel::item_array_t* items; + gInventory.getDirectDescendentsOf(cat->getUUID(), categories, items); + for (LLInventoryModel::cat_array_t::const_iterator it = categories->begin(); + it != categories->end(); + ++it) + { + mFetchQueue.push_back(FetchQueueInfo((*it)->getUUID(),info.mRecursive)); + } + + // We received a response in less than the fast time. + if (mTimelyFetchPending && mFetchTimer.getElapsedTimeF32() < fast_fetch_time) + { + // Shrink timeouts based on success. + mMinTimeBetweenFetches = llmax(mMinTimeBetweenFetches * 0.8f, 0.3f); + mMaxTimeBetweenFetches = llmax(mMaxTimeBetweenFetches * 0.8f, 10.f); + lldebugs << "Inventory fetch times shrunk to (" << mMinTimeBetweenFetches << ", " << mMaxTimeBetweenFetches << ")" << llendl; + } + + mTimelyFetchPending = FALSE; + continue; + } + else if (mFetchTimer.getElapsedTimeF32() > mMaxTimeBetweenFetches) + { + // Received first packet, but our num descendants does not match db's num descendants + // so try again later. + mFetchQueue.pop_front(); + + if (mNumFetchRetries++ < MAX_FETCH_RETRIES) + { + // push on back of queue + mFetchQueue.push_back(info); + } + mTimelyFetchPending = FALSE; + mFetchTimer.reset(); break; } + + // Not enough time has elapsed to do a new fetch + break; } - // Do I have all my children? - else if (gInventory.isCategoryComplete(info.mUUID)) + else { - // Finished with this category, remove from queue. - mFetchQueue.pop_front(); + LLViewerInventoryItem* itemp = gInventory.getItem(info.mUUID); - // Add all children to queue. - LLInventoryModel::cat_array_t* categories; - LLInventoryModel::item_array_t* items; - gInventory.getDirectDescendentsOf(cat->getUUID(), categories, items); - for (LLInventoryModel::cat_array_t::const_iterator it = categories->begin(); - it != categories->end(); - ++it) + mFetchQueue.pop_front(); + if (!itemp) { - mFetchQueue.push_back(FetchQueueInfo((*it)->getUUID(),info.mRecursive)); + continue; } - // We received a response in less than the fast time. - if (mTimelyFetchPending && mFetchTimer.getElapsedTimeF32() < fast_fetch_time) + if (mFetchTimer.getElapsedTimeF32() > mMinTimeBetweenFetches) { - // Shrink timeouts based on success. - mMinTimeBetweenFetches = llmax(mMinTimeBetweenFetches * 0.8f, 0.3f); - mMaxTimeBetweenFetches = llmax(mMaxTimeBetweenFetches * 0.8f, 10.f); - lldebugs << "Inventory fetch times shrunk to (" << mMinTimeBetweenFetches << ", " << mMaxTimeBetweenFetches << ")" << llendl; + itemp->fetchFromServer(); + mFetchTimer.reset(); + mTimelyFetchPending = TRUE; } - - mTimelyFetchPending = FALSE; - continue; - } - else if (mFetchTimer.getElapsedTimeF32() > mMaxTimeBetweenFetches) - { - // Received first packet, but our num descendants does not match db's num descendants - // so try again later. - mFetchQueue.pop_front(); - - if (mNumFetchRetries++ < MAX_FETCH_RETRIES) + else if (itemp->mIsComplete) + { + mTimelyFetchPending = FALSE; + } + else if (mFetchTimer.getElapsedTimeF32() > mMaxTimeBetweenFetches) { - // push on back of queue mFetchQueue.push_back(info); + mFetchTimer.reset(); + mTimelyFetchPending = FALSE; } - mTimelyFetchPending = FALSE; - mFetchTimer.reset(); + // Not enough time has elapsed to do a new fetch break; } - - // Not enough time has elapsed to do a new fetch - break; } // @@ -543,7 +572,6 @@ void LLInventoryModelBackgroundFetch::bulkFetch() //Background fetch is called from gIdleCallbacks in a loop until background fetch is stopped. //If there are items in mFetchQueue, we want to check the time since the last bulkFetch was //sent. If it exceeds our retry time, go ahead and fire off another batch. - //Stopbackgroundfetch will be run from the Responder instead of here. LLViewerRegion* region = gAgent.getRegion(); if (!region) return; @@ -574,12 +602,12 @@ void LLInventoryModelBackgroundFetch::bulkFetch() LLSD item_request_body; LLSD item_request_body_lib; - while (!(mFetchQueue.empty()) && ((item_count + folder_count) < max_batch_size)) + while (!mFetchQueue.empty() + && (item_count + folder_count) < max_batch_size) { const FetchQueueInfo& fetch_info = mFetchQueue.front(); if (fetch_info.mIsCategory) { - const LLUUID &cat_id = fetch_info.mUUID; if (cat_id.isNull()) //DEV-17797 { diff --git a/indra/newview/llinventorymodelbackgroundfetch.h b/indra/newview/llinventorymodelbackgroundfetch.h index 0745407a8c..9dfedddd6d 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.h +++ b/indra/newview/llinventorymodelbackgroundfetch.h @@ -48,7 +48,7 @@ public: // This gets triggered when performing a filter-search. void start(const LLUUID& cat_id = LLUUID::null, BOOL recursive = TRUE); - BOOL backgroundFetchActive() const; + BOOL folderFetchActive() const; bool isEverythingFetched() const; // completing the fetch once per session should be sufficient bool libraryFetchStarted() const; @@ -67,7 +67,6 @@ protected: void backgroundFetch(); static void backgroundFetchCB(void*); // background fetch idle function - void stopBackgroundFetch(); // stop fetch process void setAllFoldersFetched(); bool fetchQueueContainsNoDescendentsOf(const LLUUID& cat_id) const; @@ -77,6 +76,7 @@ private: BOOL mAllFoldersFetched; BOOL mBackgroundFetchActive; + bool mFolderFetchActive; S16 mFetchCount; BOOL mTimelyFetchPending; S32 mNumFetchRetries; diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 382569fa3a..01a8ecfb5d 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -817,7 +817,7 @@ BOOL LLInventoryPanel::handleHover(S32 x, S32 y, MASK mask) if(handled) { ECursorType cursor = getWindow()->getCursor(); - if (LLInventoryModelBackgroundFetch::instance().backgroundFetchActive() && cursor == UI_CURSOR_ARROW) + if (LLInventoryModelBackgroundFetch::instance().folderFetchActive() && cursor == UI_CURSOR_ARROW) { // replace arrow cursor with arrow and hourglass cursor getWindow()->setCursor(UI_CURSOR_WORKING); diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index 374afb90be..c3c62920d3 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -567,7 +567,7 @@ void LLPanelMainInventory::updateItemcountText() std::string text = ""; - if (LLInventoryModelBackgroundFetch::instance().backgroundFetchActive()) + if (LLInventoryModelBackgroundFetch::instance().folderFetchActive()) { text = getString("ItemcountFetching", string_args); } diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index cf52b5165b..45ca23cdfe 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -436,11 +436,6 @@ void LLViewerInventoryItem::fetchFromServer(void) const gAgent.sendReliableMessage(); } } - else - { - // *FIX: this can be removed after a bit. - llwarns << "request to fetch complete item" << llendl; - } } // virtual -- cgit v1.3 From 26d33527a345ad6fe4b6deba8c120fe435e95f77 Mon Sep 17 00:00:00 2001 From: Seth ProductEngine Date: Wed, 22 Feb 2012 22:33:57 +0200 Subject: EXP-1335 FIXED Dragging folders into Recent Items disabled. - Dragging folder into Recent Items disabled, but allowed within Recent Items. - Dragging Contents folder from task inventory disabled. - Filtering folder contents upon dragging to any inventory panel added, to make the behavior consistent with items filtering during DnD. --- indra/newview/llinventorybridge.cpp | 145 +++++++++++++++++++++++++++++++++--- indra/newview/llinventorybridge.h | 4 +- indra/newview/llinventoryfilter.cpp | 27 ++++++- indra/newview/llinventoryfilter.h | 3 +- 4 files changed, 161 insertions(+), 18 deletions(-) (limited to 'indra/newview/llinventorybridge.cpp') diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index daebfb5c86..416261780e 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -113,6 +113,13 @@ bool move_task_inventory_callback(const LLSD& notification, const LLSD& response bool confirm_attachment_rez(const LLSD& notification, const LLSD& response); 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, + LLInventoryFilter* filter); +static bool check_item(const LLUUID& item_id, + LLFolderView* active_folder_view, + LLInventoryFilter* filter); // Helper functions @@ -1959,6 +1966,12 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, if (!isAgentAvatarValid()) return FALSE; if (!isAgentInventory()) return FALSE; // cannot drag categories into library + LLInventoryPanel* destination_panel = mInventoryPanel.get(); + if (!destination_panel) return false; + + LLInventoryFilter* filter = destination_panel->getFilter(); + if (!filter) return false; + const LLUUID &cat_id = inv_cat->getUUID(); const LLUUID ¤t_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false); const LLUUID &outbox_id = model->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false); @@ -2146,6 +2159,39 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, } } + if (is_movable) + { + LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); + is_movable = active_panel != NULL; + + // For a folder to pass the filter all its descendants are required to pass. + // We make this exception to allow reordering folders within an inventory panel, + // which has a filter applied, like Recent tab for example. + // There may be folders which are displayed because some of their descendants pass + // the filter, but other don't, and thus remain hidden. Without this check, + // such folders would not be allowed to be moved within a panel. + if (destination_panel == active_panel) + { + is_movable = true; + } + else + { + LLFolderView* active_folder_view; + + if (is_movable) + { + active_folder_view = active_panel->getRootFolder(); + is_movable = active_folder_view != NULL; + } + + if (is_movable) + { + // 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); + } + } + } // //-------------------------------------------------------------------------------- @@ -2240,7 +2286,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, } else { - accept = move_inv_category_world_to_agent(cat_id, mUUID, drop); + accept = move_inv_category_world_to_agent(cat_id, mUUID, drop, NULL, NULL, filter); } } else if (LLToolDragAndDrop::SOURCE_LIBRARY == source) @@ -2285,7 +2331,8 @@ BOOL move_inv_category_world_to_agent(const LLUUID& object_id, const LLUUID& category_id, BOOL drop, void (*callback)(S32, void*), - void* user_data) + void* user_data, + LLInventoryFilter* filter) { // Make sure the object exists. If we allowed dragging from // anonymous objects, it would be possible to bypass @@ -2309,7 +2356,7 @@ BOOL move_inv_category_world_to_agent(const LLUUID& object_id, return FALSE; } - BOOL accept = TRUE; + BOOL accept = FALSE; BOOL is_move = FALSE; // coming from a task. Need to figure out if the person can @@ -2318,9 +2365,16 @@ BOOL move_inv_category_world_to_agent(const LLUUID& object_id, LLInventoryObject::object_list_t::iterator end = inventory_objects.end(); for ( ; it != end; ++it) { + LLInventoryItem* item = dynamic_cast(it->get()); + if (!item) + { + llwarns << "Invalid inventory item for drop" << llendl; + continue; + } + // coming from a task. Need to figure out if the person can // move/copy this item. - LLPermissions perm(((LLInventoryItem*)((LLInventoryObject*)(*it)))->getPermissions()); + LLPermissions perm(item->getPermissions()); if((perm.allowCopyBy(gAgent.getID(), gAgent.getGroupID()) && perm.allowTransferTo(gAgent.getID()))) // || gAgent.isGodlike()) @@ -2335,9 +2389,14 @@ BOOL move_inv_category_world_to_agent(const LLUUID& object_id, is_move = TRUE; accept = TRUE; } - else + + if (filter && accept) + { + accept = filter->check(item); + } + + if (!accept) { - accept = FALSE; break; } } @@ -3693,10 +3752,10 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, // passes the filter of the destination panel. if (accept && active_panel) { - LLFolderView* active_folder_viev = active_panel->getRootFolder(); - if (!active_folder_viev) return false; + LLFolderView* active_folder_view = active_panel->getRootFolder(); + if (!active_folder_view) return false; - LLFolderViewItem* fv_item = active_folder_viev->getItemByID(inv_item->getUUID()); + LLFolderViewItem* fv_item = active_folder_view->getItemByID(inv_item->getUUID()); if (!fv_item) return false; accept = filter->check(fv_item); @@ -3916,10 +3975,10 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, // passes the filter of the destination panel. if (accept && active_panel) { - LLFolderView* active_folder_viev = active_panel->getRootFolder(); - if (!active_folder_viev) return false; + LLFolderView* active_folder_view = active_panel->getRootFolder(); + if (!active_folder_view) return false; - LLFolderViewItem* fv_item = active_folder_viev->getItemByID(inv_item->getUUID()); + LLFolderViewItem* fv_item = active_folder_view->getItemByID(inv_item->getUUID()); if (!fv_item) return false; accept = filter->check(fv_item); @@ -3959,6 +4018,68 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, return accept; } +// static +bool check_category(LLInventoryModel* model, + const LLUUID& cat_id, + LLFolderView* active_folder_view, + LLInventoryFilter* filter) +{ + if (!model || !active_folder_view || !filter) + return false; + + if (!filter->checkFolder(cat_id)) + { + return false; + } + + LLInventoryModel::cat_array_t descendent_categories; + LLInventoryModel::item_array_t descendent_items; + model->collectDescendents(cat_id, descendent_categories, descendent_items, TRUE); + + S32 num_descendent_categories = descendent_categories.count(); + S32 num_descendent_items = descendent_items.count(); + + if (num_descendent_categories + num_descendent_items == 0 + && filter->getShowFolderState() != LLInventoryFilter::SHOW_ALL_FOLDERS) + { + // Empty folders are not allowed if we are not showing all folders + return false; + } + + for (S32 i = 0; i < num_descendent_categories; ++i) + { + LLInventoryCategory* category = descendent_categories[i]; + if(!check_category(model, category->getUUID(), active_folder_view, filter)) + { + return false; + } + } + + for (S32 i = 0; i < num_descendent_items; ++i) + { + LLViewerInventoryItem* item = descendent_items[i]; + if(!check_item(item->getUUID(), active_folder_view, filter)) + { + return false; + } + } + + return true; +} + +// static +bool check_item(const LLUUID& item_id, + LLFolderView* active_folder_view, + LLInventoryFilter* filter) +{ + if (!active_folder_view || !filter) return false; + + LLFolderViewItem* fv_item = active_folder_view->getItemByID(item_id); + if (!fv_item) return false; + + return filter->check(fv_item); +} + // +=================================================+ // | LLTextureBridge | // +=================================================+ diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 3bcd71557c..3b4f845f54 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -35,6 +35,7 @@ #include "llviewercontrol.h" #include "llwearable.h" +class LLInventoryFilter; class LLInventoryPanel; class LLInventoryModel; class LLMenuGL; @@ -645,7 +646,8 @@ BOOL move_inv_category_world_to_agent(const LLUUID& object_id, const LLUUID& category_id, BOOL drop, void (*callback)(S32, void*) = NULL, - void* user_data = NULL); + void* user_data = NULL, + LLInventoryFilter* filter = NULL); // Utility function to hide all entries except those in the list // Can be called multiple times on the same menu (e.g. if multiple items diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index 4971ded634..5496c273f2 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -121,16 +121,35 @@ bool LLInventoryFilter::check(const LLInventoryItem* item) return passed; } -bool LLInventoryFilter::checkFolder(const LLFolderViewFolder* folder) +bool LLInventoryFilter::checkFolder(const LLFolderViewFolder* folder) const { - // we're showing all folders, overriding filter - if (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS) + if (!folder) { - return true; + 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(); + if (!listener) + { + llwarns << "Folder view event listener not found." << llendl; + llassert(false); // crash in development builds + return false; + } + const LLUUID folder_id = listener->getUUID(); + + return checkFolder(folder_id); +} + +bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const +{ + // we're showing all folders, overriding filter + if (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS) + { + return true; + } if (mFilterOps.mFilterTypes & FILTERTYPE_CATEGORY) { diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h index 8635d5d5b3..6be2acfaa3 100644 --- a/indra/newview/llinventoryfilter.h +++ b/indra/newview/llinventoryfilter.h @@ -117,7 +117,8 @@ public: // +-------------------------------------------------------------------+ BOOL check(const LLFolderViewItem* item); bool check(const LLInventoryItem* item); - bool checkFolder(const LLFolderViewFolder* folder); + bool checkFolder(const LLFolderViewFolder* folder) 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; -- cgit v1.3 From d5d2147a97953434f2baddf9d3f7c9d1be7f7b3e Mon Sep 17 00:00:00 2001 From: Seth ProductEngine Date: Wed, 22 Feb 2012 23:11:29 +0200 Subject: Windows build fix. --- indra/newview/llinventorybridge.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llinventorybridge.cpp') diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 416261780e..dcdc1391eb 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -2176,7 +2176,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, } else { - LLFolderView* active_folder_view; + LLFolderView* active_folder_view = NULL; if (is_movable) { -- cgit v1.3 From 11d29660aa84a1a8a61e427698715497a57243c2 Mon Sep 17 00:00:00 2001 From: Seth ProductEngine Date: Thu, 23 Feb 2012 21:47:03 +0200 Subject: EXP-1335 FIXED empty folders not draggable between Inventory windows. Added filtering empty folders as any other folder view item. This enables dragging empty folders between Inventory floaters when they pass the filter. --- indra/newview/llinventorybridge.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'indra/newview/llinventorybridge.cpp') diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index dcdc1391eb..6a20120808 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -4039,11 +4039,12 @@ bool check_category(LLInventoryModel* model, S32 num_descendent_categories = descendent_categories.count(); S32 num_descendent_items = descendent_items.count(); - if (num_descendent_categories + num_descendent_items == 0 - && filter->getShowFolderState() != LLInventoryFilter::SHOW_ALL_FOLDERS) + if (num_descendent_categories + num_descendent_items == 0) { - // Empty folders are not allowed if we are not showing all folders - return false; + // 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); } for (S32 i = 0; i < num_descendent_categories; ++i) -- cgit v1.3