summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorTofu Linden <tofu.linden@lindenlab.com>2010-04-30 07:49:05 +0100
committerTofu Linden <tofu.linden@lindenlab.com>2010-04-30 07:49:05 +0100
commite4ac91472173b4e943ceb7081c021ed103415a0b (patch)
treea304116660473245e946e4c3b70b8779eb9930f7 /indra
parentcb96bdc188b7177d253426e398932426276762f8 (diff)
parentc19c7d7d3bd2b36e4e7a50d64e38a97a676b0e80 (diff)
merge from PE's viewer-trunk
Diffstat (limited to 'indra')
-rw-r--r--indra/llui/llaccordionctrltab.cpp28
-rw-r--r--indra/llui/llaccordionctrltab.h6
-rw-r--r--indra/newview/llchannelmanager.cpp16
-rw-r--r--indra/newview/llchannelmanager.h5
-rw-r--r--indra/newview/llcofwearables.cpp8
-rw-r--r--indra/newview/llimfloater.cpp23
-rw-r--r--indra/newview/llimfloater.h2
-rw-r--r--indra/newview/llinventorybridge.cpp16
-rw-r--r--indra/newview/llinventoryfunctions.cpp23
-rw-r--r--indra/newview/llinventoryfunctions.h6
-rw-r--r--indra/newview/llinventoryitemslist.cpp55
-rw-r--r--indra/newview/llinventoryitemslist.h17
-rw-r--r--indra/newview/llinventoryobserver.cpp76
-rw-r--r--indra/newview/llinventoryobserver.h13
-rw-r--r--indra/newview/lloutfitslist.cpp119
-rw-r--r--indra/newview/lloutfitslist.h17
-rw-r--r--indra/newview/llpaneloutfitsinventory.cpp30
-rw-r--r--indra/newview/llpreviewnotecard.cpp30
-rw-r--r--indra/newview/llpreviewnotecard.h4
-rw-r--r--indra/newview/llscreenchannel.cpp25
-rw-r--r--indra/newview/llscreenchannel.h6
-rw-r--r--indra/newview/llwearableitemslist.cpp84
-rw-r--r--indra/newview/llwearableitemslist.h30
-rw-r--r--indra/newview/skins/default/xui/en/floater_preview_notecard.xml12
-rw-r--r--indra/newview/skins/default/xui/en/panel_body_parts_list_item.xml7
-rw-r--r--indra/newview/skins/default/xui/en/panel_clothing_list_item.xml8
-rw-r--r--indra/newview/skins/default/xui/en/panel_dummy_clothing_list_item.xml62
-rw-r--r--indra/newview/skins/default/xui/en/panel_outfit_edit.xml24
-rw-r--r--indra/newview/skins/default/xui/en/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_chat.xml2
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml14
31 files changed, 652 insertions, 117 deletions
diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp
index 3c706ce90e..596da782ce 100644
--- a/indra/llui/llaccordionctrltab.cpp
+++ b/indra/llui/llaccordionctrltab.cpp
@@ -436,6 +436,34 @@ void LLAccordionCtrlTab::setAccordionView(LLView* panel)
addChild(panel,0);
}
+void LLAccordionCtrlTab::setTitle(const std::string& title)
+{
+ LLAccordionCtrlTabHeader* header = findChild<LLAccordionCtrlTabHeader>(DD_HEADER_NAME);
+ if (header)
+ {
+ header->setTitle(title);
+ }
+}
+
+boost::signals2::connection LLAccordionCtrlTab::setFocusReceivedCallback(const focus_signal_t::slot_type& cb)
+{
+ LLAccordionCtrlTabHeader* header = findChild<LLAccordionCtrlTabHeader>(DD_HEADER_NAME);
+ if (header)
+ {
+ return header->setFocusReceivedCallback(cb);
+ }
+ return boost::signals2::connection();
+}
+
+boost::signals2::connection LLAccordionCtrlTab::setFocusLostCallback(const focus_signal_t::slot_type& cb)
+{
+ LLAccordionCtrlTabHeader* header = findChild<LLAccordionCtrlTabHeader>(DD_HEADER_NAME);
+ if (header)
+ {
+ return header->setFocusLostCallback(cb);
+ }
+ return boost::signals2::connection();
+}
LLView* LLAccordionCtrlTab::findContainerView()
{
diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h
index fb19d17e99..de254ed3eb 100644
--- a/indra/llui/llaccordionctrltab.h
+++ b/indra/llui/llaccordionctrltab.h
@@ -113,6 +113,12 @@ public:
void setAccordionView(LLView* panel);
LLView* getAccordionView() { return mContainerPanel; };
+ // Set text in LLAccordionCtrlTabHeader
+ void setTitle(const std::string& title);
+
+ boost::signals2::connection setFocusReceivedCallback(const focus_signal_t::slot_type& cb);
+ boost::signals2::connection setFocusLostCallback(const focus_signal_t::slot_type& cb);
+
bool getCollapsible() {return mCollapsible;};
void setCollapsible(bool collapsible) {mCollapsible = collapsible;};
diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp
index 4f9434030f..fafa315a59 100644
--- a/indra/newview/llchannelmanager.cpp
+++ b/indra/newview/llchannelmanager.cpp
@@ -243,3 +243,19 @@ void LLChannelManager::killToastsFromChannel(const LLUUID& channel_id, const LLS
}
}
+// static
+LLNotificationsUI::LLScreenChannel* LLChannelManager::getNotificationScreenChannel()
+{
+ LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*>
+ (LLNotificationsUI::LLChannelManager::getInstance()->
+ findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
+
+ if (channel == NULL)
+ {
+ llwarns << "Can't find screen channel by NotificationChannelUUID" << llendl;
+ llassert(!"Can't find screen channel by NotificationChannelUUID");
+ }
+
+ return channel;
+}
+
diff --git a/indra/newview/llchannelmanager.h b/indra/newview/llchannelmanager.h
index c2be39122f..8c725f2660 100644
--- a/indra/newview/llchannelmanager.h
+++ b/indra/newview/llchannelmanager.h
@@ -114,6 +114,11 @@ public:
*/
void killToastsFromChannel(const LLUUID& channel_id, const LLScreenChannel::Matcher& matcher);
+ /**
+ * Returns notification screen channel.
+ */
+ static LLNotificationsUI::LLScreenChannel* getNotificationScreenChannel();
+
private:
LLScreenChannel* createChannel(LLChannelManager::Params& p);
diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp
index a2a1dd504a..b8222ebb18 100644
--- a/indra/newview/llcofwearables.cpp
+++ b/indra/newview/llcofwearables.cpp
@@ -204,10 +204,10 @@ void LLCOFWearables::addClothingTypesDummies(const LLAppearanceMgr::wearables_by
U32 size = clothing_by_type[type].size();
if (size) continue;
- //*TODO create dummy item panel
-
- //*TODO add dummy item panel -> mClothing->addItem(dummy_item_panel, item->getUUID(), ADD_BOTTOM, false);
-
+ EWearableType w_type = static_cast<EWearableType>(type);
+ LLPanelInventoryListItemBase* item_panel = LLPanelDummyClothingListItem::create(w_type);
+ if(!item_panel) continue;
+ mClothing->addItem(item_panel, LLUUID::null, ADD_BOTTOM, false);
addWearableTypeSeparator(mClothing);
}
}
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 19dbc564d1..c0cc3f1985 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -53,6 +53,7 @@
#include "llsyswellwindow.h"
#include "lltrans.h"
#include "llchathistory.h"
+#include "llnotifications.h"
#include "llviewerwindow.h"
#include "llvoicechannel.h"
#include "lltransientfloatermgr.h"
@@ -371,6 +372,8 @@ void LLIMFloater::onSlide()
//static
LLIMFloater* LLIMFloater::show(const LLUUID& session_id)
{
+ closeHiddenIMToasts();
+
if (!gIMMgr->hasSession(session_id)) return NULL;
if(!isChatMultiTab())
@@ -1084,6 +1087,26 @@ void LLIMFloater::removeTypingIndicator(const LLIMInfo* im_info)
}
// static
+void LLIMFloater::closeHiddenIMToasts()
+{
+ class IMToastMatcher: public LLNotificationsUI::LLScreenChannel::Matcher
+ {
+ public:
+ bool matches(const LLNotificationPtr notification) const
+ {
+ // "notifytoast" type of notifications is reserved for IM notifications
+ return "notifytoast" == notification->getType();
+ }
+ };
+
+ LLNotificationsUI::LLScreenChannel* channel = LLNotificationsUI::LLChannelManager::getNotificationScreenChannel();
+ if (channel != NULL)
+ {
+ channel->closeHiddenToasts(IMToastMatcher());
+ }
+}
+
+// static
bool LLIMFloater::isChatMultiTab()
{
// Restart is required in order to change chat window type.
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 763dd5655b..f9dd8b9b85 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -148,6 +148,8 @@ private:
// Remove the "User is typing..." indicator.
void removeTypingIndicator(const LLIMInfo* im_info = NULL);
+ static void closeHiddenIMToasts();
+
LLPanelChatControlPanel* mControlPanel;
LLUUID mSessionID;
S32 mLastMessageIndex;
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index c6f806178c..2d08c0a01a 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -853,21 +853,7 @@ void LLInvFVBridge::changeItemParent(LLInventoryModel* model,
const LLUUID& new_parent_id,
BOOL restamp)
{
- if (item->getParentUUID() != new_parent_id)
- {
- LLInventoryModel::update_list_t update;
- LLInventoryModel::LLCategoryUpdate old_folder(item->getParentUUID(),-1);
- update.push_back(old_folder);
- LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1);
- update.push_back(new_folder);
- gInventory.accountForUpdate(update);
-
- LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
- new_item->setParent(new_parent_id);
- new_item->updateParentOnServer(restamp);
- model->updateItem(new_item);
- model->notifyObservers();
- }
+ change_item_parent(model, item, new_parent_id, restamp);
}
// static
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index 8487588404..8010d1f43d 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -582,3 +582,26 @@ BOOL get_is_item_worn(const LLUUID& id)
}
return FALSE;
}
+
+
+void change_item_parent(LLInventoryModel* model,
+ LLViewerInventoryItem* item,
+ const LLUUID& new_parent_id,
+ BOOL restamp)
+{
+ if (item->getParentUUID() != new_parent_id)
+ {
+ LLInventoryModel::update_list_t update;
+ LLInventoryModel::LLCategoryUpdate old_folder(item->getParentUUID(),-1);
+ update.push_back(old_folder);
+ LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1);
+ update.push_back(new_folder);
+ gInventory.accountForUpdate(update);
+
+ LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
+ new_item->setParent(new_parent_id);
+ new_item->updateParentOnServer(restamp);
+ model->updateItem(new_item);
+ model->notifyObservers();
+ }
+}
diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h
index e3cd988e39..6f373f7392 100644
--- a/indra/newview/llinventoryfunctions.h
+++ b/indra/newview/llinventoryfunctions.h
@@ -310,6 +310,12 @@ LLUIImagePtr get_item_icon(LLAssetType::EType asset_type,
// Is this item or its baseitem is worn, attached, etc...
BOOL get_is_item_worn(const LLUUID& id);
+
+void change_item_parent(LLInventoryModel* model,
+ LLViewerInventoryItem* item,
+ const LLUUID& new_parent_id,
+ BOOL restamp);
+
#endif // LL_LLINVENTORYFUNCTIONS_H
diff --git a/indra/newview/llinventoryitemslist.cpp b/indra/newview/llinventoryitemslist.cpp
index 3d8cb6dfe8..8dfdb0788a 100644
--- a/indra/newview/llinventoryitemslist.cpp
+++ b/indra/newview/llinventoryitemslist.cpp
@@ -65,14 +65,8 @@ LLPanelInventoryListItemBase* LLPanelInventoryListItemBase::create(LLViewerInven
void LLPanelInventoryListItemBase::updateItem()
{
- if (mItemIcon.notNull())
- mIcon->setImage(mItemIcon);
-
- LLTextUtil::textboxSetHighlightedVal(
- mTitle,
- LLStyle::Params(),
- mItem->getName(),
- mHighlightedText);
+ setIconImage(mIconImage);
+ setTitle(mItem->getName(), mHighlightedText);
}
void LLPanelInventoryListItemBase::addWidgetToLeftSide(const std::string& name, bool show_widget/* = true*/)
@@ -122,9 +116,10 @@ void LLPanelInventoryListItemBase::setShowWidget(LLUICtrl* ctrl, bool show)
BOOL LLPanelInventoryListItemBase::postBuild()
{
- // Inheritors need to call base implementation
- mIcon = getChild<LLIconCtrl>("item_icon");
- mTitle = getChild<LLTextBox>("item_name");
+ setIconCtrl(getChild<LLIconCtrl>("item_icon"));
+ setTitleCtrl(getChild<LLTextBox>("item_name"));
+
+ mIconImage = get_item_icon(mItem->getType(), mItem->getInventoryType(), mItem->getFlags(), FALSE);
updateItem();
@@ -156,13 +151,12 @@ void LLPanelInventoryListItemBase::onMouseLeave(S32 x, S32 y, MASK mask)
LLPanelInventoryListItemBase::LLPanelInventoryListItemBase(LLViewerInventoryItem* item)
: LLPanel()
, mItem(item)
-, mIcon(NULL)
-, mTitle(NULL)
+, mIconCtrl(NULL)
+, mTitleCtrl(NULL)
, mWidgetSpacing(WIDGET_SPACING)
, mLeftWidgetsWidth(0)
, mRightWidgetsWidth(0)
{
- mItemIcon = get_item_icon(mItem->getType(), mItem->getInventoryType(), mItem->getFlags(), FALSE);
}
void LLPanelInventoryListItemBase::init()
@@ -197,6 +191,24 @@ void LLPanelInventoryListItemBase::reshapeWidgets()
reshapeMiddleWidgets();
}
+void LLPanelInventoryListItemBase::setIconImage(const LLUIImagePtr& image)
+{
+ if(image)
+ {
+ mIconImage = image;
+ mIconCtrl->setImage(mIconImage);
+ }
+}
+
+void LLPanelInventoryListItemBase::setTitle(const std::string& title, const std::string& highlit_text)
+{
+ LLTextUtil::textboxSetHighlightedVal(
+ mTitleCtrl,
+ LLStyle::Params(),
+ title,
+ highlit_text);
+}
+
void LLPanelInventoryListItemBase::reshapeLeftWidgets()
{
S32 widget_left = 0;
@@ -246,16 +258,16 @@ void LLPanelInventoryListItemBase::reshapeRightWidgets()
void LLPanelInventoryListItemBase::reshapeMiddleWidgets()
{
- LLRect icon_rect(mIcon->getRect());
+ LLRect icon_rect(mIconCtrl->getRect());
icon_rect.setLeftTopAndSize(mLeftWidgetsWidth + getWidgetSpacing(), icon_rect.mTop,
icon_rect.getWidth(), icon_rect.getHeight());
- mIcon->setShape(icon_rect);
+ mIconCtrl->setShape(icon_rect);
S32 name_left = icon_rect.mRight + getWidgetSpacing();
S32 name_right = getLocalRect().getWidth() - mRightWidgetsWidth - getWidgetSpacing();
- LLRect name_rect(mTitle->getRect());
+ LLRect name_rect(mTitleCtrl->getRect());
name_rect.set(name_left, name_rect.mTop, name_right, name_rect.mBottom);
- mTitle->setShape(name_rect);
+ mTitleCtrl->setShape(name_rect);
}
////////////////////////////////////////////////////////////////////////////////
@@ -356,17 +368,18 @@ void LLInventoryItemsList::addNewItem(LLViewerInventoryItem* item)
if (!item)
{
llwarns << "No inventory item. Couldn't create flat list item." << llendl;
- llassert(!"No inventory item. Couldn't create flat list item.");
+ llassert(item != NULL);
}
LLPanelInventoryListItemBase *list_item = LLPanelInventoryListItemBase::create(item);
if (!list_item)
return;
- if (!addItem(list_item, item->getUUID()))
+ bool is_item_added = addItem(list_item, item->getUUID());
+ if (!is_item_added)
{
llwarns << "Couldn't add flat list item." << llendl;
- llassert(!"Couldn't add flat list item.");
+ llassert(is_item_added);
}
}
diff --git a/indra/newview/llinventoryitemslist.h b/indra/newview/llinventoryitemslist.h
index 15f04c79a9..152aafbd7e 100644
--- a/indra/newview/llinventoryitemslist.h
+++ b/indra/newview/llinventoryitemslist.h
@@ -125,6 +125,11 @@ protected:
*/
virtual void init();
+ /** setter for mIconCtrl */
+ void setIconCtrl(LLIconCtrl* icon) { mIconCtrl = icon; }
+ /** setter for MTitleCtrl */
+ void setTitleCtrl(LLTextBox* tb) { mTitleCtrl = tb; }
+
void setLeftWidgetsWidth(S32 width) { mLeftWidgetsWidth = width; }
void setRightWidgetsWidth(S32 width) { mRightWidgetsWidth = width; }
@@ -139,6 +144,12 @@ protected:
*/
virtual void reshapeWidgets();
+ /** set wearable type icon image */
+ void setIconImage(const LLUIImagePtr& image);
+
+ /** Set item title - inventory item name usually */
+ void setTitle(const std::string& title, const std::string& highlit_text);
+
private:
/** reshape left side widgets
@@ -155,10 +166,10 @@ private:
LLViewerInventoryItem* mItem;
- LLIconCtrl* mIcon;
- LLTextBox* mTitle;
+ LLIconCtrl* mIconCtrl;
+ LLTextBox* mTitleCtrl;
- LLUIImagePtr mItemIcon;
+ LLUIImagePtr mIconImage;
std::string mHighlightedText;
widget_array_t mLeftSideWidgets;
diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp
index 214b5d317a..86147d65e6 100644
--- a/indra/newview/llinventoryobserver.cpp
+++ b/indra/newview/llinventoryobserver.cpp
@@ -215,7 +215,7 @@ void LLInventoryFetchItemsObserver::changed(U32 mask)
void fetch_items_from_llsd(const LLSD& items_llsd)
{
- if (!items_llsd.size()) return;
+ if (!items_llsd.size() || gDisconnected) return;
LLSD body;
body[0]["cap_name"] = "FetchInventory";
body[1]["cap_name"] = "FetchLib";
@@ -235,6 +235,11 @@ void fetch_items_from_llsd(const LLSD& items_llsd)
for (S32 i=0; i<body.size(); i++)
{
+ if(!gAgent.getRegion())
+ {
+ llwarns<<"Agent's region is null"<<llendl;
+ break;
+ }
if (0 >= body[i].size()) continue;
std::string url = gAgent.getRegion()->getCapability(body[i]["cap_name"].asString());
@@ -664,36 +669,87 @@ void LLInventoryCategoriesObserver::changed(U32 mask)
if (!category)
continue;
- S32 version = category->getVersion();
- if (version != (*iter).second.mVersion)
+ const S32 version = category->getVersion();
+ const S32 expected_num_descendents = category->getDescendentCount();
+ if ((version == LLViewerInventoryCategory::VERSION_UNKNOWN) ||
+ (expected_num_descendents == LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN))
{
- // Update category version in map.
- (*iter).second.mVersion = version;
- (*iter).second.mCallback();
+ continue;
+ }
+
+ // Check number of known descendents to find out whether it has changed.
+ LLInventoryModel::cat_array_t* cats;
+ LLInventoryModel::item_array_t* items;
+ gInventory.getDirectDescendentsOf((*iter).first, cats, items);
+ if (!cats || !items)
+ {
+ llwarns << "Category '" << category->getName() << "' descendents corrupted, fetch failed." << llendl;
+ // NULL means the call failed -- cats/items map doesn't exist (note: this does NOT mean
+ // that the cat just doesn't have any items or subfolders).
+ // Unrecoverable, so just skip this category.
+
+ llassert(cats != NULL && items != NULL);
+ }
+ const S32 current_num_known_descendents = cats->count() + items->count();
+
+ LLCategoryData cat_data = (*iter).second;
+
+ // If category version or descendents count has changed
+ // update category data in mCategoryMap and fire a callback.
+ if (version != cat_data.mVersion || current_num_known_descendents != cat_data.mDescendentsCount)
+ {
+ cat_data.mVersion = version;
+ cat_data.mDescendentsCount = current_num_known_descendents;
+
+ cat_data.mCallback();
}
}
}
-void LLInventoryCategoriesObserver::addCategory(const LLUUID& cat_id, callback_t cb)
+bool LLInventoryCategoriesObserver::addCategory(const LLUUID& cat_id, callback_t cb)
{
S32 version;
+ S32 current_num_known_descendents;
+ bool can_be_added = true;
+
LLViewerInventoryCategory* category = gInventory.getCategory(cat_id);
if (category)
{
// Inventory category version is used to find out if some changes
// to a category have been made.
version = category->getVersion();
+
+ LLInventoryModel::cat_array_t* cats;
+ LLInventoryModel::item_array_t* items;
+ gInventory.getDirectDescendentsOf(cat_id, cats, items);
+ if (!cats || !items)
+ {
+ llwarns << "Category '" << category->getName() << "' descendents corrupted, fetch failed." << llendl;
+ // NULL means the call failed -- cats/items map doesn't exist (note: this does NOT mean
+ // that the cat just doesn't have any items or subfolders).
+ // Unrecoverable, so just return "false" meaning that the category can't be observed.
+ can_be_added = false;
+
+ llassert(cats != NULL && items != NULL);
+ }
+ current_num_known_descendents = cats->count() + items->count();
}
else
{
// If category could not be retrieved it might mean that
// inventory is unusable at the moment so the category is
- // stored with VERSION_UNKNOWN and it may be updated later.
+ // stored with VERSION_UNKNOWN and DESCENDENT_COUNT_UNKNOWN,
+ // it may be updated later.
version = LLViewerInventoryCategory::VERSION_UNKNOWN;
+ current_num_known_descendents = LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN;
+ }
+
+ if (can_be_added)
+ {
+ mCategoryMap.insert(category_map_value_t(cat_id, LLCategoryData(cb, version, current_num_known_descendents)));
}
- version = category->getVersion();
- mCategoryMap.insert(category_map_value_t(cat_id, LLCategoryData(cb, version)));
+ return can_be_added;
}
void LLInventoryCategoriesObserver::removeCategory(const LLUUID& cat_id)
diff --git a/indra/newview/llinventoryobserver.h b/indra/newview/llinventoryobserver.h
index e63b67d2ad..036e6ca40d 100644
--- a/indra/newview/llinventoryobserver.h
+++ b/indra/newview/llinventoryobserver.h
@@ -276,19 +276,28 @@ public:
LLInventoryCategoriesObserver() {};
virtual void changed(U32 mask);
- void addCategory(const LLUUID& cat_id, callback_t cb);
+ /**
+ * Add cat_id to the list of observed categories with a
+ * callback fired on category being changed.
+ *
+ * @return "true" if category was added, "false" if it could
+ * not be found.
+ */
+ bool addCategory(const LLUUID& cat_id, callback_t cb);
void removeCategory(const LLUUID& cat_id);
protected:
struct LLCategoryData
{
- LLCategoryData(callback_t cb, S32 version)
+ LLCategoryData(callback_t cb, S32 version, S32 num_descendents)
: mCallback(cb)
, mVersion(version)
+ , mDescendentsCount(num_descendents)
{}
callback_t mCallback;
S32 mVersion;
+ S32 mDescendentsCount;
};
typedef std::map<LLUUID, LLCategoryData> category_map_t;
diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp
index 1215272685..b103ec45d0 100644
--- a/indra/newview/lloutfitslist.cpp
+++ b/indra/newview/lloutfitslist.cpp
@@ -41,6 +41,7 @@
#include "llaccordionctrl.h"
#include "llaccordionctrltab.h"
+#include "llappearancemgr.h"
#include "llinventoryfunctions.h"
#include "llinventorymodel.h"
#include "llwearableitemslist.h"
@@ -51,6 +52,7 @@ LLOutfitsList::LLOutfitsList()
: LLPanel()
, mAccordion(NULL)
, mListCommands(NULL)
+ , mSelectedList(NULL)
{
mCategoriesObserver = new LLInventoryCategoriesObserver();
gInventory.addObserver(mCategoriesObserver);
@@ -135,30 +137,37 @@ void LLOutfitsList::refreshList(const LLUUID& category_id)
{
const LLUUID cat_id = (*iter);
LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
- if (!cat)
- continue;
+ if (!cat) continue;
std::string name = cat->getName();
static LLXMLNodePtr accordionXmlNode = getAccordionTabXMLNode();
-
- accordionXmlNode->setAttributeString("name", name);
- accordionXmlNode->setAttributeString("title", name);
LLAccordionCtrlTab* tab = LLUICtrlFactory::defaultBuilder<LLAccordionCtrlTab>(accordionXmlNode, NULL, NULL);
+ tab->setName(name);
+ tab->setTitle(name);
+
// *TODO: LLUICtrlFactory::defaultBuilder does not use "display_children" from xml. Should be investigated.
tab->setDisplayChildren(false);
mAccordion->addCollapsibleCtrl(tab);
+ // Start observing the new outfit category.
+ LLWearableItemsList* list = tab->getChild<LLWearableItemsList>("wearable_items_list");
+ if (!mCategoriesObserver->addCategory(cat_id, boost::bind(&LLWearableItemsList::updateList, list, cat_id)))
+ {
+ // Remove accordion tab if category could not be added to observer.
+ mAccordion->removeCollapsibleCtrl(tab);
+ continue;
+ }
+
// Map the new tab with outfit category UUID.
mOutfitsMap.insert(LLOutfitsList::outfits_map_value_t(cat_id, tab));
- // Start observing the new outfit category.
- LLWearableItemsList* list = tab->getChild<LLWearableItemsList>("wearable_items_list");
- mCategoriesObserver->addCategory(cat_id, boost::bind(&LLWearableItemsList::updateList, list, cat_id));
+ // Setting tab focus callback to monitor currently selected outfit.
+ tab->setFocusReceivedCallback(boost::bind(&LLOutfitsList::changeOutfitSelection, this, list, cat_id));
- // Setting drop down callback to monitor currently selected outfit.
- tab->setDropDownStateChangedCallback(boost::bind(&LLOutfitsList::onTabExpandedCollapsed, this, list));
+ // Setting list commit callback to monitor currently selected wearable item.
+ list->setCommitCallback(boost::bind(&LLOutfitsList::onSelectionChange, this, _1));
// Fetch the new outfit contents.
cat->fetch();
@@ -178,10 +187,18 @@ void LLOutfitsList::refreshList(const LLUUID& category_id)
// 1. Remove outfit accordion tab from accordion.
mAccordion->removeCollapsibleCtrl(outfits_iter->second);
+ const LLUUID& outfit_id = outfits_iter->first;
+
// 2. Remove outfit category from observer to stop monitoring its changes.
- mCategoriesObserver->removeCategory(outfits_iter->first);
+ mCategoriesObserver->removeCategory(outfit_id);
- // 3. Remove category UUID to accordion tab mapping.
+ // 3. Reset selection if selected outfit is being removed.
+ if (mSelectedOutfitUUID == outfit_id)
+ {
+ changeOutfitSelection(NULL, LLUUID());
+ }
+
+ // 4. Remove category UUID to accordion tab mapping.
mOutfitsMap.erase(outfits_iter);
}
}
@@ -199,40 +216,30 @@ void LLOutfitsList::refreshList(const LLUUID& category_id)
mAccordion->arrange();
}
-void LLOutfitsList::updateOutfitTab(const LLUUID& category_id)
+void LLOutfitsList::onSelectionChange(LLUICtrl* ctrl)
{
- outfits_map_t::iterator outfits_iter = mOutfitsMap.find(category_id);
- if (outfits_iter != mOutfitsMap.end())
- {
- LLViewerInventoryCategory *cat = gInventory.getCategory(category_id);
- if (!cat)
- return;
+ LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(ctrl);
+ if (!list) return;
- std::string name = cat->getName();
+ LLViewerInventoryItem *item = gInventory.getItem(list->getSelectedUUID());
+ if (!item) return;
- // Update tab name with the new category name.
- LLAccordionCtrlTab* tab = outfits_iter->second;
- if (tab)
- {
- tab->setName(name);
- }
-
- // Update tab title with the new category name using textbox
- // in accordion tab header.
- LLTextBox* tab_title = tab->findChild<LLTextBox>("dd_textbox");
- if (tab_title)
- {
- tab_title->setText(name);
- }
- }
+ changeOutfitSelection(list, item->getParentUUID());
}
-void LLOutfitsList::onTabExpandedCollapsed(LLWearableItemsList* list)
+void LLOutfitsList::performAction(std::string action)
{
- if (!list)
- return;
+ LLViewerInventoryCategory* cat = gInventory.getCategory(mSelectedOutfitUUID);
+ if (!cat) return;
- // TODO: Add outfit selection handling.
+ if ("replaceoutfit" == action)
+ {
+ LLAppearanceMgr::instance().wearInventoryCategory( cat, FALSE, FALSE );
+ }
+ else if ("addtooutfit" == action)
+ {
+ LLAppearanceMgr::instance().wearInventoryCategory( cat, FALSE, TRUE );
+ }
}
void LLOutfitsList::setFilterSubString(const std::string& string)
@@ -240,7 +247,6 @@ void LLOutfitsList::setFilterSubString(const std::string& string)
mFilterSubString = string;
}
-
//////////////////////////////////////////////////////////////////////////
// Private methods
//////////////////////////////////////////////////////////////////////////
@@ -283,4 +289,37 @@ void LLOutfitsList::computeDifference(
LLCommonUtils::computeDifference(vnew, vcur, vadded, vremoved);
}
+void LLOutfitsList::updateOutfitTab(const LLUUID& category_id)
+{
+ outfits_map_t::iterator outfits_iter = mOutfitsMap.find(category_id);
+ if (outfits_iter != mOutfitsMap.end())
+ {
+ LLViewerInventoryCategory *cat = gInventory.getCategory(category_id);
+ if (!cat) return;
+
+ std::string name = cat->getName();
+
+ // Update tab name with the new category name.
+ LLAccordionCtrlTab* tab = outfits_iter->second;
+ if (tab)
+ {
+ tab->setName(name);
+ tab->setTitle(name);
+ }
+ }
+}
+
+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)
+ {
+ mSelectedList->resetSelection();
+ }
+
+ mSelectedList = list;
+ mSelectedOutfitUUID = category_id;
+}
+
// EOF
diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h
index 2d103ea356..d86cf5a703 100644
--- a/indra/newview/lloutfitslist.h
+++ b/indra/newview/lloutfitslist.h
@@ -65,10 +65,9 @@ public:
void refreshList(const LLUUID& category_id);
- // Update tab displaying outfit identified by category_id.
- void updateOutfitTab(const LLUUID& category_id);
+ void onSelectionChange(LLUICtrl* ctrl);
- void onTabExpandedCollapsed(LLWearableItemsList* list);
+ void performAction(std::string action);
void setFilterSubString(const std::string& string);
@@ -85,12 +84,24 @@ private:
*/
void computeDifference(const LLInventoryModel::cat_array_t& vcats, uuid_vec_t& vadded, uuid_vec_t& vremoved);
+ /**
+ * Updates tab displaying outfit identified by category_id.
+ */
+ void updateOutfitTab(const LLUUID& category_id);
+
+ /**
+ * Resets previous selection and stores newly selected list and outfit id.
+ */
+ void changeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id);
LLInventoryCategoriesObserver* mCategoriesObserver;
LLAccordionCtrl* mAccordion;
LLPanel* mListCommands;
+ LLWearableItemsList* mSelectedList;
+ LLUUID mSelectedOutfitUUID;
+
std::string mFilterSubString;
typedef std::map<LLUUID, LLAccordionCtrlTab*> outfits_map_t;
diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp
index 789e85b46f..80964938f5 100644
--- a/indra/newview/llpaneloutfitsinventory.cpp
+++ b/indra/newview/llpaneloutfitsinventory.cpp
@@ -188,19 +188,37 @@ void LLPanelOutfitsInventory::onSearchEdit(const std::string& string)
void LLPanelOutfitsInventory::onWearButtonClick()
{
- LLFolderViewEventListener* listenerp = getCorrectListenerForAction();
- if (listenerp)
+ // TODO: Remove if/else, add common interface
+ // for "My Outfits" and "Wearing" tabs.
+ if (!isCOFPanelActive())
+ {
+ mMyOutfitsPanel->performAction("replaceoutfit");
+ }
+ else
{
- listenerp->performAction(NULL, "replaceoutfit");
+ LLFolderViewEventListener* listenerp = getCorrectListenerForAction();
+ if (listenerp)
+ {
+ listenerp->performAction(NULL, "replaceoutfit");
+ }
}
}
void LLPanelOutfitsInventory::onAdd()
{
- LLFolderViewEventListener* listenerp = getCorrectListenerForAction();
- if (listenerp)
+ // TODO: Remove if/else, add common interface
+ // for "My Outfits" and "Wearing" tabs.
+ if (!isCOFPanelActive())
+ {
+ mMyOutfitsPanel->performAction("addtooutfit");
+ }
+ else
{
- listenerp->performAction(NULL, "addtooutfit");
+ LLFolderViewEventListener* listenerp = getCorrectListenerForAction();
+ if (listenerp)
+ {
+ listenerp->performAction(NULL, "addtooutfit");
+ }
}
}
diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp
index 75702dc8e5..fb7ac0d86b 100644
--- a/indra/newview/llpreviewnotecard.cpp
+++ b/indra/newview/llpreviewnotecard.cpp
@@ -35,6 +35,7 @@
#include "llpreviewnotecard.h"
#include "llinventory.h"
+#include "llinventoryfunctions.h" // for change_item_parent()
#include "llagent.h"
#include "llassetuploadresponders.h"
@@ -92,11 +93,17 @@ BOOL LLPreviewNotecard::postBuild()
childSetAction("Save", onClickSave, this);
childSetVisible("lock", FALSE);
+ childSetAction("Delete", onClickDelete, this);
+ childSetEnabled("Delete", false);
+
const LLInventoryItem* item = getItem();
childSetCommitCallback("desc", LLPreview::onText, this);
if (item)
+ {
childSetText("desc", item->getDescription());
+ childSetEnabled("Delete", true);
+ }
childSetPrevalidate("desc", &LLTextValidate::validateASCIIPrintableNoPipe);
return LLPreview::postBuild();
@@ -374,6 +381,17 @@ void LLPreviewNotecard::onClickSave(void* user_data)
}
}
+
+// static
+void LLPreviewNotecard::onClickDelete(void* user_data)
+{
+ LLPreviewNotecard* preview = (LLPreviewNotecard*)user_data;
+ if(preview)
+ {
+ preview->deleteNotecard();
+ }
+}
+
struct LLSaveNotecardInfo
{
LLPreviewNotecard* mSelf;
@@ -466,6 +484,18 @@ bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem)
return true;
}
+void LLPreviewNotecard::deleteNotecard()
+{
+ LLViewerInventoryItem* item = gInventory.getItem(mItemUUID);
+ if (item != NULL)
+ {
+ const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ change_item_parent(&gInventory, item, trash_id, FALSE);
+ }
+
+ closeFloater();
+}
+
// static
void LLPreviewNotecard::onSaveComplete(const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed)
{
diff --git a/indra/newview/llpreviewnotecard.h b/indra/newview/llpreviewnotecard.h
index e0363eef54..98de99aa33 100644
--- a/indra/newview/llpreviewnotecard.h
+++ b/indra/newview/llpreviewnotecard.h
@@ -83,6 +83,8 @@ protected:
virtual void loadAsset();
bool saveIfNeeded(LLInventoryItem* copyitem = NULL);
+ void deleteNotecard();
+
static void onLoadComplete(LLVFS *vfs,
const LLUUID& asset_uuid,
LLAssetType::EType type,
@@ -90,6 +92,8 @@ protected:
static void onClickSave(void* data);
+ static void onClickDelete(void* data);
+
static void onSaveComplete(const LLUUID& asset_uuid,
void* user_data,
S32 status, LLExtStat ext_status);
diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp
index af440a3689..de1da248c1 100644
--- a/indra/newview/llscreenchannel.cpp
+++ b/indra/newview/llscreenchannel.cpp
@@ -706,6 +706,31 @@ void LLScreenChannel::hideToast(const LLUUID& notification_id)
}
}
+void LLScreenChannel::closeHiddenToasts(const Matcher& matcher)
+{
+ // since we can't guarantee that close toast operation doesn't change mToastList
+ // we collect matched toasts that should be closed into separate list
+ std::list<ToastElem> toasts;
+ for (std::vector<ToastElem>::iterator it = mToastList.begin(); it
+ != mToastList.end(); it++)
+ {
+ LLToast * toast = it->toast;
+ // add to list valid toast that match to provided matcher criteria
+ if (toast != NULL && !toast->isDead() && toast->getNotification() != NULL
+ && !toast->getVisible() && matcher.matches(toast->getNotification()))
+ {
+ toasts.push_back(*it);
+ }
+ }
+
+ // close collected toasts
+ for (std::list<ToastElem>::iterator it = toasts.begin(); it
+ != toasts.end(); it++)
+ {
+ it->toast->closeFloater();
+ }
+}
+
//--------------------------------------------------------------------------
void LLScreenChannel::removeToastsFromChannel()
{
diff --git a/indra/newview/llscreenchannel.h b/indra/newview/llscreenchannel.h
index 88053d87d9..46c5fed7b6 100644
--- a/indra/newview/llscreenchannel.h
+++ b/indra/newview/llscreenchannel.h
@@ -173,6 +173,12 @@ public:
void hideToastsFromScreen();
// hide toast by notification id
void hideToast(const LLUUID& notification_id);
+
+ /**
+ * Closes hidden matched toasts from channel.
+ */
+ void closeHiddenToasts(const Matcher& matcher);
+
// removes all toasts from a channel
void removeToastsFromChannel();
// show all toasts in a channel
diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp
index b8fab63be9..56b2791993 100644
--- a/indra/newview/llwearableitemslist.cpp
+++ b/indra/newview/llwearableitemslist.cpp
@@ -33,8 +33,11 @@
#include "llwearableitemslist.h"
+#include "lliconctrl.h"
+
#include "llinventoryfunctions.h"
#include "llinventorymodel.h"
+#include "lltransutil.h"
class LLFindOutfitItems : public LLInventoryCollectFunctor
{
@@ -212,6 +215,87 @@ void LLPanelBodyPartsListItem::setShowEditButton(bool show)
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
+LLPanelDummyClothingListItem* LLPanelDummyClothingListItem::create(EWearableType w_type)
+{
+ LLPanelDummyClothingListItem* list_item = new LLPanelDummyClothingListItem(w_type);
+ list_item->init();
+ return list_item;
+}
+
+void LLPanelDummyClothingListItem::updateItem()
+{
+ std::string title = wearableTypeToString(mWearableType);
+ setTitle(title, LLStringUtil::null);
+}
+
+BOOL LLPanelDummyClothingListItem::postBuild()
+{
+ LLIconCtrl* icon = getChild<LLIconCtrl>("item_icon");
+ setIconCtrl(icon);
+ setTitleCtrl(getChild<LLTextBox>("item_name"));
+
+ addWidgetToRightSide("btn_add");
+
+ setIconImage(get_item_icon(LLAssetType::AT_CLOTHING, LLInventoryType::IT_NONE, mWearableType, FALSE));
+ updateItem();
+
+ // Make it look loke clothing item - reserve space for 'delete' button
+ setLeftWidgetsWidth(icon->getRect().mLeft);
+
+ setWidgetsVisible(false);
+ reshapeWidgets();
+
+ return TRUE;
+}
+
+LLPanelDummyClothingListItem::LLPanelDummyClothingListItem(EWearableType w_type)
+ : LLPanelWearableListItem(NULL)
+ , mWearableType(w_type)
+{
+}
+
+void LLPanelDummyClothingListItem::init()
+{
+ LLUICtrlFactory::getInstance()->buildPanel(this, "panel_dummy_clothing_list_item.xml");
+}
+
+typedef std::map<EWearableType, std::string> clothing_to_string_map_t;
+
+clothing_to_string_map_t init_clothing_string_map()
+{
+ clothing_to_string_map_t w_map;
+ w_map.insert(std::make_pair(WT_SHIRT, "shirt_not_worn"));
+ w_map.insert(std::make_pair(WT_PANTS, "pants_not_worn"));
+ w_map.insert(std::make_pair(WT_SHOES, "shoes_not_worn"));
+ w_map.insert(std::make_pair(WT_SOCKS, "socks_not_worn"));
+ w_map.insert(std::make_pair(WT_JACKET, "jacket_not_worn"));
+ w_map.insert(std::make_pair(WT_GLOVES, "gloves_not_worn"));
+ w_map.insert(std::make_pair(WT_UNDERSHIRT, "undershirt_not_worn"));
+ w_map.insert(std::make_pair(WT_UNDERPANTS, "underpants_not_worn"));
+ w_map.insert(std::make_pair(WT_SKIRT, "skirt_not_worn"));
+ w_map.insert(std::make_pair(WT_ALPHA, "alpha_not_worn"));
+ w_map.insert(std::make_pair(WT_TATTOO, "tattoo_not_worn"));
+ return w_map;
+}
+
+std::string LLPanelDummyClothingListItem::wearableTypeToString(EWearableType w_type)
+{
+ static const clothing_to_string_map_t w_map = init_clothing_string_map();
+ static const std::string invalid_str = LLTrans::getString("invalid_not_worn");
+
+ std::string type_str = invalid_str;
+ clothing_to_string_map_t::const_iterator it = w_map.find(w_type);
+ if(w_map.end() != it)
+ {
+ type_str = LLTrans::getString(it->second);
+ }
+ return type_str;
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
static const LLDefaultChildRegistry::Register<LLWearableItemsList> r("wearable_items_list");
LLWearableItemsList::Params::Params()
diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h
index ae43b3f673..c4a415dfbf 100644
--- a/indra/newview/llwearableitemslist.h
+++ b/indra/newview/llwearableitemslist.h
@@ -81,7 +81,6 @@ public:
virtual ~LLPanelClothingListItem();
- /*virtual*/ void init();
/*virtual*/ BOOL postBuild();
/**
@@ -96,6 +95,8 @@ public:
protected:
LLPanelClothingListItem(LLViewerInventoryItem* item);
+
+ /*virtual*/ void init();
};
class LLPanelBodyPartsListItem : public LLPanelWearableListItem
@@ -107,7 +108,6 @@ public:
virtual ~LLPanelBodyPartsListItem();
- /*virtual*/ void init();
/*virtual*/ BOOL postBuild();
/**
@@ -118,6 +118,32 @@ public:
protected:
LLPanelBodyPartsListItem(LLViewerInventoryItem* item);
+
+ /*virtual*/ void init();
+};
+
+/**
+ * @class LLPanelDummyClothingListItem
+ *
+ * A dummy item panel - displays grayed clothing icon, grayed title '<clothing> not worn' and 'add' button
+ */
+class LLPanelDummyClothingListItem : public LLPanelWearableListItem
+{
+public:
+ static LLPanelDummyClothingListItem* create(EWearableType w_type);
+
+ /*virtual*/ void updateItem();
+ /*virtual*/ BOOL postBuild();
+
+protected:
+ LLPanelDummyClothingListItem(EWearableType w_type);
+
+ /*virtual*/ void init();
+
+ static std::string wearableTypeToString(EWearableType w_type);
+
+private:
+ EWearableType mWearableType;
};
/**
diff --git a/indra/newview/skins/default/xui/en/floater_preview_notecard.xml b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
index 14c0081c0d..0e8eef2a21 100644
--- a/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
+++ b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
@@ -84,8 +84,18 @@
label="Save"
label_selected="Save"
layout="topleft"
- left="288"
+ left="178"
name="Save"
top="332"
width="100" />
+ <button
+ follows="right|bottom"
+ height="22"
+ label="Delete"
+ label_selected="Delete"
+ layout="topleft"
+ left="288"
+ name="Delete"
+ top="332"
+ width="100" />
</floater>
diff --git a/indra/newview/skins/default/xui/en/panel_body_parts_list_item.xml b/indra/newview/skins/default/xui/en/panel_body_parts_list_item.xml
index 445f677c94..4313d450fb 100644
--- a/indra/newview/skins/default/xui/en/panel_body_parts_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_body_parts_list_item.xml
@@ -48,14 +48,13 @@
top="4"
value="..."
width="359" />
- <button
+ <icon
name="btn_lock"
layout="topleft"
follows="top|right"
- image_unselected="Lock2"
- image_selected="Lock2"
+ image_name="Lock2"
top="0"
- left_pad="3"
+ left="0"
height="20"
width="20"
tab_stop="false" />
diff --git a/indra/newview/skins/default/xui/en/panel_clothing_list_item.xml b/indra/newview/skins/default/xui/en/panel_clothing_list_item.xml
index 386b3b2c4f..8dc67de06f 100644
--- a/indra/newview/skins/default/xui/en/panel_clothing_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_clothing_list_item.xml
@@ -81,17 +81,15 @@
height="20"
width="20"
tab_stop="false" />
- <button
+ <icon
name="btn_lock"
layout="topleft"
follows="top|right"
- image_unselected="Lock2"
- image_selected="Lock2"
+ image_name="Lock2"
top="0"
left_pad="3"
height="20"
- width="20"
- tab_stop="false" />
+ width="20" />
<button
name="btn_edit"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_dummy_clothing_list_item.xml b/indra/newview/skins/default/xui/en/panel_dummy_clothing_list_item.xml
new file mode 100644
index 0000000000..dbbfa8f2e2
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_dummy_clothing_list_item.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ follows="top|right|left"
+ height="20"
+ layout="topleft"
+ left="0"
+ name="dummy_clothing_item"
+ top="0"
+ width="380">
+ <icon
+ follows="top|right|left"
+ height="20"
+ image_name="ListItem_Over"
+ layout="topleft"
+ left="0"
+ name="hovered_icon"
+ top="0"
+ visible="false"
+ width="380" />
+ <icon
+ height="20"
+ follows="top|right|left"
+ image_name="ListItem_Select"
+ layout="topleft"
+ left="0"
+ name="selected_icon"
+ top="0"
+ visible="false"
+ width="380" />
+ <icon
+ height="16"
+ color="0.75 0.75 0.75 1"
+ follows="top|left"
+ image_name="Inv_Object"
+ layout="topleft"
+ left="20"
+ name="item_icon"
+ top="2"
+ width="16" />
+ <text
+ follows="left|right"
+ height="16"
+ layout="topleft"
+ left_pad="5"
+ allow_html="false"
+ use_ellipses="true"
+ name="item_name"
+ text_color="LtGray_50"
+ top="4"
+ value="..."
+ width="359" />
+ <button
+ name="btn_add"
+ layout="topleft"
+ follows="top|right"
+ label="+"
+ top="0"
+ left="0"
+ height="20"
+ width="20"
+ tab_stop="false" />
+</panel>
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 73181392c9..a9f588698a 100644
--- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
@@ -234,6 +234,14 @@
name="move_further_btn"
top="1"
width="31" />
+ <icon
+ follows="bottom|left"
+ height="25"
+ image_name="Toolbar_Middle_Off"
+ layout="topleft"
+ left_pad="1"
+ name="dummy_icon"
+ width="105" />
<button
follows="bottom|right"
height="25"
@@ -440,6 +448,22 @@
name="add_to_outfit_btn"
top="1"
width="31" />
+ <icon
+ follows="bottom|left"
+ height="25"
+ image_name="Toolbar_Middle_Off"
+ layout="topleft"
+ left_pad="1"
+ name="dummy_middle_icon"
+ width="140" />
+ <icon
+ follows="bottom|left"
+ height="25"
+ image_name="Toolbar_Right_Off"
+ layout="topleft"
+ left_pad="1"
+ name="dummy_right_icon"
+ width="31" />
</panel>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index 066ea3be6e..7e212c9383 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -490,6 +490,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
label="Share"
layout="topleft"
name="share_btn"
+ tool_tip="Share an inventory item"
width="62" />
<button
follows="bottom|left"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
index 3ef16d2dec..ba967d3e2c 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
@@ -330,7 +330,7 @@
<check_box
enabled="false"
height="16"
- label="Enable plain text chat history"
+ label="Enable plain text IM and chat history"
layout="topleft"
left_delta="0"
name="plain_text_chat_history"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 3cba76cbfa..e0d58a16c8 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -1802,6 +1802,20 @@ Clears (deletes) the media and all params from the given face.
<string name="alpha">Alpha</string>
<string name="tattoo">Tattoo</string>
<string name="invalid">invalid</string>
+
+ <!-- Not Worn Wearable Types -->
+ <string name="shirt_not_worn">Shirt not worn</string>
+ <string name="pants_not_worn">Pants not worn</string>
+ <string name="shoes_not_worn">Shoes not worn</string>
+ <string name="socks_not_worn">Socks not worn</string>
+ <string name="jacket_not_worn">Jacket not worn</string>
+ <string name="gloves_not_worn">Gloves not worn</string>
+ <string name="undershirt_not_worn">Undershirt not worn</string>
+ <string name="underpants_not_worn">Underpants not worn</string>
+ <string name="skirt_not_worn">Skirt not worn</string>
+ <string name="alpha_not_worn">Alpha not worn</string>
+ <string name="tattoo_not_worn">Tattoo not worn</string>
+ <string name="invalid_not_worn">invalid</string>
<!-- Wearable List-->
<string name="NewWearable">New [WEARABLE_ITEM]</string>