[MAINT-2287] The rest of the updates so far to outbox.
This commit is contained in:
@@ -164,6 +164,17 @@ BOOL LLFloaterOutbox::postBuild()
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLFloaterOutbox::cleanOutbox()
|
||||
{
|
||||
// Note: we cannot delete the mOutboxInventoryPanel as that point
|
||||
// as this is called through callback observers of the panel itself.
|
||||
// Doing so would crash rapidly.
|
||||
|
||||
// Invalidate the outbox data
|
||||
mOutboxId.setNull();
|
||||
mOutboxItemCount = 0;
|
||||
}
|
||||
|
||||
void LLFloaterOutbox::onClose(bool app_quitting)
|
||||
{
|
||||
/*
|
||||
@@ -226,14 +237,26 @@ void LLFloaterOutbox::setupOutbox()
|
||||
}
|
||||
|
||||
// We are a merchant. Get the outbox, create it if needs be.
|
||||
mOutboxId = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, true, false);
|
||||
if (mOutboxId.isNull())
|
||||
LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, true);
|
||||
if (outbox_id.isNull())
|
||||
{
|
||||
// We should never get there unles inventory fails badly
|
||||
// We should never get there unless inventory fails badly
|
||||
llerrs << "Inventory problem: failure to create the outbox for a merchant!" << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Consolidate Merchant Outbox
|
||||
// We shouldn't have to do that but with a client/server system relying on a "well known folder" convention, things get messy and conventions get broken down eventually
|
||||
gInventory.consolidateForType(outbox_id, LLFolderType::FT_OUTBOX);
|
||||
|
||||
if (outbox_id == mOutboxId)
|
||||
{
|
||||
|
||||
llwarns << "Inventory warning: Merchant outbox already set" << llendl;
|
||||
return;
|
||||
}
|
||||
mOutboxId = outbox_id;
|
||||
|
||||
// No longer need to observe new category creation
|
||||
if (mCategoryAddedObserver && gInventory.containsObserver(mCategoryAddedObserver))
|
||||
{
|
||||
@@ -243,13 +266,15 @@ void LLFloaterOutbox::setupOutbox()
|
||||
}
|
||||
llassert(!mCategoryAddedObserver);
|
||||
|
||||
// Create observer for outbox modifications
|
||||
if (mCategoriesObserver == NULL)
|
||||
// Create observer for outbox modifications : clear the old one and create a new one
|
||||
if (mCategoriesObserver && gInventory.containsObserver(mCategoriesObserver))
|
||||
{
|
||||
mCategoriesObserver = new LLInventoryCategoriesObserver();
|
||||
gInventory.addObserver(mCategoriesObserver);
|
||||
mCategoriesObserver->addCategory(mOutboxId, boost::bind(&LLFloaterOutbox::onOutboxChanged, this));
|
||||
gInventory.removeObserver(mCategoriesObserver);
|
||||
delete mCategoriesObserver;
|
||||
}
|
||||
mCategoriesObserver = new LLInventoryCategoriesObserver();
|
||||
gInventory.addObserver(mCategoriesObserver);
|
||||
mCategoriesObserver->addCategory(mOutboxId, boost::bind(&LLFloaterOutbox::onOutboxChanged, this));
|
||||
llassert(mCategoriesObserver);
|
||||
|
||||
// Set up the outbox inventory view
|
||||
@@ -273,13 +298,15 @@ void LLFloaterOutbox::initializeMarketPlace()
|
||||
//
|
||||
// Initialize the marketplace import API
|
||||
//
|
||||
|
||||
LLMarketplaceInventoryImporter& importer = LLMarketplaceInventoryImporter::instance();
|
||||
|
||||
importer.setInitializationErrorCallback(boost::bind(&LLFloaterOutbox::initializationReportError, this, _1, _2));
|
||||
importer.setStatusChangedCallback(boost::bind(&LLFloaterOutbox::importStatusChanged, this, _1));
|
||||
importer.setStatusReportCallback(boost::bind(&LLFloaterOutbox::importReportResults, this, _1, _2));
|
||||
importer.initialize();
|
||||
if (!importer.isInitialized())
|
||||
{
|
||||
importer.setInitializationErrorCallback(boost::bind(&LLFloaterOutbox::initializationReportError, this, _1, _2));
|
||||
importer.setStatusChangedCallback(boost::bind(&LLFloaterOutbox::importStatusChanged, this, _1));
|
||||
importer.setStatusReportCallback(boost::bind(&LLFloaterOutbox::importReportResults, this, _1, _2));
|
||||
importer.initialize();
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterOutbox::setStatusString(const std::string& statusString)
|
||||
@@ -306,6 +333,11 @@ void LLFloaterOutbox::updateFolderCount()
|
||||
|
||||
mOutboxItemCount = item_count;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If there's no outbox, the number of items in it should be set to 0 for consistency
|
||||
mOutboxItemCount = 0;
|
||||
}
|
||||
|
||||
if (!mImportBusy)
|
||||
{
|
||||
@@ -375,6 +407,11 @@ void LLFloaterOutbox::updateView()
|
||||
|
||||
if (mOutboxId.notNull())
|
||||
{
|
||||
// Does the outbox needs recreation?
|
||||
if ((mOutboxInventoryPanel.get() == NULL) || !gInventory.getCategory(mOutboxId))
|
||||
{
|
||||
setupOutbox();
|
||||
}
|
||||
// "Outbox is empty!" message strings
|
||||
outbox_text = LLTrans::getString("InventoryOutboxNoItems");
|
||||
subs_link = "[MARKETPLACE_DASHBOARD_URL]";
|
||||
@@ -441,7 +478,8 @@ BOOL LLFloaterOutbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
||||
{
|
||||
if ((mOutboxInventoryPanel.get() == NULL) ||
|
||||
//(mWindowShade && mWindowShade->isShown()) ||
|
||||
LLMarketplaceInventoryImporter::getInstance()->isImportInProgress())
|
||||
LLMarketplaceInventoryImporter::getInstance()->isImportInProgress() ||
|
||||
mOutboxId.isNull())
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -511,16 +549,16 @@ void LLFloaterOutbox::onImportButtonClicked()
|
||||
|
||||
void LLFloaterOutbox::onOutboxChanged()
|
||||
{
|
||||
llassert(!mOutboxId.isNull());
|
||||
|
||||
if (mOutboxInventoryPanel)
|
||||
LLViewerInventoryCategory* category = gInventory.getCategory(mOutboxId);
|
||||
if (mOutboxId.notNull() && category)
|
||||
{
|
||||
mOutboxInventoryPanel->requestSort();
|
||||
fetchOutboxContents();
|
||||
updateView();
|
||||
}
|
||||
else
|
||||
{
|
||||
cleanOutbox();
|
||||
}
|
||||
|
||||
fetchOutboxContents();
|
||||
|
||||
updateView();
|
||||
}
|
||||
|
||||
void LLFloaterOutbox::importReportResults(U32 status, const LLSD& content)
|
||||
|
||||
@@ -72,6 +72,7 @@ public:
|
||||
|
||||
protected:
|
||||
void setupOutbox();
|
||||
void cleanOutbox();
|
||||
void fetchOutboxContents();
|
||||
|
||||
void importReportResults(U32 status, const LLSD& content);
|
||||
|
||||
@@ -405,6 +405,66 @@ void LLInventoryModel::unlockDirectDescendentArrays(const LLUUID& cat_id)
|
||||
mItemLock[cat_id] = false;
|
||||
}
|
||||
|
||||
void LLInventoryModel::consolidateForType(const LLUUID& main_id, LLFolderType::EType type)
|
||||
{
|
||||
// Make a list of folders that are not "main_id" and are of "type"
|
||||
std::vector<LLUUID> folder_ids;
|
||||
for (cat_map_t::iterator cit = mCategoryMap.begin(); cit != mCategoryMap.end(); ++cit)
|
||||
{
|
||||
LLViewerInventoryCategory* cat = cit->second;
|
||||
if ((cat->getPreferredType() == type) && (cat->getUUID() != main_id))
|
||||
{
|
||||
folder_ids.push_back(cat->getUUID());
|
||||
}
|
||||
}
|
||||
|
||||
// Iterate through those folders
|
||||
for (std::vector<LLUUID>::iterator folder_ids_it = folder_ids.begin(); folder_ids_it != folder_ids.end(); ++folder_ids_it)
|
||||
{
|
||||
LLUUID folder_id = (*folder_ids_it);
|
||||
|
||||
// Get the content of this folder
|
||||
cat_array_t* cats;
|
||||
item_array_t* items;
|
||||
getDirectDescendentsOf(folder_id, cats, items);
|
||||
|
||||
// Move all items to the main folder
|
||||
// Note : we get the list of UUIDs and iterate on them instead of iterating directly on item_array_t
|
||||
// elements. This is because moving elements modify the maps and, consequently, invalidate iterators on them.
|
||||
// This "gather and iterate" method is verbose but resilient.
|
||||
std::vector<LLUUID> list_uuids;
|
||||
for (item_array_t::const_iterator it = items->begin(); it != items->end(); ++it)
|
||||
{
|
||||
list_uuids.push_back((*it)->getUUID());
|
||||
}
|
||||
for (std::vector<LLUUID>::const_iterator it = list_uuids.begin(); it != list_uuids.end(); ++it)
|
||||
{
|
||||
LLViewerInventoryItem* item = getItem(*it);
|
||||
changeItemParent(item, main_id, TRUE);
|
||||
}
|
||||
|
||||
// Move all folders to the main folder
|
||||
list_uuids.clear();
|
||||
for (cat_array_t::const_iterator it = cats->begin(); it != cats->end(); ++it)
|
||||
{
|
||||
list_uuids.push_back((*it)->getUUID());
|
||||
}
|
||||
for (std::vector<LLUUID>::const_iterator it = list_uuids.begin(); it != list_uuids.end(); ++it)
|
||||
{
|
||||
LLViewerInventoryCategory* cat = getCategory(*it);
|
||||
changeCategoryParent(cat, main_id, TRUE);
|
||||
}
|
||||
|
||||
// Purge the emptied folder
|
||||
// Note: we'd like to use purgeObject() but it doesn't cleanly eliminate the folder
|
||||
// which leads to issues further down the road when the folder is found again
|
||||
//purgeObject(folder_id);
|
||||
// We remove the folder and empty the trash instead which seems to work
|
||||
removeCategory(folder_id);
|
||||
gInventory.emptyFolderType("", LLFolderType::FT_TRASH);
|
||||
}
|
||||
}
|
||||
|
||||
// findCategoryUUIDForType() returns the uuid of the category that
|
||||
// specifies 'type' as what it defaults to containing. The category is
|
||||
// not necessarily only for that type. *NOTE: This will create a new
|
||||
|
||||
@@ -275,6 +275,11 @@ public:
|
||||
LLViewerInventoryItem* getLinkedItem(const LLUUID& object_id) const;
|
||||
|
||||
LLUUID findCategoryByName(std::string name);
|
||||
|
||||
// Copy content of all folders of type "type" into folder "id" and delete/purge the empty folders
|
||||
// Note : This method has been designed for FT_OUTBOX (aka Merchant Outbox) but can be used for other categories
|
||||
void consolidateForType(const LLUUID& id, LLFolderType::EType type);
|
||||
|
||||
private:
|
||||
mutable LLPointer<LLViewerInventoryItem> mLastItem; // cache recent lookups
|
||||
|
||||
|
||||
@@ -690,15 +690,24 @@ void LLInventoryCategoriesObserver::changed(U32 mask)
|
||||
if (!mCategoryMap.size())
|
||||
return;
|
||||
|
||||
std::vector<LLUUID> deleted_categories_ids;
|
||||
|
||||
for (category_map_t::iterator iter = mCategoryMap.begin();
|
||||
iter != mCategoryMap.end();
|
||||
++iter)
|
||||
{
|
||||
const LLUUID& cat_id = (*iter).first;
|
||||
LLCategoryData& cat_data = (*iter).second;
|
||||
|
||||
LLViewerInventoryCategory* category = gInventory.getCategory(cat_id);
|
||||
if (!category)
|
||||
{
|
||||
llwarns << "Category : Category id = " << cat_id << " disappeared" << llendl;
|
||||
cat_data.mCallback();
|
||||
// Keep track of those deleted categories so we can remove them
|
||||
deleted_categories_ids.push_back(cat_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
const S32 version = category->getVersion();
|
||||
const S32 expected_num_descendents = category->getDescendentCount();
|
||||
@@ -726,8 +735,6 @@ void LLInventoryCategoriesObserver::changed(U32 mask)
|
||||
|
||||
const S32 current_num_known_descendents = cats->count() + items->count();
|
||||
|
||||
LLCategoryData& cat_data = (*iter).second;
|
||||
|
||||
bool cat_changed = false;
|
||||
|
||||
// If category version or descendents count has changed
|
||||
@@ -757,6 +764,12 @@ void LLInventoryCategoriesObserver::changed(U32 mask)
|
||||
if (cat_changed)
|
||||
cat_data.mCallback();
|
||||
}
|
||||
|
||||
// Remove deleed categories from the list
|
||||
for (std::vector<LLUUID>::iterator deleted_id = deleted_categories_ids.begin(); deleted_id != deleted_categories_ids.end(); ++deleted_id)
|
||||
{
|
||||
removeCategory(*deleted_id);
|
||||
}
|
||||
}
|
||||
|
||||
bool LLInventoryCategoriesObserver::addCategory(const LLUUID& cat_id, callback_t cb)
|
||||
|
||||
@@ -231,9 +231,11 @@ namespace LLMarketplaceImport
|
||||
llinfos << " SLM GET timer: " << slmGetTimer.getElapsedTimeF32() << llendl;
|
||||
}
|
||||
|
||||
// MAINT-2452 : Do not clear the cookie on IMPORT_DONE_WITH_ERRORS
|
||||
// MAINT-2452 : Do not clear the cookie on IMPORT_DONE_WITH_ERRORS : Happens when trying to import objects with wrong permissions
|
||||
// ACME-1221 : Do not clear the cookie on IMPORT_NOT_FOUND : Happens for newly created Merchant accounts that are initially empty
|
||||
if ((status >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST) &&
|
||||
(status != MarketplaceErrorCodes::IMPORT_DONE_WITH_ERRORS))
|
||||
(status != MarketplaceErrorCodes::IMPORT_DONE_WITH_ERRORS) &&
|
||||
(status != MarketplaceErrorCodes::IMPORT_NOT_FOUND))
|
||||
{
|
||||
if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
|
||||
{
|
||||
@@ -241,9 +243,9 @@ namespace LLMarketplaceImport
|
||||
}
|
||||
sMarketplaceCookie.clear();
|
||||
}
|
||||
else if (gSavedSettings.getBOOL("InventoryOutboxLogging") && (status == MarketplaceErrorCodes::IMPORT_DONE_WITH_ERRORS))
|
||||
else if (gSavedSettings.getBOOL("InventoryOutboxLogging") && (status >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST))
|
||||
{
|
||||
llinfos << " SLM GET : Got IMPORT_DONE_WITH_ERRORS, marketplace cookie not cleared." << llendl;
|
||||
llinfos << " SLM GET : Got error status = " << status << ", but marketplace cookie not cleared." << llendl;
|
||||
}
|
||||
|
||||
sImportInProgress = (status == MarketplaceErrorCodes::IMPORT_PROCESSING);
|
||||
@@ -306,13 +308,15 @@ namespace LLMarketplaceImport
|
||||
|
||||
std::string url = getInventoryImportURL();
|
||||
|
||||
AIHTTPHeaders headers = LLViewerMedia::getHeaders();
|
||||
if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
|
||||
{
|
||||
llinfos << " SLM GET: " << url << llendl;
|
||||
llinfos << " SLM GET: establishMarketplaceSessionCookie, LLHTTPClient::get, url = " << url << llendl;
|
||||
llinfos << " SLM GET: headers " << llendl;
|
||||
llinfos << headers << llendl;
|
||||
}
|
||||
|
||||
slmGetTimer.start();
|
||||
AIHTTPHeaders headers = LLViewerMedia::getHeaders();
|
||||
LLHTTPClient::get(url, new LLImportGetResponder(), headers);
|
||||
|
||||
return true;
|
||||
@@ -453,7 +457,10 @@ boost::signals2::connection LLMarketplaceInventoryImporter::setStatusReportCallb
|
||||
|
||||
void LLMarketplaceInventoryImporter::initialize()
|
||||
{
|
||||
llassert(!mInitialized);
|
||||
if (mInitialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!LLMarketplaceImport::hasSessionCookie())
|
||||
{
|
||||
|
||||
@@ -92,6 +92,7 @@ public:
|
||||
void initialize();
|
||||
bool triggerImport();
|
||||
bool isImportInProgress() const { return mImportInProgress; }
|
||||
bool isInitialized() const { return mInitialized; }
|
||||
U32 getMarketPlaceStatus() const { return mMarketPlaceStatus; }
|
||||
|
||||
protected:
|
||||
|
||||
Reference in New Issue
Block a user