summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llagentwearables.cpp2
-rw-r--r--indra/newview/llappearancemgr.cpp78
-rw-r--r--indra/newview/llappearancemgr.h11
-rw-r--r--indra/newview/llsidepanelappearance.cpp3
-rw-r--r--indra/newview/llsidepanelappearance.h1
-rw-r--r--indra/newview/skins/default/xui/en/panel_outfits_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/en/sidepanel_appearance.xml25
7 files changed, 107 insertions, 15 deletions
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 29530c9c05..f49f862045 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -2274,6 +2274,8 @@ void LLInitialWearablesFetch::processContents()
}
else
{
+ // if we're constructing the COF from the wearables message, we don't have a proper outfit link
+ LLAppearanceManager::instance().setOutfitDirty(true);
processWearablesMessage();
}
delete this;
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 1150d84feb..4d4a89bcd4 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -674,6 +674,10 @@ void LLAppearanceManager::updateAgentWearables(LLWearableHoldingPattern* holder,
void LLAppearanceManager::updateAppearanceFromCOF()
{
+ // update dirty flag to see if the state of the COF matches
+ // the saved outfit stored as a folder link
+ updateIsDirty();
+
dumpCat(getCOF(),"COF, start");
bool follow_folder_links = true;
@@ -1005,7 +1009,9 @@ void LLAppearanceManager::addCOFItemLink(const LLInventoryItem *item, bool do_up
if (linked_already)
{
if (do_update)
+ {
LLAppearanceManager::updateAppearanceFromCOF();
+ }
return;
}
else
@@ -1059,6 +1065,75 @@ void LLAppearanceManager::removeCOFItemLinks(const LLUUID& item_id, bool do_upda
}
}
+void LLAppearanceManager::updateIsDirty()
+{
+ LLUUID cof = getCOF();
+ LLUUID base_outfit;
+
+ // find base outfit link
+ const LLViewerInventoryItem* base_outfit_item = getBaseOutfitLink();
+ LLViewerInventoryCategory* catp = NULL;
+ if (base_outfit_item && base_outfit_item->getIsLinkType())
+ {
+ catp = base_outfit_item->getLinkedCategory();
+ }
+ if(catp && catp->getPreferredType() == LLFolderType::FT_OUTFIT)
+ {
+ base_outfit = catp->getUUID();
+ }
+
+ if(base_outfit.isNull())
+ {
+ // no outfit link found, display "unsaved outfit"
+ mOutfitIsDirty = true;
+ }
+ else
+ {
+ LLInventoryModel::cat_array_t cof_cats;
+ LLInventoryModel::item_array_t cof_items;
+ gInventory.collectDescendents(cof, cof_cats, cof_items,
+ LLInventoryModel::EXCLUDE_TRASH);
+
+ LLInventoryModel::cat_array_t outfit_cats;
+ LLInventoryModel::item_array_t outfit_items;
+ gInventory.collectDescendents(base_outfit, outfit_cats, outfit_items,
+ LLInventoryModel::EXCLUDE_TRASH);
+
+ if(outfit_items.count() != cof_items.count() -1)
+ {
+ // Current outfit folder should have one more item than the outfit folder.
+ // this one item is the link back to the outfit folder itself.
+ mOutfitIsDirty = true;
+ }
+ else
+ {
+ typedef std::set<LLUUID> item_set_t;
+ item_set_t cof_set;
+ item_set_t outfit_set;
+
+ // sort COF items by UUID
+ for (S32 i = 0; i < cof_items.count(); ++i)
+ {
+ LLViewerInventoryItem *item = cof_items.get(i);
+ // don't add the base outfit link to the list of objects we're comparing
+ if(item != base_outfit_item)
+ {
+ cof_set.insert(item->getLinkedUUID());
+ }
+ }
+
+ // sort outfit folder by UUID
+ for (S32 i = 0; i < outfit_items.count(); ++i)
+ {
+ LLViewerInventoryItem *item = outfit_items.get(i);
+ outfit_set.insert(item->getLinkedUUID());
+ }
+
+ mOutfitIsDirty = (outfit_set != cof_set);
+ }
+ }
+}
+
//#define DUMP_CAT_VERBOSE
void LLAppearanceManager::dumpCat(const LLUUID& cat_id, const std::string& msg)
@@ -1095,7 +1170,8 @@ void LLAppearanceManager::dumpItemArray(const LLInventoryModel::item_array_t& it
}
LLAppearanceManager::LLAppearanceManager():
- mAttachmentInvLinkEnabled(false)
+ mAttachmentInvLinkEnabled(false),
+ mOutfitIsDirty(false)
{
}
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index 11b910ee11..b954968998 100644
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -96,6 +96,16 @@ public:
// Add COF link to ensemble folder.
void addEnsembleLink(LLInventoryCategory* item, bool do_update = true);
+ //has the current outfit changed since it was loaded?
+ bool isOutfitDirty() { return mOutfitIsDirty; }
+
+ // set false if you just loaded the outfit, true otherwise
+ void setOutfitDirty(bool isDirty) { mOutfitIsDirty = isDirty; }
+
+ // manually compare ouftit folder link to COF to see if outfit has changed.
+ // should only be necessary to do on initial login.
+ void updateIsDirty();
+
protected:
LLAppearanceManager();
~LLAppearanceManager();
@@ -120,6 +130,7 @@ private:
std::set<LLUUID> mRegisteredAttachments;
bool mAttachmentInvLinkEnabled;
+ bool mOutfitIsDirty;
};
#define SUPPORT_ENSEMBLES 0
diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp
index 0aefebce10..0a1f7ad0da 100644
--- a/indra/newview/llsidepanelappearance.cpp
+++ b/indra/newview/llsidepanelappearance.cpp
@@ -151,6 +151,8 @@ BOOL LLSidepanelAppearance::postBuild()
}
mCurrentLookName = getChild<LLTextBox>("currentlook_name");
+
+ mOutfitDirtyTag = getChild<LLTextBox>("currentlook_title");
mCurrOutfitPanel = getChild<LLPanel>("panel_currentlook");
@@ -316,6 +318,7 @@ void LLSidepanelAppearance::updateVerbs()
void LLSidepanelAppearance::refreshCurrentOutfitName(const std::string& name)
{
+ mOutfitDirtyTag->setVisible(LLAppearanceManager::getInstance()->isOutfitDirty());
if (name == "")
{
const LLViewerInventoryItem *outfit_link = LLAppearanceManager::getInstance()->getBaseOutfitLink();
diff --git a/indra/newview/llsidepanelappearance.h b/indra/newview/llsidepanelappearance.h
index 8ef2088eda..9524b0ece9 100644
--- a/indra/newview/llsidepanelappearance.h
+++ b/indra/newview/llsidepanelappearance.h
@@ -86,6 +86,7 @@ private:
LLPanel* mCurrOutfitPanel;
LLTextBox* mCurrentLookName;
+ LLTextBox* mOutfitDirtyTag;
// Used to make sure the user's inventory is in memory.
LLCurrentlyWornFetchObserver* mFetchWorn;
diff --git a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml
index 7e512f9594..27ab98177c 100644
--- a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml
@@ -93,7 +93,7 @@
<button
follows="bottom|left"
height="23"
- label="Make Outfit"
+ label="Save Outfit"
layout="topleft"
name="make_outfit_btn"
tool_tip="Save appearance as an outfit"
diff --git a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml
index 44248eedd5..fab1f11273 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml
@@ -52,25 +52,25 @@ width="333">
text_color="white"
top="3"
use_ellipses="true"
- width="290"
+ width="305"
follows="top|left"
word_wrap="true"
mouse_opaque="false"
name="currentlook_name">
MyOutfit With a really Long Name like MOOSE
</text>
- <!-- <text
- text_color="LtGray_50"
- width="290"
- left="40"
+ <text
+ font="SansSerifSmall"
+ text_color="White_50"
+ width="300"
height="1"
follows="top|left"
layout="topleft"
- top_pad="-2"
+ top_pad="5"
mouse_opaque="false"
name="currentlook_title" >
- (current outfit)
- </text>-->
+ (unsaved)
+ </text>
</panel>
<filter_editor
height="23"
@@ -80,18 +80,18 @@ width="333">
label="Filter Outfits"
max_length="300"
name="Filter"
- top_pad="0"
+ top_pad="10"
width="303" />
<panel
class="panel_outfits_inventory"
filename="panel_outfits_inventory.xml"
name="panel_outfits_inventory"
- height="515"
+ height="505"
min_height="410"
width="320"
+ left="0"
top_pad="0"
- follows="all"
- />
+ follows="all" />
<!-- <button
follows="bottom|left"
height="23"
@@ -120,4 +120,3 @@ width="333">
top="35"
visible="false" />
</panel>
-