diff options
| -rw-r--r-- | indra/newview/llaisapi.cpp | 45 | ||||
| -rw-r--r-- | indra/newview/llinventorybridge.cpp | 8 | ||||
| -rw-r--r-- | indra/newview/llpanelmaininventory.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/llplacesinventorybridge.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llviewerinventory.cpp | 8 | 
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);  			} | 
