diff options
16 files changed, 147 insertions, 55 deletions
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 7b8f51ae3c..621e72ce38 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -560,21 +560,6 @@ void LLNotification::setResponseFunctor(const LLNotificationResponderPtr& respon mResponder = responder; } -bool LLNotification::payloadContainsAll(const std::vector<std::string>& required_fields) const -{ - for(std::vector<std::string>::const_iterator required_fields_it = required_fields.begin(); - required_fields_it != required_fields.end(); - required_fields_it++) - { - std::string required_field_name = *required_fields_it; - if( ! getPayload().has(required_field_name)) - { - return false; // a required field was not found - } - } - return true; // all required fields were found -} - bool LLNotification::isEquivalentTo(LLNotificationPtr that) const { if (this->mTemplatep->mName != that->mTemplatep->mName) @@ -583,11 +568,22 @@ bool LLNotification::isEquivalentTo(LLNotificationPtr that) const } if (this->mTemplatep->mUnique) { + const LLSD& these_substitutions = this->getSubstitutions(); + const LLSD& those_substitutions = that->getSubstitutions(); + // highlander bit sez there can only be one of these - return - this->payloadContainsAll(that->mTemplatep->mUniqueContext) && - that->payloadContainsAll(this->mTemplatep->mUniqueContext); + for (std::vector<std::string>::const_iterator it = mTemplatep->mUniqueContext.begin(), end_it = mTemplatep->mUniqueContext.end(); + it != end_it; + ++it) + { + if (these_substitutions.get(*it).asString() != those_substitutions.get(*it).asString()) + { + return false; + } + } + return true; } + return false; } diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index c942a32512..8bfada0e71 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -400,8 +400,6 @@ private: void cancel(); - bool payloadContainsAll(const std::vector<std::string>& required_fields) const; - public: // constructor from a saved notification diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index ce022ac840..547dfd7006 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -55,6 +55,25 @@ #include "llviewerregion.h" #include "llwearablelist.h" +// RAII thingy to guarantee that a variable gets reset when the Setter +// goes out of scope. More general utility would be handy - TODO: +// check boost. +class BoolSetter +{ +public: + BoolSetter(bool& var): + mVar(var) + { + mVar = true; + } + ~BoolSetter() + { + mVar = false; + } +private: + bool& mVar; +}; + char ORDER_NUMBER_SEPARATOR('@'); class LLOutfitUnLockTimer: public LLEventTimer @@ -1537,16 +1556,89 @@ bool sort_by_description(const LLInventoryItem* item1, const LLInventoryItem* it return item1->LLInventoryItem::getDescription() < item2->LLInventoryItem::getDescription(); } +void item_array_diff(LLInventoryModel::item_array_t& full_list, + LLInventoryModel::item_array_t& keep_list, + LLInventoryModel::item_array_t& kill_list) + +{ + for (LLInventoryModel::item_array_t::iterator it = full_list.begin(); + it != full_list.end(); + ++it) + { + LLViewerInventoryItem *item = *it; + if (keep_list.find(item) < 0) // Why on earth does LLDynamicArray need to redefine find()? + { + kill_list.push_back(item); + } + } +} + +void LLAppearanceMgr::enforceItemCountLimits() +{ + S32 purge_count = 0; + + LLInventoryModel::item_array_t body_items; + getDescendentsOfAssetType(getCOF(), body_items, LLAssetType::AT_BODYPART, false); + LLInventoryModel::item_array_t curr_body_items = body_items; + removeDuplicateItems(body_items); + filterWearableItems(body_items, 1); + LLInventoryModel::item_array_t kill_body_items; + item_array_diff(curr_body_items,body_items,kill_body_items); + for (LLInventoryModel::item_array_t::iterator it = kill_body_items.begin(); + it != kill_body_items.end(); + ++it) + { + LLViewerInventoryItem *item = *it; + llinfos << "purging dup body part " << item->getName() << llendl; + gInventory.purgeObject(item->getUUID()); + purge_count++; + } + + LLInventoryModel::item_array_t wear_items; + getDescendentsOfAssetType(getCOF(), wear_items, LLAssetType::AT_CLOTHING, false); + LLInventoryModel::item_array_t curr_wear_items = wear_items; + removeDuplicateItems(wear_items); + filterWearableItems(wear_items, LLAgentWearables::MAX_CLOTHING_PER_TYPE); + LLInventoryModel::item_array_t kill_wear_items; + item_array_diff(curr_wear_items,wear_items,kill_wear_items); + for (LLInventoryModel::item_array_t::iterator it = kill_wear_items.begin(); + it != kill_wear_items.end(); + ++it) + { + LLViewerInventoryItem *item = *it; + llinfos << "purging excess clothing item " << item->getName() << llendl; + gInventory.purgeObject(item->getUUID()); + purge_count++; + } + + if (purge_count>0) + { + gInventory.notifyObservers(); + } +} + void LLAppearanceMgr::updateAppearanceFromCOF() { + if (mIsInUpdateAppearanceFromCOF) + { + llwarns << "Called updateAppearanceFromCOF inside updateAppearanceFromCOF, skipping" << llendl; + return; + } + + BoolSetter setIsInUpdateAppearanceFromCOF(mIsInUpdateAppearanceFromCOF); + + llinfos << "starting" << llendl; + //checking integrity of the COF in terms of ordering of wearables, //checking and updating links' descriptions of wearables in the COF (before analyzed for "dirty" state) updateClothingOrderingInfo(); + // Remove duplicate or excess wearables. Should normally be enforced at the UI level, but + // this should catch anything that gets through. + enforceItemCountLimits(); + // update dirty flag to see if the state of the COF matches // the saved outfit stored as a folder link - llinfos << "starting" << llendl; - updateIsDirty(); dumpCat(getCOF(),"COF, start"); @@ -2493,7 +2585,8 @@ void LLAppearanceMgr::dumpItemArray(const LLInventoryModel::item_array_t& items, LLAppearanceMgr::LLAppearanceMgr(): mAttachmentInvLinkEnabled(false), - mOutfitIsDirty(false) + mOutfitIsDirty(false), + mIsInUpdateAppearanceFromCOF(false) { LLOutfitObserver& outfit_observer = LLOutfitObserver::instance(); diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 61779d5c0e..afd1bf3ade 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -66,6 +66,7 @@ public: void renameOutfit(const LLUUID& outfit_id); void takeOffOutfit(const LLUUID& cat_id); void addCategoryToCurrentOutfit(const LLUUID& cat_id); + void enforceItemCountLimits(); // Copy all items and the src category itself. void shallowCopyCategory(const LLUUID& src_id, const LLUUID& dst_id, @@ -203,6 +204,7 @@ private: std::set<LLUUID> mRegisteredAttachments; bool mAttachmentInvLinkEnabled; bool mOutfitIsDirty; + bool mIsInUpdateAppearanceFromCOF; // to detect recursive calls. /** * Lock for blocking operations on outfit until server reply or timeout exceed diff --git a/indra/newview/skins/default/xui/da/floater_world_map.xml b/indra/newview/skins/default/xui/da/floater_world_map.xml index 4dec9a9ba7..ca18faa0bb 100644 --- a/indra/newview/skins/default/xui/da/floater_world_map.xml +++ b/indra/newview/skins/default/xui/da/floater_world_map.xml @@ -35,11 +35,11 @@ <text name="pg_label"> Generelt </text> - <check_box name="event_mature_chk"/> - <text name="mature_label"> + <check_box name="events_mature_chk"/> + <text name="events_mature_label"> Moderat </text> - <text name="adult_label"> + <text name="events_adult_label"> Voksent </text> </panel> diff --git a/indra/newview/skins/default/xui/de/floater_world_map.xml b/indra/newview/skins/default/xui/de/floater_world_map.xml index fb3a4ba9b5..f54d8c3328 100644 --- a/indra/newview/skins/default/xui/de/floater_world_map.xml +++ b/indra/newview/skins/default/xui/de/floater_world_map.xml @@ -39,12 +39,12 @@ <text name="pg_label"> Generell </text> - <check_box label="Mature" name="event_mature_chk"/> - <text name="mature_label"> + <check_box label="Mature" name="events_mature_chk"/> + <text name="events_mature_label"> Moderat </text> - <check_box label="Adult" name="event_adult_chk"/> - <text name="adult_label"> + <check_box label="Adult" name="events_adult_chk"/> + <text name="events_adult_label"> Adult </text> </panel> diff --git a/indra/newview/skins/default/xui/en/floater_stats.xml b/indra/newview/skins/default/xui/en/floater_stats.xml index f9dacf0207..b87cb9a433 100644 --- a/indra/newview/skins/default/xui/en/floater_stats.xml +++ b/indra/newview/skins/default/xui/en/floater_stats.xml @@ -361,8 +361,7 @@ <stat_view name="physicsdetail" label="Physics Details" - show_label="true" - display_children="false"> + show_label="true"> <stat_bar name="physicspinnedtasks" label="Pinned Objects" diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 88732fee7d..290c8c55a9 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -4886,6 +4886,10 @@ If you want to view streaming media on parcels that support it you should go to persist="true" type="notify"> No Media Plugin was found to handle the "[MIME_TYPE]" mime type. Media of this type will be unavailable. + <unique> + <context key="[MIME_TYPE]"/> + </unique> + </notification> <notification icon="alertmodal.tga" diff --git a/indra/newview/skins/default/xui/en/panel_outfits_list.xml b/indra/newview/skins/default/xui/en/panel_outfits_list.xml index 62b23aa74c..27e23440df 100644 --- a/indra/newview/skins/default/xui/en/panel_outfits_list.xml +++ b/indra/newview/skins/default/xui/en/panel_outfits_list.xml @@ -16,7 +16,7 @@ bg_opaque_color="DkGray2" no_matched_tabs_text.value="Didn't find what you're looking for? Try [secondlife:///app/search/all/[SEARCH_TERM] Search]." no_matched_tabs_text.v_pad="10" - no_visible_tabs_text.value="There are no any outfits. Try [secondlife:///app/search/all/ Search]." + no_visible_tabs_text.value="..." follows="all" height="400" layout="topleft" diff --git a/indra/newview/skins/default/xui/es/floater_world_map.xml b/indra/newview/skins/default/xui/es/floater_world_map.xml index deda5b86c8..3135324816 100644 --- a/indra/newview/skins/default/xui/es/floater_world_map.xml +++ b/indra/newview/skins/default/xui/es/floater_world_map.xml @@ -35,11 +35,11 @@ <text name="pg_label"> General </text> - <check_box name="event_mature_chk"/> - <text name="mature_label"> + <check_box name="events_mature_chk"/> + <text name="events_mature_label"> Moderado </text> - <text name="adult_label"> + <text name="events_adult_label"> Adulto </text> </panel> diff --git a/indra/newview/skins/default/xui/fr/floater_world_map.xml b/indra/newview/skins/default/xui/fr/floater_world_map.xml index 4d500857ea..0047a3bb04 100644 --- a/indra/newview/skins/default/xui/fr/floater_world_map.xml +++ b/indra/newview/skins/default/xui/fr/floater_world_map.xml @@ -35,11 +35,11 @@ <text name="pg_label"> Général </text> - <check_box initial_value="true" name="event_mature_chk"/> - <text name="mature_label"> + <check_box initial_value="true" name="events_mature_chk"/> + <text name="events_mature_label"> Modéré </text> - <text name="adult_label"> + <text name="events_adult_label"> Adulte </text> </panel> diff --git a/indra/newview/skins/default/xui/it/floater_world_map.xml b/indra/newview/skins/default/xui/it/floater_world_map.xml index b07daac6fb..a6bd4ffbaf 100644 --- a/indra/newview/skins/default/xui/it/floater_world_map.xml +++ b/indra/newview/skins/default/xui/it/floater_world_map.xml @@ -35,11 +35,11 @@ <text name="pg_label"> Generale </text> - <check_box name="event_mature_chk"/> - <text name="mature_label"> + <check_box name="events_mature_chk"/> + <text name="events_mature_label"> Moderato </text> - <text name="adult_label"> + <text name="events_adult_label"> Adulto </text> </panel> diff --git a/indra/newview/skins/default/xui/ja/floater_world_map.xml b/indra/newview/skins/default/xui/ja/floater_world_map.xml index ce9e7d0777..62670251d6 100644 --- a/indra/newview/skins/default/xui/ja/floater_world_map.xml +++ b/indra/newview/skins/default/xui/ja/floater_world_map.xml @@ -39,12 +39,12 @@ <text name="pg_label"> General </text> - <check_box initial_value="true" label="Mature" name="event_mature_chk"/> - <text name="mature_label"> + <check_box initial_value="true" label="Mature" name="events_mature_chk"/> + <text name="events_mature_label"> Moderate </text> - <check_box label="Adult" name="event_adult_chk"/> - <text name="adult_label"> + <check_box label="Adult" name="events_adult_chk"/> + <text name="events_adult_label"> Adult </text> </panel> diff --git a/indra/newview/skins/default/xui/nl/floater_world_map.xml b/indra/newview/skins/default/xui/nl/floater_world_map.xml index bc14f92126..2fee2ecf05 100644 --- a/indra/newview/skins/default/xui/nl/floater_world_map.xml +++ b/indra/newview/skins/default/xui/nl/floater_world_map.xml @@ -26,8 +26,8 @@ Evenementen: </text> <check_box label="PG" name="event_chk"/> - <check_box label="Mature" name="event_mature_chk"/> - <check_box label="Adult" name="event_adult_chk"/> + <check_box label="Mature" name="events_mature_chk"/> + <check_box label="Adult" name="events_adult_chk"/> <combo_box label="Online vrienden" name="friend combo" tool_tip="Vriend die op kaart getoond wordt"> <combo_box.item name="item1" label="Online vrienden"/> </combo_box> diff --git a/indra/newview/skins/default/xui/pl/floater_world_map.xml b/indra/newview/skins/default/xui/pl/floater_world_map.xml index 05287ad42a..3e62393e7a 100644 --- a/indra/newview/skins/default/xui/pl/floater_world_map.xml +++ b/indra/newview/skins/default/xui/pl/floater_world_map.xml @@ -35,11 +35,11 @@ <text name="pg_label"> Ogólne </text> - <check_box name="event_mature_chk"/> - <text name="mature_label"> + <check_box name="events_mature_chk"/> + <text name="events_mature_label"> Moderuj </text> - <text name="adult_label"> + <text name="events_adult_label"> Adult </text> </panel> diff --git a/indra/newview/skins/default/xui/pt/floater_world_map.xml b/indra/newview/skins/default/xui/pt/floater_world_map.xml index 878d0b1973..3952b80269 100644 --- a/indra/newview/skins/default/xui/pt/floater_world_map.xml +++ b/indra/newview/skins/default/xui/pt/floater_world_map.xml @@ -39,12 +39,12 @@ <text name="pg_label"> Público geral </text> - <check_box label="Mature" name="event_mature_chk"/> - <text name="mature_label"> + <check_box label="Mature" name="events_mature_chk"/> + <text name="events_mature_label"> Moderado </text> - <check_box label="Adult" name="event_adult_chk"/> - <text name="adult_label"> + <check_box label="Adult" name="events_adult_chk"/> + <text name="events_adult_label"> Adulto </text> </panel> |