summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llchathistory.cpp2
-rw-r--r--indra/newview/llfolderview.cpp22
-rw-r--r--indra/newview/llinventoryitemslist.cpp10
-rw-r--r--indra/newview/lloutfitobserver.cpp20
-rw-r--r--indra/newview/lloutfitobserver.h3
-rw-r--r--indra/newview/lloutfitslist.cpp55
-rw-r--r--indra/newview/lloutfitslist.h12
-rw-r--r--indra/newview/llpaneloutfitedit.cpp1
-rw-r--r--indra/newview/llpaneloutfitsinventory.cpp32
-rw-r--r--indra/newview/llwearableitemslist.cpp34
-rw-r--r--indra/newview/llwearableitemslist.h6
-rw-r--r--indra/newview/skins/default/xui/en/menu_wearable_list_item.xml14
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_cof_wearables.xml6
-rw-r--r--indra/newview/skins/default/xui/en/panel_dummy_clothing_list_item.xml20
-rw-r--r--indra/newview/skins/default/xui/en/widgets/accordion.xml1
16 files changed, 208 insertions, 31 deletions
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 0bd03571da..961969a5c5 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -667,7 +667,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
// (don't let object names with hyperlinks override our objectim Url)
LLStyle::Params link_params(style_params);
link_params.color.control = "HTMLLinkColor";
- link_params.link_href = url;
+ link_params.link_href = LLURI::escape(url);
mEditor->appendText("<nolink>" + chat.mFromName + "</nolink>" + delimiter,
false, link_params);
}
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index a87f7288fa..010033fcd3 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -246,6 +246,7 @@ LLFolderView::LLFolderView(const Params& p)
text_p.font(font);
text_p.visible(false);
text_p.allow_html(true);
+ text_p.wrap(true); // allow multiline text. See EXT-7564, EXT-7047
mStatusTextBox = LLUICtrlFactory::create<LLTextBox> (text_p);
mStatusTextBox->setFollowsLeft();
mStatusTextBox->setFollowsTop();
@@ -953,6 +954,23 @@ void LLFolderView::draw()
}
mStatusTextBox->setValue(mStatusText);
mStatusTextBox->setVisible( TRUE );
+
+ // firstly reshape message textbox with current size. This is necessary to
+ // LLTextBox::getTextPixelHeight works properly
+ const LLRect local_rect = getLocalRect();
+ mStatusTextBox->setShape(local_rect);
+
+ // get preferable text height...
+ S32 pixel_height = mStatusTextBox->getTextPixelHeight();
+ bool height_changed = local_rect.getHeight() != pixel_height;
+ if (height_changed)
+ {
+ // ... if it does not match current height, lets rearrange current view.
+ // This will indirectly call ::arrange and reshape of the status textbox.
+ // We should call this method to also notify parent about required rect.
+ // See EXT-7564, EXT-7047.
+ arrangeFromRoot();
+ }
}
@@ -2310,7 +2328,7 @@ void LLFolderView::updateRenamerPosition()
bool LLFolderView::selectFirstItem()
{
for (folders_t::iterator iter = mFolders.begin();
- iter != mFolders.end();)
+ iter != mFolders.end();++iter)
{
LLFolderViewFolder* folder = (*iter );
if (folder->getVisible())
@@ -2347,7 +2365,7 @@ bool LLFolderView::selectLastItem()
}
}
for (folders_t::reverse_iterator iter = mFolders.rbegin();
- iter != mFolders.rend();)
+ iter != mFolders.rend();++iter)
{
LLFolderViewFolder* folder = (*iter);
if (folder->getVisible())
diff --git a/indra/newview/llinventoryitemslist.cpp b/indra/newview/llinventoryitemslist.cpp
index 3e5f8d9848..55cb2619cf 100644
--- a/indra/newview/llinventoryitemslist.cpp
+++ b/indra/newview/llinventoryitemslist.cpp
@@ -79,7 +79,15 @@ void LLPanelInventoryListItemBase::draw()
void LLPanelInventoryListItemBase::updateItem()
{
setIconImage(mIconImage);
- setTitle(mItem->getName(), mHighlightedText);
+
+ std::string name = mItem->getName();
+
+ if (get_is_item_worn(mItem->getUUID()))
+ {
+ name += LLTrans::getString("worn");
+ }
+
+ setTitle(name, mHighlightedText);
}
void LLPanelInventoryListItemBase::addWidgetToLeftSide(const std::string& name, bool show_widget/* = true*/)
diff --git a/indra/newview/lloutfitobserver.cpp b/indra/newview/lloutfitobserver.cpp
index 5652a98981..efa01bade9 100644
--- a/indra/newview/lloutfitobserver.cpp
+++ b/indra/newview/lloutfitobserver.cpp
@@ -74,6 +74,16 @@ S32 LLOutfitObserver::getCategoryVersion(const LLUUID& cat_id)
return cat->getVersion();
}
+// static
+const std::string& LLOutfitObserver::getCategoryName(const LLUUID& cat_id)
+{
+ LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
+ if (!cat)
+ return LLStringUtil::null;
+
+ return cat->getName();
+}
+
bool LLOutfitObserver::checkCOF()
{
LLUUID cof = LLAppearanceMgr::getInstance()->getCOF();
@@ -105,8 +115,11 @@ void LLOutfitObserver::checkBaseOutfit()
return;
const S32 baseoutfit_ver = getCategoryVersion(baseoutfit_id);
+ const std::string& baseoutfit_name = getCategoryName(baseoutfit_id);
- if (baseoutfit_ver == mBaseOutfitLastVersion)
+ if (baseoutfit_ver == mBaseOutfitLastVersion
+ // renaming category doesn't change version, so it's need to check it
+ && baseoutfit_name == mLastBaseOutfitName)
return;
}
else
@@ -116,10 +129,11 @@ void LLOutfitObserver::checkBaseOutfit()
if (baseoutfit_id.isNull())
return;
-
- mBaseOutfitLastVersion = getCategoryVersion(mBaseOutfitId);
}
+ mBaseOutfitLastVersion = getCategoryVersion(mBaseOutfitId);
+ mLastBaseOutfitName = getCategoryName(baseoutfit_id);
+
LLAppearanceMgr& app_mgr = LLAppearanceMgr::instance();
// dirtiness state should be updated before sending signal
app_mgr.updateIsDirty();
diff --git a/indra/newview/lloutfitobserver.h b/indra/newview/lloutfitobserver.h
index a4b5fbe04a..3a66b5ea9f 100644
--- a/indra/newview/lloutfitobserver.h
+++ b/indra/newview/lloutfitobserver.h
@@ -68,6 +68,8 @@ protected:
/** Get a version of an inventory category specified by its UUID */
static S32 getCategoryVersion(const LLUUID& cat_id);
+ static const std::string& getCategoryName(const LLUUID& cat_id);
+
bool checkCOF();
void checkBaseOutfit();
@@ -78,6 +80,7 @@ protected:
LLUUID mBaseOutfitId;
S32 mBaseOutfitLastVersion;
+ std::string mLastBaseOutfitName;
bool mLastOutfitDirtiness;
diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp
index e20b2e26be..bca292fa4a 100644
--- a/indra/newview/lloutfitslist.cpp
+++ b/indra/newview/lloutfitslist.cpp
@@ -44,6 +44,7 @@
#include "llinventorymodel.h"
#include "lllistcontextmenu.h"
#include "llnotificationsutil.h"
+#include "lloutfitobserver.h"
#include "llsidetray.h"
#include "lltransutil.h"
#include "llviewermenu.h"
@@ -199,6 +200,9 @@ void LLOutfitsList::onOpen(const LLSD& /*info*/)
mCategoriesObserver->addCategory(outfits,
boost::bind(&LLOutfitsList::refreshList, this, outfits));
+ // Start observing changes in Current Outfit to update items worn state.
+ LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&LLOutfitsList::onCOFChanged, this));
+
// Fetch "My Outfits" contents and refresh the list to display
// initially fetched items. If not all items are fetched now
// the observer will refresh the list as soon as the new items
@@ -322,7 +326,7 @@ void LLOutfitsList::refreshList(const LLUUID& category_id)
// 3. Reset currently selected outfit id if it is being removed.
if (outfit_id == mSelectedOutfitUUID)
{
- mSelectedOutfitUUID = LLUUID();
+ setSelectedOutfitUUID(LLUUID());
}
// 4. Remove category UUID to accordion tab mapping.
@@ -385,6 +389,11 @@ void LLOutfitsList::setFilterSubString(const std::string& string)
mFilterSubString = string;
}
+boost::signals2::connection LLOutfitsList::addSelectionChangeCallback(selection_change_callback_t cb)
+{
+ return mSelectionChangeSignal.connect(cb);
+}
+
//////////////////////////////////////////////////////////////////////////
// Private methods
//////////////////////////////////////////////////////////////////////////
@@ -471,7 +480,12 @@ void LLOutfitsList::changeOutfitSelection(LLWearableItemsList* list, const LLUUI
}
mSelectedListsMap.insert(wearables_lists_map_value_t(category_id, list));
- mSelectedOutfitUUID = category_id;
+ setSelectedOutfitUUID(category_id);
+}
+
+void LLOutfitsList::setSelectedOutfitUUID(const LLUUID& category_id)
+{
+ mSelectionChangeSignal(mSelectedOutfitUUID = category_id);
}
void LLOutfitsList::onFilteredWearableItemsListRefresh(LLUICtrl* ctrl)
@@ -645,6 +659,43 @@ void LLOutfitsList::onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y)
LLWearableItemsList::ContextMenu::instance().show(list, selected_uuids, x, y);
}
+void LLOutfitsList::onCOFChanged()
+{
+ LLInventoryModel::changed_items_t changed_linked_items;
+
+ const LLInventoryModel::changed_items_t& changed_items = gInventory.getChangedIDs();
+ for (LLInventoryModel::changed_items_t::const_iterator iter = changed_items.begin();
+ iter != changed_items.end();
+ ++iter)
+ {
+ LLViewerInventoryItem* item = gInventory.getItem(*iter);
+ if (item)
+ {
+ // From gInventory we get the UUIDs of new links added to COF
+ // or removed from COF. These links UUIDs are not the same UUIDs
+ // that we have in each wearable items list. So we collect base items
+ // UUIDs to find all items or links that point to same base items in wearable
+ // items lists and update their worn state there.
+ changed_linked_items.insert(item->getLinkedUUID());
+ }
+ }
+
+ for (outfits_map_t::iterator iter = mOutfitsMap.begin();
+ iter != mOutfitsMap.end();
+ ++iter)
+ {
+ LLAccordionCtrlTab* tab = iter->second;
+ if (!tab) continue;
+
+ LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(tab->getAccordionView());
+ if (!list) continue;
+
+ // Every list updates the labels of changed items or
+ // the links that point to these items.
+ list->updateChangedItems(changed_linked_items);
+ }
+}
+
bool is_tab_header_clicked(LLAccordionCtrlTab* tab, S32 y)
{
if(!tab || !tab->getHeaderVisible()) return false;
diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h
index bb516446d2..478eaa50b3 100644
--- a/indra/newview/lloutfitslist.h
+++ b/indra/newview/lloutfitslist.h
@@ -71,6 +71,9 @@ public:
class LLOutfitsList : public LLPanel
{
public:
+ typedef boost::function<void (const LLUUID&)> selection_change_callback_t;
+ typedef boost::signals2::signal<void (const LLUUID&)> selection_change_signal_t;
+
LLOutfitsList();
virtual ~LLOutfitsList();
@@ -86,6 +89,8 @@ public:
const LLUUID& getSelectedOutfitUUID() const { return mSelectedOutfitUUID; }
+ boost::signals2::connection addSelectionChangeCallback(selection_change_callback_t cb);
+
private:
/**
* Reads xml with accordion tab and Flat list from xml file.
@@ -110,6 +115,11 @@ private:
void changeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id);
/**
+ * Saves newly selected outfit ID.
+ */
+ void setSelectedOutfitUUID(const LLUUID& category_id);
+
+ /**
* Called upon list refresh event to update tab visibility depending on
* the results of applying filter to the title and list items of the tab.
*/
@@ -123,6 +133,7 @@ private:
void onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id);
void onAccordionTabDoubleClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id);
void onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y);
+ void onCOFChanged();
void onSelectionChange(LLUICtrl* ctrl);
@@ -138,6 +149,7 @@ private:
wearables_lists_map_t mSelectedListsMap;
LLUUID mSelectedOutfitUUID;
+ selection_change_signal_t mSelectionChangeSignal;
std::string mFilterSubString;
diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index 3d0684afca..32b209dd0d 100644
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -707,6 +707,7 @@ void LLPanelOutfitEdit::updateVerbs()
mStatus->setText(outfit_is_dirty ? getString("unsaved_changes") : getString("now_editing"));
+ updateCurrentOutfitName();
}
bool LLPanelOutfitEdit::switchPanels(LLPanel* switch_from_panel, LLPanel* switch_to_panel)
diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp
index 8b451c156c..1286642897 100644
--- a/indra/newview/llpaneloutfitsinventory.cpp
+++ b/indra/newview/llpaneloutfitsinventory.cpp
@@ -169,6 +169,11 @@ private:
bool onEnable(LLSD::String param)
{
const LLUUID& selected_outfit_id = getSelectedOutfitID();
+ if (selected_outfit_id.isNull()) // no selection or invalid outfit selected
+ {
+ return false;
+ }
+
bool is_worn = LLAppearanceMgr::instance().getBaseOutfitUUID() == selected_outfit_id;
if ("wear" == param)
@@ -555,11 +560,25 @@ void LLPanelOutfitsInventory::onTrashButtonClick()
void LLPanelOutfitsInventory::onClipboardAction(const LLSD& userdata)
{
std::string command_name = userdata.asString();
- // TODO: add handling "My Outfits" tab.
if (isCOFPanelActive())
{
getActivePanel()->getRootFolder()->doToSelected(getActivePanel()->getModel(),command_name);
}
+ else // "My Outfits" tab active
+ {
+ if (command_name == "delete")
+ {
+ const LLUUID& selected_outfit_id = mMyOutfitsPanel->getSelectedOutfitUUID();
+ if (selected_outfit_id.notNull())
+ {
+ remove_category(&gInventory, selected_outfit_id);
+ }
+ }
+ else
+ {
+ llwarns << "Unrecognized action" << llendl;
+ }
+ }
updateListCommands();
updateVerbs();
}
@@ -614,7 +633,6 @@ BOOL LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata)
{
BOOL can_delete = FALSE;
- // TODO: add handling "My Outfits" tab.
if (isCOFPanelActive())
{
LLFolderView* root = getActivePanel()->getRootFolder();
@@ -630,10 +648,15 @@ BOOL LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata)
LLFolderViewItem *item = root->getItemByID(item_id);
can_delete &= item->getListener()->isItemRemovable();
}
- return can_delete;
}
}
- return FALSE;
+ else // "My Outfits" tab active
+ {
+ const LLUUID& selected_outfit = mMyOutfitsPanel->getSelectedOutfitUUID();
+ can_delete = LLAppearanceMgr::instance().getCanRemoveOutfit(selected_outfit);
+ }
+
+ return can_delete;
}
if (command_name == "remove_link")
{
@@ -730,6 +753,7 @@ void LLPanelOutfitsInventory::initTabPanels()
mCurrentOutfitPanel->setSelectCallback(boost::bind(&LLPanelOutfitsInventory::onTabSelectionChange, this, mCurrentOutfitPanel, _1, _2));
mMyOutfitsPanel = getChild<LLOutfitsList>(OUTFITS_TAB_NAME);
+ mMyOutfitsPanel->addSelectionChangeCallback(boost::bind(&LLPanelOutfitsInventory::updateVerbs, this));
mAppearanceTabs = getChild<LLTabContainer>("appearance_tabs");
mAppearanceTabs->setCommitCallback(boost::bind(&LLPanelOutfitsInventory::onTabChange, this));
diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp
index d56a331000..54695e9d40 100644
--- a/indra/newview/llwearableitemslist.cpp
+++ b/indra/newview/llwearableitemslist.cpp
@@ -38,7 +38,6 @@
#include "llagentwearables.h"
#include "llappearancemgr.h"
#include "llinventoryfunctions.h"
-#include "llinventorymodel.h"
#include "llmenugl.h" // for LLContextMenu
#include "lltransutil.h"
#include "llviewerattachmenu.h"
@@ -305,7 +304,7 @@ BOOL LLPanelDummyClothingListItem::postBuild()
setIconCtrl(icon);
setTitleCtrl(getChild<LLTextBox>("item_name"));
- addWidgetToRightSide("btn_add");
+ addWidgetToRightSide("btn_add_panel");
setIconImage(LLInventoryIcon::getIcon(LLAssetType::AT_CLOTHING, LLInventoryType::IT_NONE, mWearableType, FALSE));
updateItem();
@@ -508,6 +507,37 @@ void LLWearableItemsList::updateList(const LLUUID& category_id)
refreshList(item_array);
}
+void LLWearableItemsList::updateChangedItems(const LLInventoryModel::changed_items_t& changed_items_uuids)
+{
+ typedef std::vector<LLPanel*> item_panel_list_t;
+
+ item_panel_list_t items;
+ getItems(items);
+
+ for (item_panel_list_t::iterator items_iter = items.begin();
+ items_iter != items.end();
+ ++items_iter)
+ {
+ LLPanelInventoryListItemBase* item = dynamic_cast<LLPanelInventoryListItemBase*>(*items_iter);
+ if (!item) continue;
+
+ LLViewerInventoryItem* inv_item = item->getItem();
+ if (!inv_item) continue;
+
+ LLUUID linked_uuid = inv_item->getLinkedUUID();
+
+ for (LLInventoryModel::changed_items_t::const_iterator iter = changed_items_uuids.begin();
+ iter != changed_items_uuids.end();
+ ++iter)
+ {
+ if (linked_uuid == *iter)
+ {
+ item->setNeedsRefresh(true);
+ }
+ }
+ }
+}
+
void LLWearableItemsList::onRightClick(S32 x, S32 y)
{
uuid_vec_t selected_uuids;
diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h
index f03336186c..dd0ceb99e4 100644
--- a/indra/newview/llwearableitemslist.h
+++ b/indra/newview/llwearableitemslist.h
@@ -355,6 +355,12 @@ public:
void updateList(const LLUUID& category_id);
+ /**
+ * Update items that match UUIDs from changed_items_uuids
+ * or links that point at such items.
+ */
+ void updateChangedItems(const LLInventoryModel::changed_items_t& changed_items_uuids);
+
protected:
friend class LLUICtrlFactory;
LLWearableItemsList(const LLWearableItemsList::Params& p);
diff --git a/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml
index fa5ca60a19..430a7b6444 100644
--- a/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml
@@ -38,13 +38,6 @@
layout="topleft"
name="wearable_attach_to_hud" />
<menu_item_call
- label="Object Profile"
- layout="topleft"
- name="object_profile">
- <on_click
- function="Attachment.Profile" />
- </menu_item_call>
- <menu_item_call
label="Take Off"
layout="topleft"
name="take_off">
@@ -59,6 +52,13 @@
function="Wearable.Edit" />
</menu_item_call>
<menu_item_call
+ label="Object Profile"
+ layout="topleft"
+ name="object_profile">
+ <on_click
+ function="Attachment.Profile" />
+ </menu_item_call>
+ <menu_item_call
label="Show Original"
layout="topleft"
name="show_original">
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 76a41a3b13..aca3b750c8 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -2066,6 +2066,7 @@ Would you be my friend?
name="Cancel"
text="Cancel"/>
</form>
+ <unique/>
</notification>
<notification
diff --git a/indra/newview/skins/default/xui/en/panel_cof_wearables.xml b/indra/newview/skins/default/xui/en/panel_cof_wearables.xml
index d36c2a4e6f..f016c27b0a 100644
--- a/indra/newview/skins/default/xui/en/panel_cof_wearables.xml
+++ b/indra/newview/skins/default/xui/en/panel_cof_wearables.xml
@@ -28,7 +28,7 @@
allow_select="true"
follows="all"
height="10"
- item_pad="2"
+ item_pad="3"
layout="topleft"
left="0"
multi_select="true"
@@ -44,7 +44,7 @@
allow_select="true"
follows="all"
height="10"
- item_pad="2"
+ item_pad="3"
layout="topleft"
left="0"
multi_select="true"
@@ -60,7 +60,7 @@
allow_select="true"
follows="all"
height="10"
- item_pad="2"
+ item_pad="3"
layout="topleft"
left="0"
multi_select="true"
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
index 20652df918..b1f4cbb079 100644
--- 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
@@ -49,16 +49,26 @@
top="4"
value="..."
width="359" />
- <button
- name="btn_add"
+ <panel
+ name="btn_add_panel"
layout="topleft"
follows="top|right"
- image_overlay="AddItem_Off"
top="0"
left="0"
height="23"
- width="23"
- tab_stop="false" />
+ width="26"
+ tab_stop="false">
+ <button
+ name="btn_add"
+ layout="topleft"
+ follows="top|right"
+ image_overlay="AddItem_Off"
+ top="0"
+ left="0"
+ height="23"
+ width="23"
+ tab_stop="false" />
+ </panel>
<icon
follows="left|right|top"
height="3"
diff --git a/indra/newview/skins/default/xui/en/widgets/accordion.xml b/indra/newview/skins/default/xui/en/widgets/accordion.xml
index b817ba56ca..05d7447a6f 100644
--- a/indra/newview/skins/default/xui/en/widgets/accordion.xml
+++ b/indra/newview/skins/default/xui/en/widgets/accordion.xml
@@ -8,7 +8,6 @@
height="100"
h_pad="10"
name="no_visible_items_msg"
- value="There are no visible content here."
v_pad="15"
width="200"
wrap="true "/>