summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/newview/llaisapi.cpp45
-rw-r--r--indra/newview/llinventorybridge.cpp8
-rw-r--r--indra/newview/llpanelmaininventory.cpp4
-rw-r--r--indra/newview/llplacesinventorybridge.cpp2
-rw-r--r--indra/newview/llviewerinventory.cpp8
5 files changed, 62 insertions, 5 deletions
diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp
index 648212177b..ee49125711 100644
--- a/indra/newview/llaisapi.cpp
+++ b/indra/newview/llaisapi.cpp
@@ -394,6 +394,40 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht
{
status = LLCore::HttpStatus(HTTP_INTERNAL_ERROR, "Malformed response contents");
}
+ else if (status.getType() == 410) //GONE
+ {
+ // Item does not exist or was already deleted from server.
+ // parent folder is out of sync
+ if (type == REMOVECATEGORY)
+ {
+ LLViewerInventoryCategory *cat = gInventory.getCategory(targetId);
+ if (cat)
+ {
+ LL_WARNS("Inventory") << "Purge failed for '" << cat->getName()
+ << "' local version:" << cat->getVersion()
+ << " since folder no longer exists at server. Descendent count: server == " << cat->getDescendentCount()
+ << ", viewer == " << cat->getViewerDescendentCount()
+ << LL_ENDL;
+ gInventory.fetchDescendentsOf(cat->getParentUUID());
+ // Note: don't delete folder here - contained items will be deparented (or deleted)
+ // and since we are clearly out of sync we can't be sure we won't get rid of something we need.
+ // For example folder could have been moved or renamed with items intact, let it fetch first.
+ }
+ }
+ else if (type == REMOVEITEM)
+ {
+ LLViewerInventoryItem *item = gInventory.getItem(targetId);
+ if (item)
+ {
+ LL_WARNS("Inventory") << "Purge failed for '" << item->getName()
+ << "' since item no longer exists at server." << LL_ENDL;
+ gInventory.fetchDescendentsOf(item->getParentUUID());
+ // since item not on the server and exists at viewer, so it needs an update at the least,
+ // so delete it, in worst case item will be refetched with new params.
+ gInventory.onObjectDeletedFromServer(targetId);
+ }
+ }
+ }
LL_WARNS("Inventory") << "Inventory error: " << status.toString() << LL_ENDL;
LL_WARNS("Inventory") << ll_pretty_print_sd(result) << LL_ENDL;
}
@@ -970,7 +1004,16 @@ void AISUpdate::doUpdate()
// inventory COF is maintained on the viewer through calls to
// LLInventoryModel::accountForUpdate when a changing operation
// is performed. This occasionally gets out of sync however.
- cat->setVersion(version);
+ if (version != LLViewerInventoryCategory::VERSION_UNKNOWN)
+ {
+ cat->setVersion(version);
+ }
+ else
+ {
+ // We do not account for update if version is UNKNOWN, so we shouldn't rise version
+ // either or viewer will get stuck on descendants count -1, try to refetch folder instead
+ cat->fetch();
+ }
}
}
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 1b32fc9dfe..c8a20c9d97 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -3884,8 +3884,14 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
LLInventoryModel::cat_array_t* cat_array;
LLInventoryModel::item_array_t* item_array;
gInventory.getDirectDescendentsOf(mUUID, cat_array, item_array);
+ LLViewerInventoryCategory *trash = getCategory();
// Enable Empty menu item only when there is something to act upon.
- if ((0 == cat_array->size() && 0 == item_array->size()) || is_recent_panel)
+ // Also don't enable menu if folder isn't fully fetched
+ if ((0 == cat_array->size() && 0 == item_array->size())
+ || is_recent_panel
+ || !trash
+ || trash->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN
+ || trash->getDescendentCount() == LLViewerInventoryCategory::VERSION_UNKNOWN)
{
disabled_items.push_back(std::string("Empty Trash"));
}
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index 3db9500de0..dd75ae9c06 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -1287,13 +1287,13 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
{
const LLUUID &trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
LLInventoryModel::EHasChildren children = gInventory.categoryHasChildren(trash_id);
- return children != LLInventoryModel::CHILDREN_NO;
+ return children != LLInventoryModel::CHILDREN_NO && gInventory.isCategoryComplete(trash_id);
}
if (command_name == "empty_lostnfound")
{
const LLUUID &trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
LLInventoryModel::EHasChildren children = gInventory.categoryHasChildren(trash_id);
- return children != LLInventoryModel::CHILDREN_NO;
+ return children != LLInventoryModel::CHILDREN_NO && gInventory.isCategoryComplete(trash_id);
}
return TRUE;
diff --git a/indra/newview/llplacesinventorybridge.cpp b/indra/newview/llplacesinventorybridge.cpp
index 55cb7d616b..471e1c24f3 100644
--- a/indra/newview/llplacesinventorybridge.cpp
+++ b/indra/newview/llplacesinventorybridge.cpp
@@ -62,7 +62,7 @@ void LLPlacesLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
if(isItemInTrash())
{
items.push_back(std::string("Purge Item"));
- if (!isItemRemovable())
+ if (!isItemRemovable() || (gInventory.getCategory(mUUID) && !gInventory.isCategoryComplete(mUUID)))
{
disabled_items.push_back(std::string("Purge Item"));
}
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index bf79a0595c..da6b18bb77 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -1463,6 +1463,10 @@ void remove_inventory_category(
LLPointer<LLViewerInventoryCategory> obj = gInventory.getCategory(cat_id);
if(obj)
{
+ if (!gInventory.isCategoryComplete(cat_id))
+ {
+ LL_WARNS() << "Removing (purging) incomplete category " << obj->getName() << LL_ENDL;
+ }
if(LLFolderType::lookupIsProtectedType(obj->getPreferredType()))
{
LLNotificationsUtil::add("CannotRemoveProtectedCategories");
@@ -1540,6 +1544,10 @@ void purge_descendents_of(const LLUUID& id, LLPointer<LLInventoryCallback> cb)
{
if (AISAPI::isAvailable())
{
+ if (cat->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN)
+ {
+ LL_WARNS() << "Purging not fetched folder: " << cat->getName() << LL_ENDL;
+ }
AISAPI::completion_t cr = (cb) ? boost::bind(&doInventoryCb, cb, _1) : AISAPI::completion_t();
AISAPI::PurgeDescendents(id, cr);
}