[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;
|
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)
|
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.
|
// We are a merchant. Get the outbox, create it if needs be.
|
||||||
mOutboxId = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, true, false);
|
LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, true);
|
||||||
if (mOutboxId.isNull())
|
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;
|
llerrs << "Inventory problem: failure to create the outbox for a merchant!" << llendl;
|
||||||
return;
|
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
|
// No longer need to observe new category creation
|
||||||
if (mCategoryAddedObserver && gInventory.containsObserver(mCategoryAddedObserver))
|
if (mCategoryAddedObserver && gInventory.containsObserver(mCategoryAddedObserver))
|
||||||
{
|
{
|
||||||
@@ -243,13 +266,15 @@ void LLFloaterOutbox::setupOutbox()
|
|||||||
}
|
}
|
||||||
llassert(!mCategoryAddedObserver);
|
llassert(!mCategoryAddedObserver);
|
||||||
|
|
||||||
// Create observer for outbox modifications
|
// Create observer for outbox modifications : clear the old one and create a new one
|
||||||
if (mCategoriesObserver == NULL)
|
if (mCategoriesObserver && gInventory.containsObserver(mCategoriesObserver))
|
||||||
{
|
{
|
||||||
mCategoriesObserver = new LLInventoryCategoriesObserver();
|
gInventory.removeObserver(mCategoriesObserver);
|
||||||
gInventory.addObserver(mCategoriesObserver);
|
delete mCategoriesObserver;
|
||||||
mCategoriesObserver->addCategory(mOutboxId, boost::bind(&LLFloaterOutbox::onOutboxChanged, this));
|
|
||||||
}
|
}
|
||||||
|
mCategoriesObserver = new LLInventoryCategoriesObserver();
|
||||||
|
gInventory.addObserver(mCategoriesObserver);
|
||||||
|
mCategoriesObserver->addCategory(mOutboxId, boost::bind(&LLFloaterOutbox::onOutboxChanged, this));
|
||||||
llassert(mCategoriesObserver);
|
llassert(mCategoriesObserver);
|
||||||
|
|
||||||
// Set up the outbox inventory view
|
// Set up the outbox inventory view
|
||||||
@@ -273,13 +298,15 @@ void LLFloaterOutbox::initializeMarketPlace()
|
|||||||
//
|
//
|
||||||
// Initialize the marketplace import API
|
// Initialize the marketplace import API
|
||||||
//
|
//
|
||||||
|
|
||||||
LLMarketplaceInventoryImporter& importer = LLMarketplaceInventoryImporter::instance();
|
LLMarketplaceInventoryImporter& importer = LLMarketplaceInventoryImporter::instance();
|
||||||
|
|
||||||
importer.setInitializationErrorCallback(boost::bind(&LLFloaterOutbox::initializationReportError, this, _1, _2));
|
if (!importer.isInitialized())
|
||||||
importer.setStatusChangedCallback(boost::bind(&LLFloaterOutbox::importStatusChanged, this, _1));
|
{
|
||||||
importer.setStatusReportCallback(boost::bind(&LLFloaterOutbox::importReportResults, this, _1, _2));
|
importer.setInitializationErrorCallback(boost::bind(&LLFloaterOutbox::initializationReportError, this, _1, _2));
|
||||||
importer.initialize();
|
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)
|
void LLFloaterOutbox::setStatusString(const std::string& statusString)
|
||||||
@@ -306,6 +333,11 @@ void LLFloaterOutbox::updateFolderCount()
|
|||||||
|
|
||||||
mOutboxItemCount = item_count;
|
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)
|
if (!mImportBusy)
|
||||||
{
|
{
|
||||||
@@ -375,6 +407,11 @@ void LLFloaterOutbox::updateView()
|
|||||||
|
|
||||||
if (mOutboxId.notNull())
|
if (mOutboxId.notNull())
|
||||||
{
|
{
|
||||||
|
// Does the outbox needs recreation?
|
||||||
|
if ((mOutboxInventoryPanel.get() == NULL) || !gInventory.getCategory(mOutboxId))
|
||||||
|
{
|
||||||
|
setupOutbox();
|
||||||
|
}
|
||||||
// "Outbox is empty!" message strings
|
// "Outbox is empty!" message strings
|
||||||
outbox_text = LLTrans::getString("InventoryOutboxNoItems");
|
outbox_text = LLTrans::getString("InventoryOutboxNoItems");
|
||||||
subs_link = "[MARKETPLACE_DASHBOARD_URL]";
|
subs_link = "[MARKETPLACE_DASHBOARD_URL]";
|
||||||
@@ -441,7 +478,8 @@ BOOL LLFloaterOutbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
|||||||
{
|
{
|
||||||
if ((mOutboxInventoryPanel.get() == NULL) ||
|
if ((mOutboxInventoryPanel.get() == NULL) ||
|
||||||
//(mWindowShade && mWindowShade->isShown()) ||
|
//(mWindowShade && mWindowShade->isShown()) ||
|
||||||
LLMarketplaceInventoryImporter::getInstance()->isImportInProgress())
|
LLMarketplaceInventoryImporter::getInstance()->isImportInProgress() ||
|
||||||
|
mOutboxId.isNull())
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -511,16 +549,16 @@ void LLFloaterOutbox::onImportButtonClicked()
|
|||||||
|
|
||||||
void LLFloaterOutbox::onOutboxChanged()
|
void LLFloaterOutbox::onOutboxChanged()
|
||||||
{
|
{
|
||||||
llassert(!mOutboxId.isNull());
|
LLViewerInventoryCategory* category = gInventory.getCategory(mOutboxId);
|
||||||
|
if (mOutboxId.notNull() && category)
|
||||||
if (mOutboxInventoryPanel)
|
|
||||||
{
|
{
|
||||||
mOutboxInventoryPanel->requestSort();
|
fetchOutboxContents();
|
||||||
|
updateView();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cleanOutbox();
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchOutboxContents();
|
|
||||||
|
|
||||||
updateView();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLFloaterOutbox::importReportResults(U32 status, const LLSD& content)
|
void LLFloaterOutbox::importReportResults(U32 status, const LLSD& content)
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
void setupOutbox();
|
void setupOutbox();
|
||||||
|
void cleanOutbox();
|
||||||
void fetchOutboxContents();
|
void fetchOutboxContents();
|
||||||
|
|
||||||
void importReportResults(U32 status, const LLSD& content);
|
void importReportResults(U32 status, const LLSD& content);
|
||||||
|
|||||||
@@ -405,6 +405,66 @@ void LLInventoryModel::unlockDirectDescendentArrays(const LLUUID& cat_id)
|
|||||||
mItemLock[cat_id] = false;
|
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
|
// findCategoryUUIDForType() returns the uuid of the category that
|
||||||
// specifies 'type' as what it defaults to containing. The category is
|
// specifies 'type' as what it defaults to containing. The category is
|
||||||
// not necessarily only for that type. *NOTE: This will create a new
|
// not necessarily only for that type. *NOTE: This will create a new
|
||||||
|
|||||||
@@ -275,6 +275,11 @@ public:
|
|||||||
LLViewerInventoryItem* getLinkedItem(const LLUUID& object_id) const;
|
LLViewerInventoryItem* getLinkedItem(const LLUUID& object_id) const;
|
||||||
|
|
||||||
LLUUID findCategoryByName(std::string name);
|
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:
|
private:
|
||||||
mutable LLPointer<LLViewerInventoryItem> mLastItem; // cache recent lookups
|
mutable LLPointer<LLViewerInventoryItem> mLastItem; // cache recent lookups
|
||||||
|
|
||||||
|
|||||||
@@ -690,15 +690,24 @@ void LLInventoryCategoriesObserver::changed(U32 mask)
|
|||||||
if (!mCategoryMap.size())
|
if (!mCategoryMap.size())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
std::vector<LLUUID> deleted_categories_ids;
|
||||||
|
|
||||||
for (category_map_t::iterator iter = mCategoryMap.begin();
|
for (category_map_t::iterator iter = mCategoryMap.begin();
|
||||||
iter != mCategoryMap.end();
|
iter != mCategoryMap.end();
|
||||||
++iter)
|
++iter)
|
||||||
{
|
{
|
||||||
const LLUUID& cat_id = (*iter).first;
|
const LLUUID& cat_id = (*iter).first;
|
||||||
|
LLCategoryData& cat_data = (*iter).second;
|
||||||
|
|
||||||
LLViewerInventoryCategory* category = gInventory.getCategory(cat_id);
|
LLViewerInventoryCategory* category = gInventory.getCategory(cat_id);
|
||||||
if (!category)
|
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;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const S32 version = category->getVersion();
|
const S32 version = category->getVersion();
|
||||||
const S32 expected_num_descendents = category->getDescendentCount();
|
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();
|
const S32 current_num_known_descendents = cats->count() + items->count();
|
||||||
|
|
||||||
LLCategoryData& cat_data = (*iter).second;
|
|
||||||
|
|
||||||
bool cat_changed = false;
|
bool cat_changed = false;
|
||||||
|
|
||||||
// If category version or descendents count has changed
|
// If category version or descendents count has changed
|
||||||
@@ -757,6 +764,12 @@ void LLInventoryCategoriesObserver::changed(U32 mask)
|
|||||||
if (cat_changed)
|
if (cat_changed)
|
||||||
cat_data.mCallback();
|
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)
|
bool LLInventoryCategoriesObserver::addCategory(const LLUUID& cat_id, callback_t cb)
|
||||||
|
|||||||
@@ -231,9 +231,11 @@ namespace LLMarketplaceImport
|
|||||||
llinfos << " SLM GET timer: " << slmGetTimer.getElapsedTimeF32() << llendl;
|
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) &&
|
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"))
|
if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
|
||||||
{
|
{
|
||||||
@@ -241,9 +243,9 @@ namespace LLMarketplaceImport
|
|||||||
}
|
}
|
||||||
sMarketplaceCookie.clear();
|
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);
|
sImportInProgress = (status == MarketplaceErrorCodes::IMPORT_PROCESSING);
|
||||||
@@ -306,13 +308,15 @@ namespace LLMarketplaceImport
|
|||||||
|
|
||||||
std::string url = getInventoryImportURL();
|
std::string url = getInventoryImportURL();
|
||||||
|
|
||||||
|
AIHTTPHeaders headers = LLViewerMedia::getHeaders();
|
||||||
if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
|
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();
|
slmGetTimer.start();
|
||||||
AIHTTPHeaders headers = LLViewerMedia::getHeaders();
|
|
||||||
LLHTTPClient::get(url, new LLImportGetResponder(), headers);
|
LLHTTPClient::get(url, new LLImportGetResponder(), headers);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -453,7 +457,10 @@ boost::signals2::connection LLMarketplaceInventoryImporter::setStatusReportCallb
|
|||||||
|
|
||||||
void LLMarketplaceInventoryImporter::initialize()
|
void LLMarketplaceInventoryImporter::initialize()
|
||||||
{
|
{
|
||||||
llassert(!mInitialized);
|
if (mInitialized)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!LLMarketplaceImport::hasSessionCookie())
|
if (!LLMarketplaceImport::hasSessionCookie())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ public:
|
|||||||
void initialize();
|
void initialize();
|
||||||
bool triggerImport();
|
bool triggerImport();
|
||||||
bool isImportInProgress() const { return mImportInProgress; }
|
bool isImportInProgress() const { return mImportInProgress; }
|
||||||
|
bool isInitialized() const { return mInitialized; }
|
||||||
U32 getMarketPlaceStatus() const { return mMarketPlaceStatus; }
|
U32 getMarketPlaceStatus() const { return mMarketPlaceStatus; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
Reference in New Issue
Block a user