From a38bc63da24994b51cfd3487d4011c8e608cd41d Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Sun, 6 Apr 2014 22:03:58 -0700
Subject: DD-15 : Allow version folder to be made active/inactive, add new
 methods to marketplace to make all that a bit more clear and clean

---
 indra/newview/llinventorybridge.cpp      |  74 +++++++++++++-------
 indra/newview/llinventoryfunctions.cpp   |  20 +++++-
 indra/newview/llinventoryfunctions.h     |   1 +
 indra/newview/llmarketplacefunctions.cpp | 112 ++++++++++++++++++++++++++-----
 indra/newview/llmarketplacefunctions.h   |  26 ++++---
 5 files changed, 179 insertions(+), 54 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index cd3e51a0ea..9c9f195875 100755
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -851,24 +851,17 @@ void LLInvFVBridge::addMarketplaceContextMenuOptions(U32 flags,
 {
     S32 depth = depth_nesting_in_marketplace(mUUID);
     llinfos << "Merov : adding marketplace menu at depth = " << depth << llendl;
-    if (depth <= 1)
+    if (depth == 1)
     {
-        // Options available at the Listing Folder level only
+        // Options available at the Listing Folder level
         items.push_back(std::string("Marketplace Add Listing"));
         items.push_back(std::string("Marketplace Attach Listing"));
-        if (LLMarketplaceData::instance().isListed(mUUID))
-        {
-			disabled_items.push_back(std::string("Marketplace Add Listing"));
-			disabled_items.push_back(std::string("Marketplace Attach Listing"));
-        }
-    }
-    if (depth <= 2)
-    {
-        // Options available at the Listing Folder and Version Folder levels
         items.push_back(std::string("Marketplace Activate"));
         items.push_back(std::string("Marketplace Deactivate"));
         if (LLMarketplaceData::instance().isListed(mUUID))
         {
+			disabled_items.push_back(std::string("Marketplace Add Listing"));
+			disabled_items.push_back(std::string("Marketplace Attach Listing"));
             if (LLMarketplaceData::instance().getActivationState(mUUID))
             {
                 disabled_items.push_back(std::string("Marketplace Activate"));
@@ -884,9 +877,28 @@ void LLInvFVBridge::addMarketplaceContextMenuOptions(U32 flags,
 			disabled_items.push_back(std::string("Marketplace Deactivate"));
         }
     }
+    if (depth == 2)
+    {
+        // Options available at the Version Folder levels
+        LLInventoryObject* object = gInventory.getObject(mUUID);
+        if (LLMarketplaceData::instance().isListed(object->getParentUUID()))
+        {
+            items.push_back(std::string("Marketplace Activate"));
+            items.push_back(std::string("Marketplace Deactivate"));
+            if (LLMarketplaceData::instance().getActivationState(mUUID))
+            {
+                disabled_items.push_back(std::string("Marketplace Activate"));
+            }
+            else
+            {
+                disabled_items.push_back(std::string("Marketplace Deactivate"));
+            }
+        }
+    }
     // Options available at all levels on all items
     items.push_back(std::string("Marketplace Show Listing"));
-    if (!LLMarketplaceData::instance().isListed(mUUID))
+    LLUUID listing_folder_id = nested_parent_id(mUUID,depth);
+    if (!LLMarketplaceData::instance().isListed(listing_folder_id))
     {
         disabled_items.push_back(std::string("Marketplace Show Listing"));
     }
@@ -2011,17 +2023,9 @@ void LLFolderBridge::buildDisplayName() const
 
 std::string LLFolderBridge::getLabelSuffix() const
 {
-    // *TODO : We need to display some suffix also for the version folder!
-    /*
-     LLInventoryCategory* cat = gInventory.getCategory(getUUID());
-     if(cat)
-     {
-     const LLUUID& parent_folder_id = cat->getParentUUID();
-     accessories = (parent_folder_id == gInventory.getLibraryRootFolderID());
-     }
-     */
     if (isMarketplaceListingsFolder())
     {
+        // Listing folder case
         if (LLMarketplaceData::instance().isListed(getUUID()))
         {
             //llinfos << "Merov : in merchant folder and listed : id = " << getUUID() << llendl;
@@ -2037,6 +2041,17 @@ std::string LLFolderBridge::getLabelSuffix() const
             }
             return LLInvFVBridge::getLabelSuffix() + suffix;
         }
+        // Version folder case
+        else if (LLMarketplaceData::instance().isVersionFolder(getUUID()))
+        {
+            std::string suffix;
+            if (LLMarketplaceData::instance().getActivationState(getUUID()))
+            {
+                suffix += " (" +  LLTrans::getString("MarketplaceActive") + ")";
+            }
+            return LLInvFVBridge::getLabelSuffix() + suffix;
+        }
+        // Stock folder case
         else if (getCategory()->getPreferredType() == LLFolderType::FT_MARKETPLACE_STOCK)
         {
             //llinfos << "Merov : getLabelSuffix : stock folder : name = " << getCategory()->getName() << ", stock = " << getCategory()->getDescendentCount() << llendl;
@@ -3121,7 +3136,17 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
 	}
 	else if ("marketplace_activate" == action)
 	{
-        LLMarketplaceData::instance().setActivation(mUUID,true);
+        S32 depth = depth_nesting_in_marketplace(mUUID);
+        if (depth == 2)
+        {
+			LLInventoryCategory* category = gInventory.getCategory(mUUID);
+            LLMarketplaceData::instance().setVersionFolderID(category->getParentUUID(), mUUID);
+            LLMarketplaceData::instance().setActivation(mUUID,true);
+        }
+        else if (depth == 1)
+        {
+            LLMarketplaceData::instance().setActivation(mUUID,true);
+        }
 		return;
 	}
 	else if ("marketplace_deactivate" == action)
@@ -3131,14 +3156,13 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
 	}
 	else if ("marketplace_add_listing" == action)
 	{
-        // *TODO : Do something a bit smarter...
-        LLMarketplaceData::instance().addTestItem(mUUID);
+        LLMarketplaceData::instance().addListing(mUUID);
 		return;
 	}
 	else if ("marketplace_attach_listing" == action)
 	{
         // *TODO : Get a list of listing IDs and let the user choose one, delist the old one and relist the new one
-        LLMarketplaceData::instance().addTestItem(mUUID);
+        LLMarketplaceData::instance().addListing(mUUID);
 		return;
 	}
 	else if ("marketplace_show_listing" == action)
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index e57519d67a..aef3bc9cca 100755
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -125,8 +125,11 @@ void update_marketplace_category(const LLUUID& cat_id)
     // for all observers of the folder to, possibly, change the display label of said folder.
     // At least that's the status for the moment so, even if that function seems small, we
     // prefer to encapsulate that behavior here.
-    gInventory.addChangedMask(LLInventoryObserver::LABEL, cat_id);
-	gInventory.notifyObservers();
+    if (cat_id.notNull())
+    {
+        gInventory.addChangedMask(LLInventoryObserver::LABEL, cat_id);
+        gInventory.notifyObservers();
+    }
 }
 
 void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::string& new_name)
@@ -732,6 +735,19 @@ S32 depth_nesting_in_marketplace(LLUUID cur_uuid)
     return depth;
 }
 
+LLUUID nested_parent_id(LLUUID cur_uuid, S32 depth)
+{
+    LLInventoryObject* cur_object = gInventory.getObject(cur_uuid);
+    cur_uuid = (depth < 1 ? LLUUID::null : cur_uuid);
+    while (depth > 1)
+    {
+        depth--;
+        cur_uuid = cur_object->getParentUUID();
+        cur_object = gInventory.getCategory(cur_uuid);
+    }
+    return cur_uuid;
+}
+
 void move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_folder, bool copy)
 {
     // Get the marketplace listings, exit with error if none
diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h
index aab4db8adf..69219c7c42 100755
--- a/indra/newview/llinventoryfunctions.h
+++ b/indra/newview/llinventoryfunctions.h
@@ -77,6 +77,7 @@ void move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUU
 bool has_correct_permissions_for_sale(LLInventoryCategory* cat);
 void validate_marketplacelistings(LLInventoryCategory* inv_cat);
 S32  depth_nesting_in_marketplace(LLUUID cur_uuid);
+LLUUID nested_parent_id(LLUUID cur_uuid, S32 depth);
 
 /**                    Miscellaneous global functions
  **                                                                            **
diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index 6f35cc217d..29ce5361f0 100755
--- a/indra/newview/llmarketplacefunctions.cpp
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -535,25 +535,25 @@ void LLMarketplaceInventoryImporter::updateImport()
 
 // Tuple == Item
 LLMarketplaceTuple::LLMarketplaceTuple() :
-    mFolderListingId(),
+    mListingFolderId(),
     mListingId(""),
-    mActiveVersionFolderId(),
+    mVersionFolderId(),
     mIsActive(false)
 {
 }
 
 LLMarketplaceTuple::LLMarketplaceTuple(const LLUUID& folder_id) :
-    mFolderListingId(folder_id),
+    mListingFolderId(folder_id),
     mListingId(""),
-    mActiveVersionFolderId(),
+    mVersionFolderId(),
     mIsActive(false)
 {
 }
 
 LLMarketplaceTuple::LLMarketplaceTuple(const LLUUID& folder_id, std::string listing_id, const LLUUID& version_id, bool is_listed) :
-    mFolderListingId(folder_id),
+    mListingFolderId(folder_id),
     mListingId(listing_id),
-    mActiveVersionFolderId(version_id),
+    mVersionFolderId(version_id),
     mIsActive(is_listed)
 {
 }
@@ -564,28 +564,85 @@ LLMarketplaceData::LLMarketplaceData()
 {
 }
 
+// Creation / Deletion
+bool LLMarketplaceData::addListing(const LLUUID& folder_id)
+{
+    if (isListed(folder_id))
+    {
+        // Listing already exists -> exit with error
+        return false;
+    }
+	mMarketplaceItems[folder_id] = LLMarketplaceTuple(folder_id);
+    update_marketplace_category(folder_id);
+    return true;
+}
+
+bool LLMarketplaceData::deleteListing(const LLUUID& folder_id)
+{
+    if (!isListed(folder_id))
+    {
+        // Listing doesn't exist -> exit with error
+        return false;
+    }
+	mMarketplaceItems.erase(folder_id);
+    update_marketplace_category(folder_id);
+    return true;
+}
+
 // Accessors
 bool LLMarketplaceData::getActivationState(const LLUUID& folder_id)
 {
-    marketplace_items_list_t::iterator it = mMarketplaceItems.find(folder_id);
-    return (it == mMarketplaceItems.end() ? false : (it->second).mIsActive);
+    // Listing folder case
+    if (isListed(folder_id))
+    {
+        marketplace_items_list_t::iterator it = mMarketplaceItems.find(folder_id);
+        return (it->second).mIsActive;
+    }
+    // We need to iterate through the list to check it's not a version folder
+    marketplace_items_list_t::iterator it = mMarketplaceItems.begin();
+    while (it != mMarketplaceItems.end())
+    {
+        if ((it->second).mVersionFolderId == folder_id)
+        {
+            return (it->second).mIsActive;
+        }
+        it++;
+    }
+    return false;
 }
+
 std::string LLMarketplaceData::getListingID(const LLUUID& folder_id)
 {
     marketplace_items_list_t::iterator it = mMarketplaceItems.find(folder_id);
     return (it == mMarketplaceItems.end() ? "" : (it->second).mListingId);
 }
+
 LLUUID LLMarketplaceData::getVersionFolderID(const LLUUID& folder_id)
 {
     marketplace_items_list_t::iterator it = mMarketplaceItems.find(folder_id);
-    return (it == mMarketplaceItems.end() ? LLUUID::null : (it->second).mActiveVersionFolderId);
+    return (it == mMarketplaceItems.end() ? LLUUID::null : (it->second).mVersionFolderId);
 }
+
 bool LLMarketplaceData::isListed(const LLUUID& folder_id)
 {
     marketplace_items_list_t::iterator it = mMarketplaceItems.find(folder_id);
     return (it != mMarketplaceItems.end());
 }
 
+bool LLMarketplaceData::isVersionFolder(const LLUUID& folder_id)
+{
+    marketplace_items_list_t::iterator it = mMarketplaceItems.begin();
+    while (it != mMarketplaceItems.end())
+    {
+        if ((it->second).mVersionFolderId == folder_id)
+        {
+            return true;
+        }
+        it++;
+    }
+    return false;
+}
+
 // Modifiers
 bool LLMarketplaceData::setListingID(const LLUUID& folder_id, std::string listing_id)
 {
@@ -601,6 +658,7 @@ bool LLMarketplaceData::setListingID(const LLUUID& folder_id, std::string listin
         return true;
     }
 }
+
 bool LLMarketplaceData::setVersionFolderID(const LLUUID& folder_id, const LLUUID& version_id)
 {
     marketplace_items_list_t::iterator it = mMarketplaceItems.find(folder_id);
@@ -610,24 +668,42 @@ bool LLMarketplaceData::setVersionFolderID(const LLUUID& folder_id, const LLUUID
     }
     else
     {
-        (it->second).mActiveVersionFolderId = version_id;
-        update_marketplace_category(folder_id);
+        LLUUID old_version_id = (it->second).mVersionFolderId;
+        if (old_version_id != version_id)
+        {
+            (it->second).mVersionFolderId = version_id;
+            update_marketplace_category(old_version_id);
+            update_marketplace_category(version_id);
+        }
         return true;
     }
 }
+
 bool LLMarketplaceData::setActivation(const LLUUID& folder_id, bool activate)
 {
-    marketplace_items_list_t::iterator it = mMarketplaceItems.find(folder_id);
-    if (it == mMarketplaceItems.end())
-    {
-        return false;
-    }
-    else
+    // Listing folder case
+    if (isListed(folder_id))
     {
+        marketplace_items_list_t::iterator it = mMarketplaceItems.find(folder_id);
         (it->second).mIsActive = activate;
-        update_marketplace_category(folder_id);
+        update_marketplace_category((it->second).mListingFolderId);
+        update_marketplace_category((it->second).mVersionFolderId);
         return true;
     }
+    // We need to iterate through the list to check it's not a version folder
+    marketplace_items_list_t::iterator it = mMarketplaceItems.begin();
+    while (it != mMarketplaceItems.end())
+    {
+        if ((it->second).mVersionFolderId == folder_id)
+        {
+            (it->second).mIsActive = activate;
+            update_marketplace_category((it->second).mListingFolderId);
+            update_marketplace_category((it->second).mVersionFolderId);
+            return true;
+        }
+        it++;
+    }
+    return false;
 }
 
 // Test methods
diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h
index 00840c6e23..d76072da1f 100755
--- a/indra/newview/llmarketplacefunctions.h
+++ b/indra/newview/llmarketplacefunctions.h
@@ -113,7 +113,8 @@ private:
 // * implement the Marketplace API (TBD)
 // * cache the current Marketplace data (tuples)
 // * provide methods to get Marketplace data on any inventory item
-// * signal marketplace updates to inventory
+// * set Marketplace data
+// * signal Marketplace updates to inventory
 class LLMarketplaceData;
 
 // A Marketplace item is known by its tuple
@@ -128,15 +129,16 @@ public:
     
 private:
     // Representation of a marketplace item in the Marketplace DB (well, what we know of it...)
-    LLUUID mFolderListingId;
+    LLUUID mListingFolderId;
     std::string mListingId;
-    LLUUID mActiveVersionFolderId;
+    LLUUID mVersionFolderId;
     bool mIsActive;
 };
-// Note: the folder UUID is used as a key to this map. It could therefore be taken off the object themselves
+// Note: The listing folder UUID is used as a key to this map. It could therefore be taken off the LLMarketplaceTuple objects themselves
 typedef std::map<LLUUID, LLMarketplaceTuple> marketplace_items_list_t;
 
-// There's one and only one possible set of Marketplace data per agent and per session
+// Session cache of Marketplace tuples
+// Note: There's one and only one possible set of Marketplace dataset per agent and per session
 class LLMarketplaceData
     : public LLSingleton<LLMarketplaceData>
 {
@@ -145,14 +147,20 @@ public:
     
     bool isEmpty() { return (mMarketplaceItems.size() == 0); }
     
-    // Access Marketplace Data : each method returns a default value if the folder_id can't be found
+    // Probe the Marketplace data set to identify folders
+    bool isListed(const LLUUID& folder_id); // returns true if folder_id is a Listing folder
+    bool isVersionFolder(const LLUUID& folder_id); // returns true if folder_id is a Version folder
+    
+    // Create/Delete Marketplace data set  : each method returns true if the function succeeds, false if error
+    bool addListing(const LLUUID& folder_id);
+    bool deleteListing(const LLUUID& folder_id);
+
+    // Access Marketplace data set  : each method returns a default value if the folder_id can't be found
     bool getActivationState(const LLUUID& folder_id);
     std::string getListingID(const LLUUID& folder_id);
     LLUUID getVersionFolderID(const LLUUID& folder_id);
     
-    bool isListed(const LLUUID& folder_id); // returns true if folder_id is in the items map
-    
-    // Modify Marketplace Data : each method returns true if the function succeeds, false if error
+    // Modify Marketplace data set  : each method returns true if the function succeeds, false if error
     bool setListingID(const LLUUID& folder_id, std::string listing_id);
     bool setVersionFolderID(const LLUUID& folder_id, const LLUUID& version_id);
     bool setActivation(const LLUUID& folder_id, bool activate);
-- 
cgit v1.2.3