summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/CMakeLists.txt2
-rw-r--r--indra/newview/llagentwearablesfetch.cpp48
-rw-r--r--indra/newview/llappearancemgr.cpp10
-rw-r--r--indra/newview/llappearancemgr.h7
-rw-r--r--indra/newview/llappviewer.cpp11
-rw-r--r--indra/newview/llbottomtray.cpp6
-rw-r--r--indra/newview/llcofwearables.cpp16
-rw-r--r--indra/newview/llcofwearables.h3
-rw-r--r--indra/newview/llfilteredwearablelist.cpp46
-rw-r--r--indra/newview/llfilteredwearablelist.h9
-rw-r--r--indra/newview/llinventoryfunctions.cpp5
-rw-r--r--indra/newview/llinventoryfunctions.h35
-rw-r--r--indra/newview/llinventoryitemslist.h3
-rw-r--r--indra/newview/llnearbychatbar.cpp7
-rw-r--r--indra/newview/llnearbychatbar.h1
-rw-r--r--indra/newview/lloutfitslist.cpp78
-rw-r--r--indra/newview/lloutfitslist.h7
-rw-r--r--indra/newview/llpaneloutfitedit.cpp100
-rw-r--r--indra/newview/llpaneloutfitedit.h16
-rw-r--r--indra/newview/llpaneloutfitsinventory.cpp11
-rw-r--r--indra/newview/llpaneloutfitsinventory.h4
-rw-r--r--indra/newview/llsaveoutfitcombobtn.cpp97
-rw-r--r--indra/newview/llsaveoutfitcombobtn.h60
-rw-r--r--indra/newview/llwearableitemslist.cpp5
-rw-r--r--indra/newview/llwearableitemslist.h1
-rw-r--r--indra/newview/skins/default/textures/containers/Toolbar_Left_Flash.pngbin0 -> 356 bytes
-rw-r--r--indra/newview/skins/default/textures/containers/Toolbar_Middle_Flash.pngbin0 -> 316 bytes
-rw-r--r--indra/newview/skins/default/textures/containers/Toolbar_Right_Flash.pngbin0 -> 428 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Generic_Group_Large.pngbin7905 -> 7061 bytes
-rw-r--r--indra/newview/skins/default/textures/textures.xml3
-rw-r--r--indra/newview/skins/default/xui/en/floater_im_container.xml9
-rw-r--r--indra/newview/skins/default/xui/en/floater_search.xml1
-rw-r--r--indra/newview/skins/default/xui/en/menu_save_outfit.xml4
-rw-r--r--indra/newview/skins/default/xui/en/outfit_accordion_tab.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_tattoo.xml33
-rw-r--r--indra/newview/skins/default/xui/en/panel_outfit_edit.xml204
-rw-r--r--indra/newview/skins/default/xui/en/panel_outfits_inventory.xml33
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml15
-rw-r--r--indra/newview/skins/default/xui/en/widgets/button.xml1
-rw-r--r--indra/newview/skins/default/xui/en/widgets/tab_container.xml15
-rw-r--r--indra/newview/skins/default/xui/ja/strings.xml20
41 files changed, 672 insertions, 256 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 50d1491523..9ba44e787b 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -379,6 +379,7 @@ set(viewer_SOURCE_FILES
llregionposition.cpp
llremoteparcelrequest.cpp
llsavedsettingsglue.cpp
+ llsaveoutfitcombobtn.cpp
llscreenchannel.cpp
llscriptfloater.cpp
llscrollingpanelparam.cpp
@@ -894,6 +895,7 @@ set(viewer_HEADER_FILES
llresourcedata.h
llrootview.h
llsavedsettingsglue.h
+ llsaveoutfitcombobtn.h
llscreenchannel.h
llscriptfloater.h
llscrollingpanelparam.h
diff --git a/indra/newview/llagentwearablesfetch.cpp b/indra/newview/llagentwearablesfetch.cpp
index 43a0d48d8b..ef0b97d376 100644
--- a/indra/newview/llagentwearablesfetch.cpp
+++ b/indra/newview/llagentwearablesfetch.cpp
@@ -40,6 +40,50 @@
#include "llstartup.h"
#include "llvoavatarself.h"
+
+class LLOrderMyOutfitsOnDestroy: public LLInventoryCallback
+{
+public:
+ LLOrderMyOutfitsOnDestroy() {};
+
+ virtual ~LLOrderMyOutfitsOnDestroy()
+ {
+ const LLUUID& my_outfits_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
+ if (my_outfits_id.isNull()) return;
+
+ LLInventoryModel::cat_array_t* cats;
+ LLInventoryModel::item_array_t* items;
+ gInventory.getDirectDescendentsOf(my_outfits_id, cats, items);
+ if (!cats) return;
+
+ //My Outfits should at least contain saved initial outfit and one another outfit
+ if (cats->size() < 2)
+ {
+ llwarning("My Outfits category was not populated properly", 0);
+ return;
+ }
+
+ llinfos << "Starting updating My Outfits with wearables ordering information" << llendl;
+
+ for (LLInventoryModel::cat_array_t::iterator outfit_iter = cats->begin();
+ outfit_iter != cats->end(); ++outfit_iter)
+ {
+ const LLUUID& cat_id = (*outfit_iter)->getUUID();
+ if (cat_id.isNull()) continue;
+
+ // saved initial outfit already contains wearables ordering information
+ if (cat_id == LLAppearanceMgr::getInstance()->getBaseOutfitUUID()) continue;
+
+ LLAppearanceMgr::getInstance()->updateClothingOrderingInfo(cat_id);
+ }
+
+ llinfos << "Finished updating My Outfits with wearables ordering information" << llendl;
+ }
+
+ /* virtual */ void fire(const LLUUID& inv_item) {};
+};
+
+
LLInitialWearablesFetch::LLInitialWearablesFetch(const LLUUID& cof_id) :
LLInventoryFetchDescendentsObserver(cof_id)
{
@@ -483,6 +527,8 @@ void LLLibraryOutfitsFetch::contentsDone()
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t wearable_array;
+ LLPointer<LLOrderMyOutfitsOnDestroy> order_myoutfits_on_destroy = new LLOrderMyOutfitsOnDestroy;
+
for (uuid_vec_t::const_iterator folder_iter = mImportedClothingFolders.begin();
folder_iter != mImportedClothingFolders.end();
++folder_iter)
@@ -518,7 +564,7 @@ void LLLibraryOutfitsFetch::contentsDone()
item->getName(),
item->getDescription(),
LLAssetType::AT_LINK,
- NULL);
+ order_myoutfits_on_destroy);
}
}
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index c417f8bdf5..f27e632180 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -1790,10 +1790,16 @@ struct WearablesOrderComparator
U32 mControlSize;
};
-void LLAppearanceMgr::updateClothingOrderingInfo()
+void LLAppearanceMgr::updateClothingOrderingInfo(LLUUID cat_id)
{
+ if (cat_id.isNull())
+ {
+ cat_id = getCOF();
+ }
+
+ // COF is processed if cat_id is not specified
LLInventoryModel::item_array_t wear_items;
- getDescendentsOfAssetType(getCOF(), wear_items, LLAssetType::AT_CLOTHING, false);
+ getDescendentsOfAssetType(cat_id, wear_items, LLAssetType::AT_CLOTHING, false);
wearables_by_type_t items_by_type(LLWearableType::WT_COUNT);
divvyWearablesByType(wear_items, items_by_type);
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index 96541beb7d..dbde055c3a 100644
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -154,15 +154,16 @@ public:
//Divvy items into arrays by wearable type
static void divvyWearablesByType(const LLInventoryModel::item_array_t& items, wearables_by_type_t& items_by_type);
+ //Check ordering information on wearables stored in links' descriptions and update if it is invalid
+ // COF is processed if cat_id is not specified
+ void updateClothingOrderingInfo(LLUUID cat_id = LLUUID::null);
+
protected:
LLAppearanceMgr();
~LLAppearanceMgr();
private:
- //Check ordering information on wearables stored in links' descriptions and update if it is invalid
- void updateClothingOrderingInfo();
-
void filterWearableItems(LLInventoryModel::item_array_t& items, S32 max_per_type);
void getDescendentsOfAssetType(const LLUUID& category,
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index b9eb99230b..b1619b3c07 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -892,7 +892,16 @@ bool LLAppViewer::init()
}
LLViewerMedia::initClass();
-
+
+ LLStringOps::setupWeekDaysNames(LLTrans::getString("dateTimeWeekdaysNames"));
+ LLStringOps::setupWeekDaysShortNames(LLTrans::getString("dateTimeWeekdaysShortNames"));
+ LLStringOps::setupMonthNames(LLTrans::getString("dateTimeMonthNames"));
+ LLStringOps::setupMonthShortNames(LLTrans::getString("dateTimeMonthShortNames"));
+ LLStringOps::setupDayFormat(LLTrans::getString("dateTimeDayFormat"));
+
+ LLStringOps::sAM = LLTrans::getString("dateTimeAM");
+ LLStringOps::sPM = LLTrans::getString("dateTimePM");
+
return true;
}
diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp
index a057421135..ff1e8a9657 100644
--- a/indra/newview/llbottomtray.cpp
+++ b/indra/newview/llbottomtray.cpp
@@ -198,6 +198,12 @@ LLBottomTray::~LLBottomTray()
S32 custom_width = mNearbyChatBar->getRect().getWidth();
gSavedSettings.setS32("ChatBarCustomWidth", custom_width);
}
+
+ // emulate previous floater behavior to be hidden on startup.
+ // override effect of save_visibility=true.
+ // this attribute is necessary to button.initial_callback=Button.SetFloaterToggle works properly:
+ // i.g when floater changes its visibility - button changes its toggle state.
+ getChild<LLUICtrl>("search_btn")->setControlValue(false);
}
// *TODO Vadim: why void* ?
diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp
index 0864d63919..ee366f4e3c 100644
--- a/indra/newview/llcofwearables.cpp
+++ b/indra/newview/llcofwearables.cpp
@@ -43,6 +43,8 @@
#include "llmenugl.h"
#include "llviewermenu.h"
#include "llwearableitemslist.h"
+#include "llpaneloutfitedit.h"
+#include "llsidetray.h"
static LLRegisterPanelClassWrapper<LLCOFAccordionListAdaptor> t_cof_accodion_list_adaptor("accordion_list_adaptor");
@@ -135,8 +137,10 @@ protected:
LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
LLUUID selected_id = mUUIDs.back();
- registrar.add("BodyPart.Replace", boost::bind(&LLAppearanceMgr::wearItemOnAvatar,
- LLAppearanceMgr::getInstance(), selected_id, true, true));
+ // *HACK* need to pass pointer to LLPanelOutfitEdit instead of LLSideTray::getInstance()->getPanel().
+ // LLSideTray::getInstance()->getPanel() is rather slow variant
+ LLPanelOutfitEdit* panel_oe = dynamic_cast<LLPanelOutfitEdit*>(LLSideTray::getInstance()->getPanel("panel_outfit_edit"));
+ registrar.add("BodyPart.Replace", boost::bind(&LLPanelOutfitEdit::onReplaceBodyPartMenuItemClicked, panel_oe, selected_id));
registrar.add("BodyPart.Edit", boost::bind(LLAgentWearables::editWearable, selected_id));
enable_registrar.add("BodyPart.OnEnable", boost::bind(&CofBodyPartContextMenu::onEnable, this, _2));
@@ -419,6 +423,7 @@ void LLCOFWearables::addClothingTypesDummies(const LLAppearanceMgr::wearables_by
LLWearableType::EType w_type = static_cast<LLWearableType::EType>(type);
LLPanelInventoryListItemBase* item_panel = LLPanelDummyClothingListItem::create(w_type);
if(!item_panel) continue;
+ item_panel->childSetAction("btn_add", mCOFCallbacks.mAddWearable);
mClothing->addItem(item_panel, LLUUID::null, ADD_BOTTOM, false);
}
}
@@ -438,6 +443,13 @@ bool LLCOFWearables::getSelectedUUIDs(uuid_vec_t& selected_ids)
return selected_ids.size() != 0;
}
+LLPanel* LLCOFWearables::getSelectedItem()
+{
+ if (!mLastSelectedList) return NULL;
+
+ return mLastSelectedList->getSelectedItem();
+}
+
void LLCOFWearables::clear()
{
mAttachments->clear();
diff --git a/indra/newview/llcofwearables.h b/indra/newview/llcofwearables.h
index 590aa709dd..8f8bda2be8 100644
--- a/indra/newview/llcofwearables.h
+++ b/indra/newview/llcofwearables.h
@@ -107,6 +107,7 @@ public:
typedef boost::function<void (void*)> cof_callback_t;
+ cof_callback_t mAddWearable;
cof_callback_t mMoveWearableCloser;
cof_callback_t mMoveWearableFurther;
cof_callback_t mEditWearable;
@@ -123,6 +124,8 @@ public:
LLUUID getSelectedUUID();
bool getSelectedUUIDs(uuid_vec_t& selected_ids);
+ LLPanel* getSelectedItem();
+
void refresh();
void clear();
diff --git a/indra/newview/llfilteredwearablelist.cpp b/indra/newview/llfilteredwearablelist.cpp
index fd99f673e0..28e159421c 100644
--- a/indra/newview/llfilteredwearablelist.cpp
+++ b/indra/newview/llfilteredwearablelist.cpp
@@ -37,32 +37,10 @@
#include "llinventoryitemslist.h"
#include "llinventorymodel.h"
-class LLFindNonLinksByMask : public LLInventoryCollectFunctor
-{
-public:
- LLFindNonLinksByMask(U64 mask)
- : mFilterMask(mask)
- {}
-
- virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item)
- {
- if(item && !item->getIsLinkType() && (mFilterMask & (1LL << item->getInventoryType())) )
- {
- return true;
- }
-
- return false;
- }
-private:
- U64 mFilterMask;
-};
-
-//////////////////////////////////////////////////////////////////////////
-
-LLFilteredWearableListManager::LLFilteredWearableListManager(LLInventoryItemsList* list, U64 filter_mask)
+LLFilteredWearableListManager::LLFilteredWearableListManager(LLInventoryItemsList* list, LLInventoryCollectFunctor* collector)
: mWearableList(list)
-, mFilterMask(filter_mask)
+, mCollector(collector)
{
llassert(mWearableList);
gInventory.addObserver(this);
@@ -84,9 +62,9 @@ void LLFilteredWearableListManager::changed(U32 mask)
populateList();
}
-void LLFilteredWearableListManager::setFilterMask(U64 mask)
+void LLFilteredWearableListManager::setFilterCollector(LLInventoryCollectFunctor* collector)
{
- mFilterMask = mask;
+ mCollector = collector;
populateList();
}
@@ -94,14 +72,16 @@ void LLFilteredWearableListManager::populateList()
{
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t item_array;
- LLFindNonLinksByMask collector(mFilterMask);
- gInventory.collectDescendentsIf(
- gInventory.getRootFolderID(),
- cat_array,
- item_array,
- LLInventoryModel::EXCLUDE_TRASH,
- collector);
+ if(mCollector)
+ {
+ gInventory.collectDescendentsIf(
+ gInventory.getRootFolderID(),
+ cat_array,
+ item_array,
+ LLInventoryModel::EXCLUDE_TRASH,
+ *mCollector);
+ }
// Probably will also need to get items from Library (waiting for reply in EXT-6724).
diff --git a/indra/newview/llfilteredwearablelist.h b/indra/newview/llfilteredwearablelist.h
index 0780c02442..b7825c07af 100644
--- a/indra/newview/llfilteredwearablelist.h
+++ b/indra/newview/llfilteredwearablelist.h
@@ -32,6 +32,7 @@
#ifndef LL_LLFILTEREDWEARABLELIST_H
#define LL_LLFILTEREDWEARABLELIST_H
+#include "llinventoryfunctions.h"
#include "llinventoryobserver.h"
class LLInventoryItemsList;
@@ -42,7 +43,7 @@ class LLFilteredWearableListManager : public LLInventoryObserver
LOG_CLASS(LLFilteredWearableListManager);
public:
- LLFilteredWearableListManager(LLInventoryItemsList* list, U64 filter_mask);
+ LLFilteredWearableListManager(LLInventoryItemsList* list, LLInventoryCollectFunctor* collector);
~LLFilteredWearableListManager();
/** LLInventoryObserver implementation
@@ -51,9 +52,9 @@ public:
/*virtual*/ void changed(U32 mask);
/**
- * Sets new filter and applies it immediately
+ * Sets new collector and applies it immediately
*/
- void setFilterMask(U64 mask);
+ void setFilterCollector(LLInventoryCollectFunctor* collector);
/**
* Populates wearable list with filtered data.
@@ -62,7 +63,7 @@ public:
private:
LLInventoryItemsList* mWearableList;
- U64 mFilterMask;
+ LLInventoryCollectFunctor* mCollector;
};
#endif //LL_LLFILTEREDWEARABLELIST_H
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index f67d91cfa5..0cc4b0e389 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -371,6 +371,11 @@ bool LLFindWearablesOfType::operator()(LLInventoryCategory* cat, LLInventoryItem
return true;
}
+void LLFindWearablesOfType::setType(LLWearableType::EType type)
+{
+ mWearableType = type;
+}
+
///----------------------------------------------------------------------------
/// LLAssetIDMatches
///----------------------------------------------------------------------------
diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h
index 8b96ba29d9..bb365573d7 100644
--- a/indra/newview/llinventoryfunctions.h
+++ b/indra/newview/llinventoryfunctions.h
@@ -252,6 +252,37 @@ public:
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLFindNonLinksByMask
+//
+//
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLFindNonLinksByMask : public LLInventoryCollectFunctor
+{
+public:
+ LLFindNonLinksByMask(U64 mask)
+ : mFilterMask(mask)
+ {}
+
+ virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item)
+ {
+ if(item && !item->getIsLinkType() && (mFilterMask & (1LL << item->getInventoryType())) )
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ void setFilterMask(U64 mask)
+ {
+ mFilterMask = mask;
+ }
+
+private:
+ U64 mFilterMask;
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLFindWearables
//
// Collects wearables based on item type.
@@ -272,8 +303,10 @@ public:
LLFindWearablesOfType(LLWearableType::EType type) : mWearableType(type) {}
virtual ~LLFindWearablesOfType() {}
virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item);
+ void setType(LLWearableType::EType type);
- const LLWearableType::EType mWearableType;
+private:
+ LLWearableType::EType mWearableType;
};
/** Inventory Collector Functions
diff --git a/indra/newview/llinventoryitemslist.h b/indra/newview/llinventoryitemslist.h
index 807952948b..03ad7c2184 100644
--- a/indra/newview/llinventoryitemslist.h
+++ b/indra/newview/llinventoryitemslist.h
@@ -133,6 +133,9 @@ public:
/** Get the description of a corresponding inventory item */
const std::string& getDescription() const { return mItem->getDescription(); }
+ /** Get the associated inventory item */
+ LLViewerInventoryItem* getItem() const { return mItem; }
+
virtual ~LLPanelInventoryListItemBase(){}
protected:
diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp
index 680ed35fa2..46f531fdd9 100644
--- a/indra/newview/llnearbychatbar.cpp
+++ b/indra/newview/llnearbychatbar.cpp
@@ -34,6 +34,7 @@
#include "message.h"
+#include "llappviewer.h"
#include "llfloaterreg.h"
#include "lltrans.h"
@@ -388,6 +389,7 @@ BOOL LLNearbyChatBar::postBuild()
mChatBox->setCommitCallback(boost::bind(&LLNearbyChatBar::onChatBoxCommit, this));
mChatBox->setKeystrokeCallback(&onChatBoxKeystroke, this);
mChatBox->setFocusLostCallback(boost::bind(&onChatBoxFocusLost, _1, this));
+ mChatBox->setFocusReceivedCallback(boost::bind(&LLNearbyChatBar::onChatBoxFocusReceived, this));
mChatBox->setIgnoreArrowKeys( FALSE );
mChatBox->setCommitOnFocusLost( FALSE );
@@ -545,6 +547,11 @@ void LLNearbyChatBar::onChatBoxFocusLost(LLFocusableElement* caller, void* userd
gAgent.stopTyping();
}
+void LLNearbyChatBar::onChatBoxFocusReceived()
+{
+ mChatBox->setEnabled(!gDisconnected);
+}
+
EChatType LLNearbyChatBar::processChatTypeTriggers(EChatType type, std::string &str)
{
U32 length = str.length();
diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h
index 5af3152662..83c174fd10 100644
--- a/indra/newview/llnearbychatbar.h
+++ b/indra/newview/llnearbychatbar.h
@@ -122,6 +122,7 @@ protected:
static BOOL matchChatTypeTrigger(const std::string& in_str, std::string* out_str);
static void onChatBoxKeystroke(LLLineEditor* caller, void* userdata);
static void onChatBoxFocusLost(LLFocusableElement* caller, void* userdata);
+ void onChatBoxFocusReceived();
void sendChat( EChatType type );
void onChatBoxCommit();
diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp
index 17a2db7a43..8f189a1e9f 100644
--- a/indra/newview/lloutfitslist.cpp
+++ b/indra/newview/lloutfitslist.cpp
@@ -82,7 +82,6 @@ LLOutfitsList::LLOutfitsList()
: LLPanel()
, mAccordion(NULL)
, mListCommands(NULL)
- , mSelectedList(NULL)
{
mCategoriesObserver = new LLInventoryCategoriesObserver();
gInventory.addObserver(mCategoriesObserver);
@@ -208,6 +207,8 @@ void LLOutfitsList::refreshList(const LLUUID& category_id)
// Setting list refresh callback to apply filter on list change.
list->setRefreshCompleteCallback(boost::bind(&LLOutfitsList::onFilteredWearableItemsListRefresh, this, _1));
+ list->setRightMouseDownCallback(boost::bind(&LLOutfitsList::onWearableItemsListRightClick, this, _1, _2, _3));
+
// Fetch the new outfit contents.
cat->fetch();
@@ -237,23 +238,27 @@ void LLOutfitsList::refreshList(const LLUUID& category_id)
outfits_map_t::iterator outfits_iter = mOutfitsMap.find((*iter));
if (outfits_iter != mOutfitsMap.end())
{
- // An outfit is removed from the list. Do the following:
- // 1. Remove outfit accordion tab from accordion.
- mAccordion->removeCollapsibleCtrl(outfits_iter->second);
-
const LLUUID& outfit_id = outfits_iter->first;
+ LLAccordionCtrlTab* tab = outfits_iter->second;
- // 2. Remove outfit category from observer to stop monitoring its changes.
+ // An outfit is removed from the list. Do the following:
+ // 1. Remove outfit category from observer to stop monitoring its changes.
mCategoriesObserver->removeCategory(outfit_id);
- // 3. Reset selection if selected outfit is being removed.
- if (mSelectedOutfitUUID == outfit_id)
+ // 2. Remove selected lists map entry.
+ mSelectedListsMap.erase(outfit_id);
+
+ // 3. Reset currently selected outfit id if it is being removed.
+ if (outfit_id == mSelectedOutfitUUID)
{
- changeOutfitSelection(NULL, LLUUID());
+ mSelectedOutfitUUID = LLUUID();
}
// 4. Remove category UUID to accordion tab mapping.
mOutfitsMap.erase(outfits_iter);
+
+ // 5. Remove outfit tab from accordion.
+ mAccordion->removeCollapsibleCtrl(tab);
}
}
@@ -283,6 +288,8 @@ void LLOutfitsList::onSelectionChange(LLUICtrl* ctrl)
void LLOutfitsList::performAction(std::string action)
{
+ if (mSelectedOutfitUUID.isNull()) return;
+
LLViewerInventoryCategory* cat = gInventory.getCategory(mSelectedOutfitUUID);
if (!cat) return;
@@ -367,14 +374,28 @@ void LLOutfitsList::updateOutfitTab(const LLUUID& category_id)
void LLOutfitsList::changeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id)
{
- // Reset selection in previously selected tab
- // if a new one is selected.
- if (list && mSelectedList && mSelectedList != list)
+ MASK mask = gKeyboard->currentMask(TRUE);
+
+ // Reset selection in all previously selected tabs except for the current
+ // if new selection is started.
+ if (list && !(mask & MASK_CONTROL))
{
- mSelectedList->resetSelection();
+ for (wearables_lists_map_t::iterator iter = mSelectedListsMap.begin();
+ iter != mSelectedListsMap.end();
+ ++iter)
+ {
+ LLWearableItemsList* selected_list = (*iter).second;
+ if (selected_list != list)
+ {
+ selected_list->resetSelection();
+ }
+ }
+
+ // Clear current selection.
+ mSelectedListsMap.clear();
}
- mSelectedList = list;
+ mSelectedListsMap.insert(wearables_lists_map_value_t(category_id, list));
mSelectedOutfitUUID = category_id;
}
@@ -494,6 +515,13 @@ void LLOutfitsList::onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const
S32 header_bottom = tab->getLocalRect().getHeight() - tab->getHeaderHeight();
if(y >= header_bottom)
{
+ // Focus tab header to trigger tab selection change.
+ LLUICtrl* header = tab->findChild<LLUICtrl>("dd_header");
+ if (header)
+ {
+ header->setFocus(TRUE);
+ }
+
uuid_vec_t selected_uuids;
selected_uuids.push_back(cat_id);
mOutfitMenu->show(ctrl, selected_uuids, x, y);
@@ -501,4 +529,26 @@ void LLOutfitsList::onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const
}
}
+void LLOutfitsList::onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y)
+{
+ LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(ctrl);
+ if (!list) return;
+
+ uuid_vec_t selected_uuids;
+
+ // Collect seleted items from all selected lists.
+ for (wearables_lists_map_t::iterator iter = mSelectedListsMap.begin();
+ iter != mSelectedListsMap.end();
+ ++iter)
+ {
+ uuid_vec_t uuids;
+ (*iter).second->getSelectedUUIDs(uuids);
+
+ S32 prev_size = selected_uuids.size();
+ selected_uuids.resize(prev_size + uuids.size());
+ std::copy(uuids.begin(), uuids.end(), selected_uuids.begin() + prev_size);
+ }
+
+ LLWearableItemsList::ContextMenu::instance().show(list, selected_uuids, x, y);
+}
// EOF
diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h
index b6b3d6ae46..1da7360c2e 100644
--- a/indra/newview/lloutfitslist.h
+++ b/indra/newview/lloutfitslist.h
@@ -108,12 +108,17 @@ private:
void onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id);
+ void onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y);
+
LLInventoryCategoriesObserver* mCategoriesObserver;
LLAccordionCtrl* mAccordion;
LLPanel* mListCommands;
- LLWearableItemsList* mSelectedList;
+ typedef std::map<LLUUID, LLWearableItemsList*> wearables_lists_map_t;
+ typedef wearables_lists_map_t::value_type wearables_lists_map_value_t;
+ wearables_lists_map_t mSelectedListsMap;
+
LLUUID mSelectedOutfitUUID;
std::string mFilterSubString;
diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index 9e51aaceca..78de384cdc 100644
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -61,6 +61,7 @@
#include "llinventorymodelbackgroundfetch.h"
#include "llpaneloutfitsinventory.h"
#include "lluiconstants.h"
+#include "llsaveoutfitcombobtn.h"
#include "llscrolllistctrl.h"
#include "lltextbox.h"
#include "lluictrlfactory.h"
@@ -68,6 +69,7 @@
#include "llsidepanelappearance.h"
#include "lltoggleablemenu.h"
#include "llwearablelist.h"
+#include "llwearableitemslist.h"
static LLRegisterPanelClassWrapper<LLPanelOutfitEdit> t_outfit_edit("panel_outfit_edit");
@@ -75,7 +77,6 @@ const U64 WEARABLE_MASK = (1LL << LLInventoryType::IT_WEARABLE);
const U64 ATTACHMENT_MASK = (1LL << LLInventoryType::IT_ATTACHMENT) | (1LL << LLInventoryType::IT_OBJECT);
const U64 ALL_ITEMS_MASK = WEARABLE_MASK | ATTACHMENT_MASK;
-static const std::string SAVE_BTN("save_btn");
static const std::string REVERT_BTN("revert_btn");
class LLCOFObserver : public LLInventoryObserver
@@ -215,7 +216,10 @@ LLPanelOutfitEdit::LLPanelOutfitEdit()
mCOFObserver(NULL),
mGearMenu(NULL),
mCOFDragAndDropObserver(NULL),
- mInitialized(false)
+ mInitialized(false),
+ mAddWearablesPanel(NULL),
+ mWearableListMaskCollector(NULL),
+ mWearableListTypeCollector(NULL)
{
mSavedFolderState = new LLSaveFolderState();
mSavedFolderState->setApply(FALSE);
@@ -237,6 +241,9 @@ LLPanelOutfitEdit::~LLPanelOutfitEdit()
delete mCOFObserver;
delete mCOFDragAndDropObserver;
+
+ delete mWearableListMaskCollector;
+ delete mWearableListTypeCollector;
}
BOOL LLPanelOutfitEdit::postBuild()
@@ -252,16 +259,17 @@ BOOL LLPanelOutfitEdit::postBuild()
mFolderViewBtn = getChild<LLButton>("folder_view_btn");
mListViewBtn = getChild<LLButton>("list_view_btn");
+ mAddToOutfitBtn = getChild<LLButton>("add_to_outfit_btn");
childSetCommitCallback("filter_button", boost::bind(&LLPanelOutfitEdit::showWearablesFilter, this), NULL);
childSetCommitCallback("folder_view_btn", boost::bind(&LLPanelOutfitEdit::showFilteredFolderWearablesPanel, this), NULL);
childSetCommitCallback("list_view_btn", boost::bind(&LLPanelOutfitEdit::showFilteredWearablesPanel, this), NULL);
- childSetCommitCallback("gear_menu_btn", boost::bind(&LLPanelOutfitEdit::onGearButtonClick, this, _1), NULL);
childSetCommitCallback("wearables_gear_menu_btn", boost::bind(&LLPanelOutfitEdit::onGearButtonClick, this, _1), NULL);
mCOFWearables = getChild<LLCOFWearables>("cof_wearables_list");
mCOFWearables->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onOutfitItemSelectionChange, this));
+ mCOFWearables->getCOFCallbacks().mAddWearable = boost::bind(&LLPanelOutfitEdit::onAddWearableClicked, this);
mCOFWearables->getCOFCallbacks().mEditWearable = boost::bind(&LLPanelOutfitEdit::onEditWearableClicked, this);
mCOFWearables->getCOFCallbacks().mDeleteWearable = boost::bind(&LLPanelOutfitEdit::onRemoveFromOutfitClicked, this);
mCOFWearables->getCOFCallbacks().mMoveWearableCloser = boost::bind(&LLPanelOutfitEdit::moveWearable, this, true);
@@ -269,6 +277,7 @@ BOOL LLPanelOutfitEdit::postBuild()
mCOFWearables->childSetAction("add_btn", boost::bind(&LLPanelOutfitEdit::toggleAddWearablesPanel, this));
+ mAddWearablesPanel = getChild<LLPanel>("add_wearables_panel");
mInventoryItemsPanel = getChild<LLInventoryPanel>("inventory_items");
mInventoryItemsPanel->setFilterTypes(ALL_ITEMS_MASK);
@@ -299,18 +308,14 @@ BOOL LLPanelOutfitEdit::postBuild()
childSetAction(REVERT_BTN, boost::bind(&LLAppearanceMgr::wearBaseOutfit, LLAppearanceMgr::getInstance()));
- childSetAction(SAVE_BTN, boost::bind(&LLPanelOutfitEdit::saveOutfit, this, false));
- childSetAction("save_flyout_btn", boost::bind(&LLPanelOutfitEdit::showSaveMenu, this));
-
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar save_registar;
- save_registar.add("Outfit.Save.Action", boost::bind(&LLPanelOutfitEdit::saveOutfit, this, false));
- save_registar.add("Outfit.SaveAsNew.Action", boost::bind(&LLPanelOutfitEdit::saveOutfit, this, true));
- mSaveMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_save_outfit.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ mWearableListMaskCollector = new LLFindNonLinksByMask(ALL_ITEMS_MASK);
+ mWearableListTypeCollector = new LLFindWearablesOfType(LLWearableType::WT_NONE);
mWearableItemsPanel = getChild<LLPanel>("filtered_wearables_panel");
mWearableItemsList = getChild<LLInventoryItemsList>("filtered_wearables_list");
- mWearableListManager = new LLFilteredWearableListManager(mWearableItemsList, ALL_ITEMS_MASK);
+ mWearableListManager = new LLFilteredWearableListManager(mWearableItemsList, mWearableListMaskCollector);
+ mSaveComboBtn.reset(new LLSaveOutfitComboBtn(this));
return TRUE;
}
@@ -335,7 +340,16 @@ void LLPanelOutfitEdit::moveWearable(bool closer_to_body)
void LLPanelOutfitEdit::toggleAddWearablesPanel()
{
- childSetVisible("add_wearables_panel", !childIsVisible("add_wearables_panel"));
+ BOOL current_visibility = mAddWearablesPanel->getVisible();
+ mAddWearablesPanel->setVisible(!current_visibility);
+
+ mFolderViewBtn->setVisible(!current_visibility);
+ mListViewBtn->setVisible(!current_visibility);
+ mAddToOutfitBtn->setVisible(!current_visibility);
+
+ // Change right dummy icon to fill the toggled buttons space.
+ childSetVisible("add_wearables_dummy_icon", !current_visibility);
+ childSetVisible("dummy_right_icon", current_visibility);
}
void LLPanelOutfitEdit::showWearablesFilter()
@@ -373,33 +387,6 @@ void LLPanelOutfitEdit::showFilteredFolderWearablesPanel()
mFolderViewBtn->setToggleState(TRUE);
}
-void LLPanelOutfitEdit::saveOutfit(bool as_new)
-{
- if (!as_new && LLAppearanceMgr::getInstance()->updateBaseOutfit())
- {
- // we don't need to ask for an outfit name, and updateBaseOutfit() successfully saved.
- // If updateBaseOutfit fails, ask for an outfit name anyways
- return;
- }
-
- LLPanelOutfitsInventory* panel_outfits_inventory = LLPanelOutfitsInventory::findInstance();
- if (panel_outfits_inventory)
- {
- panel_outfits_inventory->onSave();
- }
-
- //*TODO how to get to know when base outfit is updated or new outfit is created?
-}
-
-void LLPanelOutfitEdit::showSaveMenu()
-{
- S32 x, y;
- LLUI::getMousePositionLocal(this, &x, &y);
-
- mSaveMenu->updateParent(LLMenuGL::sMenuContainer);
- LLMenuGL::showPopup(this, mSaveMenu, x, y);
-}
-
void LLPanelOutfitEdit::onTypeFilterChanged(LLUICtrl* ctrl)
{
LLComboBox* type_filter = dynamic_cast<LLComboBox*>(ctrl);
@@ -408,7 +395,9 @@ void LLPanelOutfitEdit::onTypeFilterChanged(LLUICtrl* ctrl)
{
U32 curr_filter_type = type_filter->getCurrentIndex();
mInventoryItemsPanel->setFilterTypes(mLookItemTypes[curr_filter_type].inventoryMask);
- mWearableListManager->setFilterMask(mLookItemTypes[curr_filter_type].inventoryMask);
+
+ mWearableListMaskCollector->setFilterMask(mLookItemTypes[curr_filter_type].inventoryMask);
+ mWearableListManager->setFilterCollector(mWearableListMaskCollector);
}
mSavedFolderState->setApply(TRUE);
@@ -488,6 +477,25 @@ void LLPanelOutfitEdit::onAddToOutfitClicked(void)
LLAppearanceMgr::getInstance()->wearItemOnAvatar(selected_id);
}
+void LLPanelOutfitEdit::onAddWearableClicked(void)
+{
+ LLPanelDummyClothingListItem* item = dynamic_cast<LLPanelDummyClothingListItem*>(mCOFWearables->getSelectedItem());
+
+ if(item)
+ {
+ showFilteredWearableItemsList(item->getWearableType());
+ }
+}
+
+void LLPanelOutfitEdit::onReplaceBodyPartMenuItemClicked(LLUUID selected_item_id)
+{
+ LLViewerInventoryItem* item = gInventory.getLinkedItem(selected_item_id);
+
+ if (item && item->getType() == LLAssetType::AT_BODYPART)
+ {
+ showFilteredWearableItemsList(item->getWearableType());
+ }
+}
void LLPanelOutfitEdit::onRemoveFromOutfitClicked(void)
{
@@ -676,10 +684,10 @@ void LLPanelOutfitEdit::updateVerbs()
bool outfit_is_dirty = LLAppearanceMgr::getInstance()->isOutfitDirty();
bool has_baseoutfit = LLAppearanceMgr::getInstance()->getBaseOutfitUUID().notNull();
- childSetEnabled(SAVE_BTN, outfit_is_dirty);
+ mSaveComboBtn->setSaveBtnEnabled(outfit_is_dirty);
childSetEnabled(REVERT_BTN, outfit_is_dirty && has_baseoutfit);
- mSaveMenu->setItemEnabled("save_outfit", outfit_is_dirty);
+ mSaveComboBtn->setMenuItemEnabled("save_outfit", outfit_is_dirty);
mStatus->setText(outfit_is_dirty ? getString("unsaved_changes") : getString("now_editing"));
@@ -723,4 +731,12 @@ void LLPanelOutfitEdit::onGearMenuItemClick(const LLSD& data)
}
}
+void LLPanelOutfitEdit::showFilteredWearableItemsList(LLWearableType::EType type)
+{
+ mWearableListTypeCollector->setType(type);
+ mWearableListManager->setFilterCollector(mWearableListTypeCollector);
+ mAddWearablesPanel->setVisible(TRUE);
+ showFilteredWearablesPanel();
+}
+
// EOF
diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h
index 1bf69c5606..1569c55732 100644
--- a/indra/newview/llpaneloutfitedit.h
+++ b/indra/newview/llpaneloutfitedit.h
@@ -59,6 +59,9 @@ class LLToggleableMenu;
class LLFilterEditor;
class LLFilteredWearableListManager;
class LLMenuGL;
+class LLFindNonLinksByMask;
+class LLFindWearablesOfType;
+class LLSaveOutfitComboBtn;
class LLPanelOutfitEdit : public LLPanel
{
@@ -93,8 +96,6 @@ public:
void showWearablesFilter();
void showFilteredWearablesPanel();
void showFilteredFolderWearablesPanel();
- void saveOutfit(bool as_new = false);
- void showSaveMenu();
void onTypeFilterChanged(LLUICtrl* ctrl);
void onSearchEdit(const std::string& string);
@@ -103,6 +104,8 @@ public:
void onOutfitItemSelectionChange(void);
void onRemoveFromOutfitClicked(void);
void onEditWearableClicked(void);
+ void onAddWearableClicked(void);
+ void onReplaceBodyPartMenuItemClicked(LLUUID selected_item_id);
void displayCurrentOutfit();
void updateCurrentOutfitName();
@@ -129,6 +132,7 @@ private:
void onGearButtonClick(LLUICtrl* clicked_button);
void onGearMenuItemClick(const LLSD& data);
+ void showFilteredWearableItemsList(LLWearableType::EType type);
LLTextBox* mCurrentOutfitName;
@@ -140,7 +144,11 @@ private:
LLButton* mEditWearableBtn;
LLButton* mFolderViewBtn;
LLButton* mListViewBtn;
- LLToggleableMenu* mSaveMenu;
+ LLButton* mAddToOutfitBtn;
+ LLPanel* mAddWearablesPanel;
+
+ LLFindNonLinksByMask* mWearableListMaskCollector;
+ LLFindWearablesOfType* mWearableListTypeCollector;
LLFilteredWearableListManager* mWearableListManager;
LLInventoryItemsList* mWearableItemsList;
@@ -154,6 +162,8 @@ private:
LLCOFWearables* mCOFWearables;
LLMenuGL* mGearMenu;
bool mInitialized;
+ std::auto_ptr<LLSaveOutfitComboBtn> mSaveComboBtn;
+
};
#endif // LL_LLPANELOUTFITEDIT_H
diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp
index a7e8f497d9..21f69d3470 100644
--- a/indra/newview/llpaneloutfitsinventory.cpp
+++ b/indra/newview/llpaneloutfitsinventory.cpp
@@ -50,6 +50,7 @@
#include "llmodaldialog.h"
#include "llnotificationsutil.h"
#include "lloutfitslist.h"
+#include "llsaveoutfitcombobtn.h"
#include "llsidepanelappearance.h"
#include "llsidetray.h"
#include "lltabcontainer.h"
@@ -101,6 +102,8 @@ BOOL LLPanelOutfitsInventory::postBuild()
LLInventoryModelBackgroundFetch::instance().start(outfits_cat);
}
+ mSaveComboBtn.reset(new LLSaveOutfitComboBtn(this, true));
+
return TRUE;
}
@@ -373,7 +376,6 @@ void LLPanelOutfitsInventory::initListCommandsHandlers()
mListCommands->childSetAction("options_gear_btn", boost::bind(&LLPanelOutfitsInventory::onGearButtonClick, this));
mListCommands->childSetAction("trash_btn", boost::bind(&LLPanelOutfitsInventory::onTrashButtonClick, this));
- mListCommands->childSetAction("make_outfit_btn", boost::bind(&LLPanelOutfitsInventory::onAddButtonClick, this));
mListCommands->childSetAction("wear_btn", boost::bind(&LLPanelOutfitsInventory::onWearButtonClick, this));
LLDragAndDropButton* trash_btn = mListCommands->getChild<LLDragAndDropButton>("trash_btn");
@@ -396,7 +398,7 @@ void LLPanelOutfitsInventory::updateListCommands()
mListCommands->childSetEnabled("trash_btn", trash_enabled);
mListCommands->childSetEnabled("wear_btn", wear_enabled);
mListCommands->childSetVisible("wear_btn", wear_enabled);
- mListCommands->childSetEnabled("make_outfit_btn", make_outfit_enabled);
+ mSaveComboBtn->setSaveBtnEnabled(make_outfit_enabled);
}
void LLPanelOutfitsInventory::onGearButtonClick()
@@ -404,11 +406,6 @@ void LLPanelOutfitsInventory::onGearButtonClick()
showActionMenu(mMenuGearDefault,"options_gear_btn");
}
-void LLPanelOutfitsInventory::onAddButtonClick()
-{
- onSave();
-}
-
void LLPanelOutfitsInventory::showActionMenu(LLMenuGL* menu, std::string spawning_view_name)
{
if (menu)
diff --git a/indra/newview/llpaneloutfitsinventory.h b/indra/newview/llpaneloutfitsinventory.h
index a0fe91cd80..7bdd37c16c 100644
--- a/indra/newview/llpaneloutfitsinventory.h
+++ b/indra/newview/llpaneloutfitsinventory.h
@@ -46,6 +46,7 @@ class LLButton;
class LLMenuGL;
class LLSidepanelAppearance;
class LLTabContainer;
+class LLSaveOutfitComboBtn;
class LLPanelOutfitsInventory : public LLPanel
{
@@ -86,7 +87,7 @@ private:
LLSaveFolderState* mSavedFolderState;
LLTabContainer* mAppearanceTabs;
std::string mFilterSubString;
-
+ std::auto_ptr<LLSaveOutfitComboBtn> mSaveComboBtn;
public:
//////////////////////////////////////////////////////////////////////////////////
// tab panels
@@ -117,7 +118,6 @@ protected:
void updateListCommands();
void onGearButtonClick();
void onWearButtonClick();
- void onAddButtonClick();
void showActionMenu(LLMenuGL* menu, std::string spawning_view_name);
void onTrashButtonClick();
void onClipboardAction(const LLSD& userdata);
diff --git a/indra/newview/llsaveoutfitcombobtn.cpp b/indra/newview/llsaveoutfitcombobtn.cpp
new file mode 100644
index 0000000000..b9b577084b
--- /dev/null
+++ b/indra/newview/llsaveoutfitcombobtn.cpp
@@ -0,0 +1,97 @@
+/**
+ * @file llsaveoutfitcombobtn.cpp
+ * @brief Represents outfit save/save as combo button.
+ *
+ * $LicenseInfo:firstyear=2010&license=viewergpl$
+ *
+ * Copyright (c) 2010, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llappearancemgr.h"
+#include "llpaneloutfitsinventory.h"
+#include "llsaveoutfitcombobtn.h"
+#include "llviewermenu.h"
+
+static const std::string SAVE_BTN("save_btn");
+static const std::string SAVE_FLYOUT_BTN("save_flyout_btn");
+
+LLSaveOutfitComboBtn::LLSaveOutfitComboBtn(LLPanel* parent, bool saveAsDefaultAction):
+ mParent(parent), mSaveAsDefaultAction(saveAsDefaultAction)
+{
+ // register action mapping before creating menu
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar save_registar;
+ save_registar.add("Outfit.Save.Action", boost::bind(
+ &LLSaveOutfitComboBtn::saveOutfit, this, false));
+ save_registar.add("Outfit.SaveAs.Action", boost::bind(
+ &LLSaveOutfitComboBtn::saveOutfit, this, true));
+
+ mParent->childSetAction(SAVE_BTN, boost::bind(&LLSaveOutfitComboBtn::saveOutfit, this, mSaveAsDefaultAction));
+ mParent->childSetAction(SAVE_FLYOUT_BTN, boost::bind(&LLSaveOutfitComboBtn::showSaveMenu, this));
+
+ mSaveMenu = LLUICtrlFactory::getInstance()->createFromFile<
+ LLToggleableMenu> ("menu_save_outfit.xml", gMenuHolder,
+ LLViewerMenuHolderGL::child_registry_t::instance());
+}
+
+void LLSaveOutfitComboBtn::showSaveMenu()
+{
+ S32 x, y;
+ LLUI::getMousePositionLocal(mParent, &x, &y);
+
+ mSaveMenu->updateParent(LLMenuGL::sMenuContainer);
+ LLMenuGL::showPopup(mParent, mSaveMenu, x, y);
+}
+
+void LLSaveOutfitComboBtn::saveOutfit(bool as_new)
+{
+ if (!as_new && LLAppearanceMgr::getInstance()->updateBaseOutfit())
+ {
+ // we don't need to ask for an outfit name, and updateBaseOutfit() successfully saved.
+ // If updateBaseOutfit fails, ask for an outfit name anyways
+ return;
+ }
+
+ LLPanelOutfitsInventory* panel_outfits_inventory =
+ LLPanelOutfitsInventory::findInstance();
+ if (panel_outfits_inventory)
+ {
+ panel_outfits_inventory->onSave();
+ }
+
+ //*TODO how to get to know when base outfit is updated or new outfit is created?
+}
+
+void LLSaveOutfitComboBtn::setMenuItemEnabled(const std::string& item, bool enabled)
+{
+ mSaveMenu->setItemEnabled("save_outfit", enabled);
+}
+
+void LLSaveOutfitComboBtn::setSaveBtnEnabled(bool enabled)
+{
+ mParent->childSetEnabled(SAVE_BTN, enabled);
+}
diff --git a/indra/newview/llsaveoutfitcombobtn.h b/indra/newview/llsaveoutfitcombobtn.h
new file mode 100644
index 0000000000..fec7122194
--- /dev/null
+++ b/indra/newview/llsaveoutfitcombobtn.h
@@ -0,0 +1,60 @@
+/**
+ * @file llsaveoutfitcombobtn.h
+ * @brief Represents outfit save/save as combo button.
+ *
+ * $LicenseInfo:firstyear=2010&license=viewergpl$
+ *
+ * Copyright (c) 2010, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLSAVEOUTFITCOMBOBTN_H
+#define LL_LLSAVEOUTFITCOMBOBTN_H
+
+class LLButton;
+
+#include "lltoggleablemenu.h"
+
+/**
+ * Represents outfit Save/Save As combo button.
+ */
+class LLSaveOutfitComboBtn
+{
+ LOG_CLASS(LLSaveOutfitComboBtn);
+public:
+ LLSaveOutfitComboBtn(LLPanel* parent, bool saveAsDefaultAction = false);
+
+ void showSaveMenu();
+ void saveOutfit(bool as_new = false);
+ void setMenuItemEnabled(const std::string& item, bool enabled);
+ void setSaveBtnEnabled(bool enabled);
+
+private:
+ bool mSaveAsDefaultAction;
+ LLPanel* mParent;
+ LLToggleableMenu* mSaveMenu;
+};
+
+#endif // LL_LLSAVEOUTFITCOMBOBTN_H
diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp
index fb7577c008..161cd40cfc 100644
--- a/indra/newview/llwearableitemslist.cpp
+++ b/indra/newview/llwearableitemslist.cpp
@@ -251,6 +251,11 @@ BOOL LLPanelDummyClothingListItem::postBuild()
return TRUE;
}
+LLWearableType::EType LLPanelDummyClothingListItem::getWearableType() const
+{
+ return mWearableType;
+}
+
LLPanelDummyClothingListItem::LLPanelDummyClothingListItem(LLWearableType::EType w_type)
: LLPanelWearableListItem(NULL)
, mWearableType(w_type)
diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h
index 7ad1b5a3ad..de024ed220 100644
--- a/indra/newview/llwearableitemslist.h
+++ b/indra/newview/llwearableitemslist.h
@@ -162,6 +162,7 @@ public:
/*virtual*/ void updateItem();
/*virtual*/ BOOL postBuild();
+ LLWearableType::EType getWearableType() const;
protected:
LLPanelDummyClothingListItem(LLWearableType::EType w_type);
diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Left_Flash.png b/indra/newview/skins/default/textures/containers/Toolbar_Left_Flash.png
new file mode 100644
index 0000000000..9f1e2a469d
--- /dev/null
+++ b/indra/newview/skins/default/textures/containers/Toolbar_Left_Flash.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Middle_Flash.png b/indra/newview/skins/default/textures/containers/Toolbar_Middle_Flash.png
new file mode 100644
index 0000000000..dd73d655e9
--- /dev/null
+++ b/indra/newview/skins/default/textures/containers/Toolbar_Middle_Flash.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/containers/Toolbar_Right_Flash.png b/indra/newview/skins/default/textures/containers/Toolbar_Right_Flash.png
new file mode 100644
index 0000000000..f6b775c2a0
--- /dev/null
+++ b/indra/newview/skins/default/textures/containers/Toolbar_Right_Flash.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Generic_Group_Large.png b/indra/newview/skins/default/textures/icons/Generic_Group_Large.png
index c067646c65..de8a39fc8a 100644
--- a/indra/newview/skins/default/textures/icons/Generic_Group_Large.png
+++ b/indra/newview/skins/default/textures/icons/Generic_Group_Large.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 29c72a414b..072ea40ee4 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -527,15 +527,18 @@ with the same filename but different name
<texture name="Tool_Grab" file_name="build/Tool_Grab.png" preload="false" />
<texture name="Tool_Zoom" file_name="build/Tool_Zoom.png" preload="false" />
+ <texture name="Toolbar_Left_Flash" file_name="containers/Toolbar_Left_Flash.png" preload="false" scale.left="5" scale.bottom="4" scale.top="24" scale.right="30" />
<texture name="Toolbar_Left_Off" file_name="containers/Toolbar_Left_Off.png" preload="false" scale.left="5" scale.bottom="4" scale.top="24" scale.right="30" />
<texture name="Toolbar_Left_Over" file_name="containers/Toolbar_Left_Over.png" preload="false" scale.left="5" scale.bottom="4" scale.top="24" scale.right="30" />
<texture name="Toolbar_Left_Selected" file_name="containers/Toolbar_Left_Selected.png" preload="false" scale.left="5" scale.bottom="4" scale.top="24" scale.right="30" />
<texture name="Toolbar_Middle_Off" file_name="containers/Toolbar_Middle_Off.png" preload="false" scale.left="1" scale.bottom="2" scale.top="24" scale.right="30" />
<texture name="Toolbar_Middle_Over" file_name="containers/Toolbar_Middle_Over.png" preload="false" scale.left="1" scale.bottom="2" scale.top="24" scale.right="30" />
<texture name="Toolbar_Middle_Selected" file_name="containers/Toolbar_Middle_Selected.png" preload="false" scale.left="1" scale.bottom="2" scale.top="24" scale.right="30" />
+ <texture name="Toolbar_Middle_Flash" file_name="containers/Toolbar_Middle_Flash.png" preload="false" scale.left="5" scale.bottom="4" scale.top="24" scale.right="30" />
<texture name="Toolbar_Right_Off" file_name="containers/Toolbar_Right_Off.png" preload="false" scale.left="1" scale.bottom="4" scale.top="24" scale.right="26" />
<texture name="Toolbar_Right_Over" file_name="containers/Toolbar_Right_Over.png" preload="false" scale.left="1" scale.bottom="4" scale.top="24" scale.right="26" />
<texture name="Toolbar_Right_Selected" file_name="containers/Toolbar_Right_Selected.png" preload="false" scale.left="1" scale.bottom="4" scale.top="24" scale.right="26" />
+ <texture name="Toolbar_Right_Flash" file_name="containers/Toolbar_Right_Flash.png" preload="false" scale.left="1" scale.bottom="4" scale.top="24" scale.right="26" />
<texture name="Tooltip" file_name="widgets/Tooltip.png" preload="true" scale.left="2" scale.top="16" scale.right="100" scale.bottom="3" />
diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml
index ced8c29199..e123de46c2 100644
--- a/indra/newview/skins/default/xui/en/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_container.xml
@@ -27,7 +27,14 @@
halign="left"
use_ellipses="true"
top="0"
- width="394" />
+ width="394">
+ <first_tab
+ tab_bottom_image_flash="Toolbar_Left_Flash"/>
+ <middle_tab
+ tab_bottom_image_flash="Toolbar_Middle_Flash"/>
+ <last_tab
+ tab_bottom_image_flash="Toolbar_Right_Flash"/>
+ </tab_container>
<icon
color="DefaultShadowLight"
enabled="false"
diff --git a/indra/newview/skins/default/xui/en/floater_search.xml b/indra/newview/skins/default/xui/en/floater_search.xml
index 9ca18d455b..49b3b58113 100644
--- a/indra/newview/skins/default/xui/en/floater_search.xml
+++ b/indra/newview/skins/default/xui/en/floater_search.xml
@@ -9,6 +9,7 @@
name="floater_search"
help_topic="floater_search"
save_rect="true"
+ save_visibility="true"
single_instance="true"
title="FIND"
width="650">
diff --git a/indra/newview/skins/default/xui/en/menu_save_outfit.xml b/indra/newview/skins/default/xui/en/menu_save_outfit.xml
index a8778df7f6..6285bf7417 100644
--- a/indra/newview/skins/default/xui/en/menu_save_outfit.xml
+++ b/indra/newview/skins/default/xui/en/menu_save_outfit.xml
@@ -14,9 +14,9 @@
</menu_item_call>
<menu_item_call
name="save_as_new_outfit"
- label="Save As New">
+ label="Save As">
<menu_item_call.on_click
- function="Outfit.SaveAsNew.Action"
+ function="Outfit.SaveAs.Action"
userdata="" />
</menu_item_call>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/outfit_accordion_tab.xml b/indra/newview/skins/default/xui/en/outfit_accordion_tab.xml
index 066992b25d..44437d01eb 100644
--- a/indra/newview/skins/default/xui/en/outfit_accordion_tab.xml
+++ b/indra/newview/skins/default/xui/en/outfit_accordion_tab.xml
@@ -8,6 +8,7 @@
height="45"
layout="topleft"
name="Mockup Tab"
+ selection_enabled="true"
title="Mockup Tab"
translate="false"
width="0">
@@ -18,5 +19,6 @@
multi_select="true"
name="wearable_items_list"
translate="false"
+ use_internal_context_menu="false"
/>
</accordion_tab>
diff --git a/indra/newview/skins/default/xui/en/panel_edit_tattoo.xml b/indra/newview/skins/default/xui/en/panel_edit_tattoo.xml
index 6d02dd41de..23a08344ea 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_tattoo.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_tattoo.xml
@@ -25,49 +25,58 @@
can_apply_immediately="true"
default_image_name="Default"
follows="left|top"
- height="100"
+ height="115"
label="Head Tattoo"
layout="topleft"
- left="30"
+ left="20"
name="Head Tattoo"
tool_tip="Click to choose a picture"
top="10"
- width="94" />
+ width="115" >
+ <texture_picker.commit_callback
+ function="TexturePicker.Commit" />
+ </texture_picker>
<texture_picker
can_apply_immediately="true"
default_image_name="Default"
follows="left|top"
- height="100"
+ height="115"
label="Upper Tattoo"
layout="topleft"
left_pad="30"
name="Upper Tattoo"
tool_tip="Click to choose a picture"
top="10"
- width="94" />
+ width="115" >
+ <texture_picker.commit_callback
+ function="TexturePicker.Commit" />
+ </texture_picker>
<texture_picker
can_apply_immediately="true"
default_image_name="Default"
follows="left|top"
- height="100"
+ height="115"
label="Lower Tattoo"
layout="topleft"
- left="30"
+ left="20"
name="Lower Tattoo"
tool_tip="Click to choose a picture"
top_pad="10"
- width="94" />
+ width="115" >
+ <texture_picker.commit_callback
+ function="TexturePicker.Commit" />
+ </texture_picker>
<color_swatch
can_apply_immediately="true"
follows="left|top"
- height="80"
+ height="115"
label="Color/Tint"
layout="topleft"
- left_pad="20"
+ left_pad="30"
name="Color/Tint"
tool_tip="Click to open color picker"
- top="10"
- width="64" >
+ top_delta="0"
+ width="115" >
<color_swatch.commit_callback
function="ColorSwatch.Commit" />
</color_swatch>
diff --git a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
index bc984ccc44..abd96c89e7 100644
--- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
@@ -160,7 +160,7 @@ It is calculated as border_size + 2*UIResizeBarOverlap
clip="false"
default_tab_group="2"
follows="all"
- height="495"
+ height="468"
width="313"
layout="topleft"
orientation="vertical"
@@ -170,7 +170,7 @@ It is calculated as border_size + 2*UIResizeBarOverlap
left="5">
<layout_panel
layout="topleft"
- height="220"
+ height="193"
label="IM Control Panel"
min_height="100"
name="outfit_wearables_panel"
@@ -190,40 +190,6 @@ It is calculated as border_size + 2*UIResizeBarOverlap
name="cof_wearables_list"
top="0"
width="311" />
-
- <!-- Button bar -->
- <panel
- background_visible="true"
- bevel_style="none"
- follows="bottom|left|right"
- height="27"
- label="bottom_panel"
- layout="topleft"
- left="0"
- name="edit_panel"
- top="193"
- width="313">
- <button
- follows="bottom|left"
- height="25"
- image_hover_unselected="Toolbar_Left_Over"
- image_overlay="OptionsMenu_Off"
- image_selected="Toolbar_Left_Selected"
- image_unselected="Toolbar_Left_Off"
- layout="topleft"
- left="0"
- name="gear_menu_btn"
- top="1"
- width="31" />
- <icon
- follows="bottom|left|right"
- height="25"
- image_name="Toolbar_Right_Off"
- layout="topleft"
- left_pad="1"
- name="dummy_right_icon"
- width="281" />
- </panel>
</layout_panel>
@@ -232,7 +198,7 @@ It is calculated as border_size + 2*UIResizeBarOverlap
bg_alpha_color="DkGray2"
auto_resize="true"
default_tab_group="3"
- height="211"
+ height="184"
min_height="210"
name="add_wearables_panel"
width="313"
@@ -360,82 +326,98 @@ It is calculated as border_size + 2*UIResizeBarOverlap
</panel>
</layout_panel>
</layout_stack>
-
- <panel
- background_visible="true"
- bevel_style="none"
- follows="left|right|bottom"
- height="27"
- label="add_wearables_button_bar"
- layout="topleft"
- left="0"
- name="add_wearables_button_bar"
- top_pad="0"
- width="313">
- <button
- follows="bottom|left"
- height="25"
- image_hover_unselected="Toolbar_Left_Over"
- image_overlay="OptionsMenu_Off"
- image_selected="Toolbar_Left_Selected"
- image_unselected="Toolbar_Left_Off"
- layout="topleft"
- left="0"
- name="wearables_gear_menu_btn"
- top="1"
- width="31" />
- <button
- follows="bottom|left"
- height="25"
- image_hover_unselected="Toolbar_Middle_Over"
- image_overlay="Hierarchy_View_Disabled"
- image_selected="Toolbar_Middle_Selected"
- image_unselected="Toolbar_Middle_Off"
- is_toggle="true"
- layout="topleft"
- left_pad="1"
- name="folder_view_btn"
- top="1"
- width="31" />
- <button
- follows="bottom|left"
- height="25"
- image_hover_unselected="Toolbar_Middle_Over"
- image_overlay="List_View_On"
- image_selected="Toolbar_Middle_Selected"
- image_unselected="Toolbar_Middle_Off"
- is_toggle="true"
- layout="topleft"
- left_pad="1"
- name="list_view_btn"
- top="1"
- width="31" />
- <button
- follows="bottom|left"
- height="25"
- image_hover_unselected="Toolbar_Middle_Over"
- image_overlay="AddItem_Off"
- image_selected="Toolbar_Middle_Selected"
- image_unselected="Toolbar_Middle_Off"
- label=""
- layout="topleft"
- left_pad="1"
- name="add_to_outfit_btn"
- top="1"
- width="31" />
- <icon
- follows="bottom|left|right"
- height="25"
- image_name="Toolbar_Right_Off"
- layout="topleft"
- left_pad="1"
- name="dummy_right_icon"
- width="184" >
- </icon>
- </panel>
- </layout_panel>
+ </layout_panel>
</layout_stack>
+ <!-- Button bar -->
+ <panel
+ background_visible="true"
+ bevel_style="none"
+ follows="left|right|bottom"
+ height="27"
+ label="add_wearables_button_bar"
+ layout="topleft"
+ left="4"
+ name="add_wearables_button_bar"
+ top_pad="0"
+ width="313">
+ <button
+ follows="bottom|left"
+ height="25"
+ image_hover_unselected="Toolbar_Left_Over"
+ image_overlay="OptionsMenu_Off"
+ image_selected="Toolbar_Left_Selected"
+ image_unselected="Toolbar_Left_Off"
+ layout="topleft"
+ left="0"
+ name="wearables_gear_menu_btn"
+ top="1"
+ width="31" />
+ <button
+ follows="bottom|left"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="Hierarchy_View_Disabled"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ is_toggle="true"
+ layout="topleft"
+ left_pad="1"
+ name="folder_view_btn"
+ top="1"
+ visible="false"
+ width="31" />
+ <button
+ follows="bottom|left"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="List_View_On"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ is_toggle="true"
+ layout="topleft"
+ left_pad="1"
+ name="list_view_btn"
+ top="1"
+ visible="false"
+ width="31" />
+ <button
+ follows="bottom|left"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="AddItem_Off"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ label=""
+ layout="topleft"
+ left_pad="1"
+ name="add_to_outfit_btn"
+ top="1"
+ visible="false"
+ width="31" />
+ <icon
+ follows="bottom|left|right"
+ height="25"
+ image_name="Toolbar_Right_Off"
+ layout="topleft"
+ left_pad="1"
+ name="add_wearables_dummy_icon"
+ top="1"
+ visible="false"
+ width="184" >
+ </icon>
+ <icon
+ follows="bottom|left|right"
+ height="25"
+ image_name="Toolbar_Right_Off"
+ layout="topleft"
+ left="32"
+ name="dummy_right_icon"
+ top="1"
+ width="281" >
+ </icon>
+ </panel>
+
<panel
follows="left|right|bottom"
height="30"
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 9e59651bd1..13e1f5ba5c 100644
--- a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml
@@ -93,17 +93,30 @@
left_pad="1"
name="trash_btn"
tool_tip="Remove selected item"
- width="31"/>
- <button
- follows="bottom|left"
- height="23"
- label="Save Outfit"
- layout="topleft"
- name="make_outfit_btn"
- tool_tip="Save appearance as an outfit"
+ width="31"/>
+ <button
+ follows="bottom|left"
+ height="23"
+ label="Save As"
+ left="0"
+ layout="topleft"
+ name="save_btn"
top_pad="6"
- left="0"
- width="153" />
+ width="155" />
+ <button
+ follows="bottom|left"
+ height="23"
+ name="save_flyout_btn"
+ label=""
+ layout="topleft"
+ left_pad="-20"
+ tab_stop="false"
+ image_selected="SegmentedBtn_Right_Selected_Press"
+ image_unselected="SegmentedBtn_Right_Off"
+ image_pressed="SegmentedBtn_Right_Press"
+ image_pressed_selected="SegmentedBtn_Right_Selected_Press"
+ image_overlay="Arrow_Small_Up"
+ width="20"/>
<button
follows="bottom|left|right"
height="23"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 3ec445f9ad..078426d3d9 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -3182,4 +3182,19 @@ Abuse Report</string>
If you continue to experience problems, please check your network and firewall setup.
</string>
+ <!-- overriding datetime formating.
+ leave emtpy in for current localization this is not needed
+ list of values should be separated with ':'
+ example:
+ <string name="dateTimeWeekdaysShortNames">
+ Son:Mon:Tue:Wed:Thu:Fri:Sat
+ </string>
+ -->
+ <string name="dateTimeWeekdaysNames"></string>
+ <string name="dateTimeWeekdaysShortNames"></string>
+ <string name="dateTimeMonthNames"></string>
+ <string name="dateTimeMonthShortNames"></string>
+ <string name="dateTimeDayFormat"></string>
+ <string name="dateTimeAM"></string>
+ <string name="dateTimePM"></string>
</strings>
diff --git a/indra/newview/skins/default/xui/en/widgets/button.xml b/indra/newview/skins/default/xui/en/widgets/button.xml
index c4f0fe5208..6dcc27b469 100644
--- a/indra/newview/skins/default/xui/en/widgets/button.xml
+++ b/indra/newview/skins/default/xui/en/widgets/button.xml
@@ -7,6 +7,7 @@
image_selected="PushButton_Selected"
image_disabled_selected="PushButton_Selected_Disabled"
image_disabled="PushButton_Disabled"
+ image_flash="FlashIconAbsent"
image_top_pad="0"
image_bottom_pad="0"
imgoverlay_label_space="1"
diff --git a/indra/newview/skins/default/xui/en/widgets/tab_container.xml b/indra/newview/skins/default/xui/en/widgets/tab_container.xml
index 8d6b0c1cfe..30b0a8462a 100644
--- a/indra/newview/skins/default/xui/en/widgets/tab_container.xml
+++ b/indra/newview/skins/default/xui/en/widgets/tab_container.xml
@@ -13,20 +13,29 @@ label_pad_left - padding to the left of tab button labels
label_pad_left="4">
<first_tab tab_top_image_unselected="TabTop_Left_Off"
tab_top_image_selected="TabTop_Left_Selected"
+ tab_top_image_flash="FlashIconAbsent"
tab_bottom_image_unselected="Toolbar_Left_Off"
tab_bottom_image_selected="Toolbar_Left_Selected"
+ tab_bottom_image_flash="FlashIconAbsent"
tab_left_image_unselected="SegmentedBtn_Left_Disabled"
- tab_left_image_selected="SegmentedBtn_Left_Selected_Over"/>
+ tab_left_image_selected="SegmentedBtn_Left_Selected_Over"
+ tab_left_image_flash="FlashIconAbsent"/>
<middle_tab tab_top_image_unselected="TabTop_Middle_Off"
tab_top_image_selected="TabTop_Middle_Selected"
+ tab_top_image_flash="FlashIconAbsent"
tab_bottom_image_unselected="Toolbar_Middle_Off"
tab_bottom_image_selected="Toolbar_Middle_Selected"
+ tab_bottom_image_flash="FlashIconAbsent"
tab_left_image_unselected="SegmentedBtn_Left_Disabled"
- tab_left_image_selected="SegmentedBtn_Left_Selected_Over"/>
+ tab_left_image_selected="SegmentedBtn_Left_Selected_Over"
+ tab_left_image_flash="FlashIconAbsent"/>
<last_tab tab_top_image_unselected="TabTop_Right_Off"
tab_top_image_selected="TabTop_Right_Selected"
+ tab_top_image_flash="FlashIconAbsent"
tab_bottom_image_unselected="Toolbar_Right_Off"
tab_bottom_image_selected="Toolbar_Right_Selected"
+ tab_bottom_image_flash="FlashIconAbsent"
tab_left_image_unselected="SegmentedBtn_Left_Disabled"
- tab_left_image_selected="SegmentedBtn_Left_Selected_Over"/>
+ tab_left_image_selected="SegmentedBtn_Left_Selected_Over"
+ tab_left_image_flash="FlashIconAbsent"/>
</tab_container>
diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml
index c0bb14afba..dfc12bc1cb 100644
--- a/indra/newview/skins/default/xui/ja/strings.xml
+++ b/indra/newview/skins/default/xui/ja/strings.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- This file contains strings that used to be hardcoded in the source.
It is only for those strings which do not belong in a floater.
For example, the strings used in avatar chat bubbles, and strings
@@ -3762,4 +3762,22 @@ www.secondlife.com から最新バージョンをダウンロードしてくだ
<string name="texture_load_dimensions_error">
[WIDTH]*[HEIGHT] 以上の画像は読み込めません
</string>
+ <!-- overriding datetime formating. leave emtpy in for current localization this is not needed -->
+ <string name="dateTimeWeekdaysNames">
+ Sunday:Monday:Tuesday:Wednesday:Thursday:Friday:Saturday
+ </string>
+ <string name="dateTimeWeekdaysShortNames">
+ Son:Mon:Tue:Wed:Thu:Fri:Sat
+ </string>
+ <string name="dateTimeMonthNames">
+ January:February:March:April:May:June:July:August:September:October:November:December
+ </string>
+ <string name="dateTimeMonthNames">
+ Jan:Feb:Mar:Apr:May:Jun:Jul:Aug:Sep:Oct:Nov:Dec
+ </string>
+ <string name="dateTimeDayFormat">
+ [MDAY] D
+ </string>
+ <string name="dateTimeAM">AM</string>
+ <string name="dateTimePM">PM</string>
</strings>