summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llui/llaccordionctrl.cpp24
-rw-r--r--indra/llui/llaccordionctrl.h1
-rw-r--r--indra/llui/llaccordionctrltab.cpp29
-rw-r--r--indra/llui/llaccordionctrltab.h7
-rw-r--r--indra/llui/llbutton.cpp30
-rw-r--r--indra/llui/llbutton.h7
-rw-r--r--indra/llui/lltabcontainer.cpp8
-rw-r--r--indra/llui/lltabcontainer.h5
-rw-r--r--indra/llui/lltextbase.cpp282
-rw-r--r--indra/llui/lltextbase.h34
-rw-r--r--indra/llui/lltexteditor.cpp49
-rw-r--r--indra/llui/lltexteditor.h1
-rw-r--r--indra/llui/llurlentry.h2
-rw-r--r--indra/llui/llurlmatch.cpp3
-rw-r--r--indra/llui/llurlmatch.h7
-rw-r--r--indra/llui/llurlregistry.cpp6
-rw-r--r--indra/llui/tests/llurlmatch_test.cpp30
-rw-r--r--indra/newview/CMakeLists.txt2
-rw-r--r--indra/newview/app_settings/settings.xml33
-rw-r--r--indra/newview/llagentwearables.cpp26
-rw-r--r--indra/newview/llagentwearables.h1
-rw-r--r--indra/newview/llappearancemgr.cpp71
-rw-r--r--indra/newview/llappearancemgr.h6
-rw-r--r--indra/newview/llavataractions.cpp159
-rw-r--r--indra/newview/llbottomtray.cpp10
-rw-r--r--indra/newview/llbottomtray.h2
-rw-r--r--indra/newview/llcofwearables.cpp71
-rw-r--r--indra/newview/llcofwearables.h47
-rw-r--r--indra/newview/llfilteredwearablelist.cpp9
-rw-r--r--indra/newview/llfloateravatarpicker.cpp2
-rw-r--r--indra/newview/llfloaterland.cpp2
-rw-r--r--indra/newview/llfloatermap.cpp13
-rw-r--r--indra/newview/llfloatermap.h2
-rw-r--r--indra/newview/llgiveinventory.cpp44
-rw-r--r--indra/newview/llgiveinventory.h7
-rw-r--r--indra/newview/llinventorybridge.cpp190
-rw-r--r--indra/newview/llinventorybridge.h1
-rw-r--r--indra/newview/llinventoryfunctions.cpp181
-rw-r--r--indra/newview/llinventoryfunctions.h31
-rw-r--r--indra/newview/llinventoryitemslist.cpp4
-rw-r--r--indra/newview/llinventoryitemslist.h6
-rw-r--r--indra/newview/llinventorymodelbackgroundfetch.cpp2
-rw-r--r--indra/newview/llinventoryobserver.cpp2
-rw-r--r--indra/newview/llinventorypanel.cpp44
-rw-r--r--indra/newview/llnavigationbar.cpp1
-rw-r--r--indra/newview/llnearbychatbar.cpp7
-rw-r--r--indra/newview/llnearbychatbar.h1
-rw-r--r--indra/newview/lloutfitslist.cpp243
-rw-r--r--indra/newview/lloutfitslist.h27
-rw-r--r--indra/newview/llpanellandmarks.cpp18
-rw-r--r--indra/newview/llpanellandmarks.h1
-rw-r--r--indra/newview/llpaneloutfitedit.cpp118
-rw-r--r--indra/newview/llpaneloutfitedit.h2
-rw-r--r--indra/newview/llpaneloutfitsinventory.cpp141
-rw-r--r--indra/newview/llpaneloutfitsinventory.h6
-rw-r--r--indra/newview/llparticipantlist.cpp3
-rw-r--r--indra/newview/llsidetray.cpp55
-rw-r--r--indra/newview/llsidetray.h10
-rw-r--r--indra/newview/llteleporthistory.cpp22
-rw-r--r--indra/newview/llteleporthistory.h4
-rw-r--r--indra/newview/lltooldraganddrop.cpp50
-rw-r--r--indra/newview/lltooldraganddrop.h3
-rw-r--r--indra/newview/llviewerattachmenu.cpp139
-rw-r--r--indra/newview/llviewerattachmenu.h43
-rw-r--r--indra/newview/llviewerinventory.cpp24
-rw-r--r--indra/newview/llwearableitemslist.cpp168
-rw-r--r--indra/newview/llwearableitemslist.h37
-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/icons/Inv_LostClosed.pngbin0 -> 3033 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Inv_LostOpen.pngbin0 -> 3223 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Inv_SysClosed.pngbin0 -> 3153 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Inv_SysOpen.pngbin0 -> 3251 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Inv_TrashClosed.pngbin0 -> 2978 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Inv_TrashOpen.pngbin0 -> 2970 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/back_arrow_off.pngbin0 -> 3775 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/back_arrow_over.pngbin0 -> 3792 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/back_arrow_press.pngbin0 -> 3844 bytes
-rw-r--r--indra/newview/skins/default/textures/textures.xml15
-rw-r--r--indra/newview/skins/default/textures/windows/Wearables_Divider.pngbin0 -> 97 bytes
-rw-r--r--indra/newview/skins/default/xui/en/floater_about_land.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_im_container.xml9
-rw-r--r--indra/newview/skins/default/xui/en/floater_map.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_search.xml1
-rw-r--r--indra/newview/skins/default/xui/en/menu_bottomtray.xml11
-rw-r--r--indra/newview/skins/default/xui/en/menu_cof_attachment.xml8
-rw-r--r--indra/newview/skins/default/xui/en/menu_cof_body_part.xml11
-rw-r--r--indra/newview/skins/default/xui/en/menu_cof_clothing.xml14
-rw-r--r--indra/newview/skins/default/xui/en/menu_cof_gear.xml17
-rw-r--r--indra/newview/skins/default/xui/en/menu_outfit_gear.xml162
-rw-r--r--indra/newview/skins/default/xui/en/menu_outfit_tab.xml27
-rw-r--r--indra/newview/skins/default/xui/en/menu_wearable_list_item.xml35
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml52
-rw-r--r--indra/newview/skins/default/xui/en/outfit_accordion_tab.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml12
-rw-r--r--indra/newview/skins/default/xui/en/panel_body_parts_list_item.xml46
-rw-r--r--indra/newview/skins/default/xui/en/panel_bottomtray.xml32
-rw-r--r--indra/newview/skins/default/xui/en/panel_classified_info.xml10
-rw-r--r--indra/newview/skins/default/xui/en/panel_clothing_list_item.xml57
-rw-r--r--indra/newview/skins/default/xui/en/panel_cof_wearables.xml67
-rw-r--r--indra/newview/skins/default/xui/en/panel_deletable_wearable_list_item.xml27
-rw-r--r--indra/newview/skins/default/xui/en/panel_dummy_clothing_list_item.xml26
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_alpha.xml89
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_classified.xml10
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_eyes.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_gloves.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_hair.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_jacket.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_pants.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_pick.xml10
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_shirt.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_shoes.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_skin.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_skirt.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_socks.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_underpants.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_undershirt.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_wearable.xml10
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml10
-rw-r--r--indra/newview/skins/default/xui/en/panel_landmark_info.xml10
-rw-r--r--indra/newview/skins/default/xui/en/panel_outfit_edit.xml497
-rw-r--r--indra/newview/skins/default/xui/en/panel_pick_info.xml10
-rw-r--r--indra/newview/skins/default/xui/en/panel_place_profile.xml11
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_view.xml10
-rw-r--r--indra/newview/skins/default/xui/en/sidepanel_item_info.xml10
-rw-r--r--indra/newview/skins/default/xui/en/sidepanel_task_info.xml10
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml14
-rw-r--r--indra/newview/skins/default/xui/en/widgets/button.xml1
-rw-r--r--indra/newview/skins/default/xui/en/widgets/tab_container.xml6
-rw-r--r--indra/newview/skins/default/xui/pl/floater_about_land.xml4
132 files changed, 2766 insertions, 1219 deletions
diff --git a/indra/llui/llaccordionctrl.cpp b/indra/llui/llaccordionctrl.cpp
index 5d1d57cbb2..8e0245c451 100644
--- a/indra/llui/llaccordionctrl.cpp
+++ b/indra/llui/llaccordionctrl.cpp
@@ -65,6 +65,7 @@ LLAccordionCtrl::LLAccordionCtrl(const Params& params):LLPanel(params)
, mFitParent(params.fit_parent)
, mAutoScrolling( false )
, mAutoScrollRate( 0.f )
+ , mSelectedTab( NULL )
{
mSingleExpansion = params.single_expansion;
if(mFitParent && !mSingleExpansion)
@@ -76,6 +77,7 @@ LLAccordionCtrl::LLAccordionCtrl(const Params& params):LLPanel(params)
LLAccordionCtrl::LLAccordionCtrl() : LLPanel()
, mAutoScrolling( false )
, mAutoScrollRate( 0.f )
+ , mSelectedTab( NULL )
{
mSingleExpansion = false;
mFitParent = false;
@@ -689,6 +691,28 @@ S32 LLAccordionCtrl::notifyParent(const LLSD& info)
}
return 0;
}
+ else if(str_action == "select_current")
+ {
+ for(size_t i=0;i<mAccordionTabs.size();++i)
+ {
+ // Set selection to the currently focused tab.
+ if(mAccordionTabs[i]->hasFocus())
+ {
+ if (mAccordionTabs[i] != mSelectedTab)
+ {
+ if (mSelectedTab)
+ {
+ mSelectedTab->setSelected(false);
+ }
+ mSelectedTab = mAccordionTabs[i];
+ mSelectedTab->setSelected(true);
+ }
+
+ return 1;
+ }
+ }
+ return 0;
+ }
}
else if (info.has("scrollToShowRect"))
{
diff --git a/indra/llui/llaccordionctrl.h b/indra/llui/llaccordionctrl.h
index ab7d6548ca..a029201c90 100644
--- a/indra/llui/llaccordionctrl.h
+++ b/indra/llui/llaccordionctrl.h
@@ -130,6 +130,7 @@ private:
bool mFitParent;
bool mAutoScrolling;
F32 mAutoScrollRate;
+ LLAccordionCtrlTab* mSelectedTab;
};
diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp
index b09c108ec3..83e67980a3 100644
--- a/indra/llui/llaccordionctrltab.cpp
+++ b/indra/llui/llaccordionctrltab.cpp
@@ -76,6 +76,8 @@ public:
std::string getTitle();
void setTitle(const std::string& title, const std::string& hl);
+ void setSelected(bool is_selected) { mIsSelected = is_selected; }
+
virtual void onMouseEnter(S32 x, S32 y, MASK mask);
virtual void onMouseLeave(S32 x, S32 y, MASK mask);
virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
@@ -103,6 +105,7 @@ private:
LLUIColor mHeaderBGColor;
bool mNeedsHighlight;
+ bool mIsSelected;
LLFrameTimer mAutoOpenTimer;
};
@@ -115,7 +118,8 @@ LLAccordionCtrlTab::LLAccordionCtrlTabHeader::LLAccordionCtrlTabHeader(
const LLAccordionCtrlTabHeader::Params& p)
: LLUICtrl(p)
, mHeaderBGColor(p.header_bg_color())
-,mNeedsHighlight(false),
+, mNeedsHighlight(false)
+, mIsSelected(false),
mImageCollapsed(p.header_collapse_img),
mImageCollapsedPressed(p.header_collapse_img_pressed),
mImageExpanded(p.header_expand_img),
@@ -187,7 +191,7 @@ void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::draw()
// Only show green "focus" background image if the accordion is open,
// because the user's mental model of focus is that it goes away after
// the accordion is closed.
- if (getParent()->hasFocus()
+ if (getParent()->hasFocus() || mIsSelected
/*&& !(collapsible && !expanded)*/ // WHY??
)
{
@@ -301,6 +305,7 @@ LLAccordionCtrlTab::Params::Params()
,header_image_focused("header_image_focused")
,header_text_color("header_text_color")
,fit_panel("fit_panel",true)
+ ,selection_enabled("selection_enabled", false)
{
mouse_opaque(false);
}
@@ -331,6 +336,11 @@ LLAccordionCtrlTab::LLAccordionCtrlTab(const LLAccordionCtrlTab::Params&p)
mHeader = LLUICtrlFactory::create<LLAccordionCtrlTabHeader>(headerParams);
addChild(mHeader, 1);
+ if (p.selection_enabled)
+ {
+ LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLAccordionCtrlTab::selectOnFocusReceived, this));
+ }
+
reshape(100, 200,FALSE);
}
@@ -498,6 +508,15 @@ boost::signals2::connection LLAccordionCtrlTab::setFocusLostCallback(const focus
return boost::signals2::connection();
}
+void LLAccordionCtrlTab::setSelected(bool is_selected)
+{
+ LLAccordionCtrlTabHeader* header = findChild<LLAccordionCtrlTabHeader>(DD_HEADER_NAME);
+ if (header)
+ {
+ header->setSelected(is_selected);
+ }
+}
+
LLView* LLAccordionCtrlTab::findContainerView()
{
for(child_list_const_iter_t it = getChildList()->begin();
@@ -513,6 +532,11 @@ LLView* LLAccordionCtrlTab::findContainerView()
return NULL;
}
+void LLAccordionCtrlTab::selectOnFocusReceived()
+{
+ if (getParent()) // A parent may not be set if tabs are added dynamically.
+ getParent()->notifyParent(LLSD().with("action", "select_current"));
+}
S32 LLAccordionCtrlTab::getHeaderHeight()
{
@@ -713,6 +737,7 @@ void LLAccordionCtrlTab::showAndFocusHeader()
{
LLAccordionCtrlTabHeader* header = getChild<LLAccordionCtrlTabHeader>(DD_HEADER_NAME);
header->setFocus(true);
+ header->setSelected(true);
LLRect screen_rc;
LLRect selected_rc = header->getRect();
diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h
index f5b7fd0af6..83a9024a74 100644
--- a/indra/llui/llaccordionctrltab.h
+++ b/indra/llui/llaccordionctrltab.h
@@ -88,6 +88,8 @@ public:
Optional<bool> fit_panel;
+ Optional<bool> selection_enabled;
+
Optional<S32> padding_left;
Optional<S32> padding_right;
Optional<S32> padding_top;
@@ -121,6 +123,8 @@ public:
boost::signals2::connection setFocusReceivedCallback(const focus_signal_t::slot_type& cb);
boost::signals2::connection setFocusLostCallback(const focus_signal_t::slot_type& cb);
+ void setSelected(bool is_selected);
+
bool getCollapsible() {return mCollapsible;};
void setCollapsible(bool collapsible) {mCollapsible = collapsible;};
@@ -199,6 +203,9 @@ protected:
void drawChild(const LLRect& root_rect,LLView* child);
LLView* findContainerView ();
+
+ void selectOnFocusReceived();
+
private:
class LLAccordionCtrlTabHeader;
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 0255061b12..34f3049f2e 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -128,6 +128,7 @@ LLButton::LLButton(const LLButton::Params& p)
mImageSelected(p.image_selected),
mImageDisabled(p.image_disabled),
mImageDisabledSelected(p.image_disabled_selected),
+ mImageFlash(p.image_flash),
mImagePressed(p.image_pressed),
mImagePressedSelected(p.image_pressed_selected),
mImageHoverSelected(p.image_hover_selected),
@@ -635,14 +636,24 @@ void LLButton::draw()
if (mFlashing)
{
- LLColor4 flash_color = mFlashBgColor.get();
- use_glow_effect = TRUE;
- glow_type = LLRender::BT_ALPHA; // blend the glow
-
- if (mNeedsHighlight) // highlighted AND flashing
- glow_color = (glow_color*0.5f + flash_color*0.5f) % 2.0f; // average between flash and highlight colour, with sum of the opacity
+ // if button should flash and we have icon for flashing, use it as image for button
+ if(flash && mImageFlash)
+ {
+ // setting flash to false to avoid its further influence on glow
+ flash = false;
+ imagep = mImageFlash;
+ }
+ // else use usual flashing via flash_color
else
- glow_color = flash_color;
+ {
+ LLColor4 flash_color = mFlashBgColor.get();
+ use_glow_effect = TRUE;
+ glow_type = LLRender::BT_ALPHA; // blend the glow
+ if (mNeedsHighlight) // highlighted AND flashing
+ glow_color = (glow_color*0.5f + flash_color*0.5f) % 2.0f; // average between flash and highlight colour, with sum of the opacity
+ else
+ glow_color = flash_color;
+ }
}
if (mNeedsHighlight && !imagep)
@@ -1018,6 +1029,11 @@ void LLButton::setImageHoverUnselected(LLPointer<LLUIImage> image)
mImageHoverUnselected = image;
}
+void LLButton::setImageFlash(LLPointer<LLUIImage> image)
+{
+ mImageFlash = image;
+}
+
void LLButton::setImageOverlay(const std::string& image_name, LLFontGL::HAlign alignment, const LLColor4& color)
{
if (image_name.empty())
diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h
index a4d81ed6c3..9bd566d3c9 100644
--- a/indra/llui/llbutton.h
+++ b/indra/llui/llbutton.h
@@ -84,6 +84,7 @@ public:
image_hover_unselected,
image_disabled_selected,
image_disabled,
+ image_flash,
image_pressed,
image_pressed_selected,
image_overlay;
@@ -246,6 +247,7 @@ public:
void setImageHoverUnselected(LLPointer<LLUIImage> image);
void setImageDisabled(LLPointer<LLUIImage> image);
void setImageDisabledSelected(LLPointer<LLUIImage> image);
+ void setImageFlash(LLPointer<LLUIImage> image);
void setImagePressed(LLPointer<LLUIImage> image);
void setCommitOnReturn(BOOL commit) { mCommitOnReturn = commit; }
@@ -310,6 +312,11 @@ private:
LLPointer<LLUIImage> mImagePressed;
LLPointer<LLUIImage> mImagePressedSelected;
+ /* There are two ways an image can flash- by making changes in color according to flash_color attribute
+ or by changing icon from current to the one specified in image_flash. Second way is used only if
+ flash icon name is set in attributes(by default it isn't). First way is used otherwise. */
+ LLPointer<LLUIImage> mImageFlash;
+
LLUIColor mHighlightColor;
LLUIColor mFlashBgColor;
diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index 30fc7babae..986cfe75a1 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -197,10 +197,13 @@ static LLDefaultChildRegistry::Register<LLTabContainer> r2("tab_container");
LLTabContainer::TabParams::TabParams()
: tab_top_image_unselected("tab_top_image_unselected"),
tab_top_image_selected("tab_top_image_selected"),
+ tab_top_image_flash("tab_top_image_flash"),
tab_bottom_image_unselected("tab_bottom_image_unselected"),
tab_bottom_image_selected("tab_bottom_image_selected"),
+ tab_bottom_image_flash("tab_bottom_image_flash"),
tab_left_image_unselected("tab_left_image_unselected"),
- tab_left_image_selected("tab_left_image_selected")
+ tab_left_image_selected("tab_left_image_selected"),
+ tab_left_image_flash("tab_left_image_flash")
{}
LLTabContainer::Params::Params()
@@ -879,16 +882,19 @@ void LLTabContainer::update_images(LLTabTuple* tuple, TabParams params, LLTabCon
{
tuple->mButton->setImageUnselected(static_cast<LLUIImage*>(params.tab_top_image_unselected));
tuple->mButton->setImageSelected(static_cast<LLUIImage*>(params.tab_top_image_selected));
+ tuple->mButton->setImageFlash(static_cast<LLUIImage*>(params.tab_top_image_flash));
}
else if (pos == LLTabContainer::BOTTOM)
{
tuple->mButton->setImageUnselected(static_cast<LLUIImage*>(params.tab_bottom_image_unselected));
tuple->mButton->setImageSelected(static_cast<LLUIImage*>(params.tab_bottom_image_selected));
+ tuple->mButton->setImageFlash(static_cast<LLUIImage*>(params.tab_bottom_image_flash));
}
else if (pos == LLTabContainer::LEFT)
{
tuple->mButton->setImageUnselected(static_cast<LLUIImage*>(params.tab_left_image_unselected));
tuple->mButton->setImageSelected(static_cast<LLUIImage*>(params.tab_left_image_selected));
+ tuple->mButton->setImageFlash(static_cast<LLUIImage*>(params.tab_left_image_flash));
}
}
}
diff --git a/indra/llui/lltabcontainer.h b/indra/llui/lltabcontainer.h
index 50ec2679f6..a2dc15aaf9 100644
--- a/indra/llui/lltabcontainer.h
+++ b/indra/llui/lltabcontainer.h
@@ -67,10 +67,13 @@ public:
{
Optional<LLUIImage*> tab_top_image_unselected,
tab_top_image_selected,
+ tab_top_image_flash,
tab_bottom_image_unselected,
tab_bottom_image_selected,
+ tab_bottom_image_flash,
tab_left_image_unselected,
- tab_left_image_selected;
+ tab_left_image_selected,
+ tab_left_image_flash;
TabParams();
};
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 78a6ab1eaa..ab9cd11769 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -1562,7 +1562,7 @@ std::string LLTextBase::getText() const
return getViewModel()->getValue().asString();
}
-void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params)
+void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Params& input_params)
{
LLStyle::Params style_params(input_params);
style_params.fillFrom(getDefaultStyleParams());
@@ -1598,8 +1598,7 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c
part = (S32)LLTextParser::MIDDLE;
}
std::string subtext=text.substr(0,start);
- appendAndHighlightText(subtext, prepend_newline, part, style_params);
- prepend_newline = false;
+ appendAndHighlightTextImpl(subtext, part, style_params);
}
// output an optional icon before the Url
@@ -1613,19 +1612,18 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c
// Text will be replaced during rendering with the icon,
// but string cannot be empty or the segment won't be
// added (or drawn).
- appendAndHighlightText(" ", prepend_newline, part, icon);
- prepend_newline = false;
+ appendImageSegment(part, icon);
}
}
// output the styled Url (unless we've been asked to suppress hyperlinking)
if (match.isLinkDisabled())
{
- appendAndHighlightText(match.getLabel(), prepend_newline, part, style_params);
+ appendAndHighlightTextImpl(match.getLabel(), part, style_params);
}
else
{
- appendAndHighlightText(match.getLabel(), prepend_newline, part, link_params);
+ appendAndHighlightTextImpl(match.getLabel(), part, link_params);
// set the tooltip for the Url label
if (! match.getTooltip().empty())
@@ -1638,8 +1636,6 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c
}
}
}
- prepend_newline = false;
-
// move on to the rest of the text after the Url
if (end < (S32)text.length())
{
@@ -1652,13 +1648,41 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c
break;
}
}
- if (part != (S32)LLTextParser::WHOLE) part=(S32)LLTextParser::END;
- if (end < (S32)text.length()) appendAndHighlightText(text, prepend_newline, part, style_params);
+ if (part != (S32)LLTextParser::WHOLE)
+ part=(S32)LLTextParser::END;
+ if (end < (S32)text.length())
+ appendAndHighlightTextImpl(text, part, style_params);
}
else
{
- appendAndHighlightText(new_text, prepend_newline, part, style_params);
+ appendAndHighlightTextImpl(new_text, part, style_params);
+ }
+}
+
+void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params)
+{
+ if (new_text.empty())
+ return;
+
+ if(prepend_newline)
+ appendLineBreakSegment(input_params);
+ std::string::size_type start = 0;
+ std::string::size_type pos = new_text.find("\n",start);
+
+ while(pos!=-1)
+ {
+ if(pos!=start)
+ {
+ std::string str = std::string(new_text,start,pos-start);
+ appendTextImpl(str,input_params);
+ }
+ appendLineBreakSegment(input_params);
+ start = pos+1;
+ pos = new_text.find("\n",start);
}
+
+ std::string str = std::string(new_text,start,new_text.length()-start);
+ appendTextImpl(str,input_params);
}
void LLTextBase::needsReflow(S32 index)
@@ -1667,10 +1691,28 @@ void LLTextBase::needsReflow(S32 index)
mReflowIndex = llmin(mReflowIndex, index);
}
-void LLTextBase::appendAndHighlightText(const std::string &new_text, bool prepend_newline, S32 highlight_part, const LLStyle::Params& style_params)
+void LLTextBase::appendLineBreakSegment(const LLStyle::Params& style_params)
{
- if (new_text.empty()) return;
+ segment_vec_t segments;
+ LLStyleConstSP sp(new LLStyle(style_params));
+ segments.push_back(new LLLineBreakTextSegment(sp, getLength()));
+ insertStringNoUndo(getLength(), utf8str_to_wstring("\n"), &segments);
+}
+
+void LLTextBase::appendImageSegment(S32 highlight_part, const LLStyle::Params& style_params)
+{
+ segment_vec_t segments;
+ LLStyleConstSP sp(new LLStyle(style_params));
+ segments.push_back(new LLImageTextSegment(sp, getLength(),*this));
+
+ insertStringNoUndo(getLength(), utf8str_to_wstring(" "), &segments);
+}
+
+
+
+void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params)
+{
// Save old state
S32 selection_start = mSelectionStart;
S32 selection_end = mSelectionEnd;
@@ -1698,14 +1740,8 @@ void LLTextBase::appendAndHighlightText(const std::string &new_text, bool prepen
highlight_params.color = lcolor;
LLWString wide_text;
- if (prepend_newline && (i == 0 || pieces.size() <= 1 ))
- {
- wide_text = utf8str_to_wstring(std::string("\n") + pieces[i]["text"].asString());
- }
- else
- {
- wide_text = utf8str_to_wstring(pieces[i]["text"].asString());
- }
+ wide_text = utf8str_to_wstring(pieces[i]["text"].asString());
+
S32 cur_length = getLength();
LLStyleConstSP sp(new LLStyle(highlight_params));
LLTextSegmentPtr segmentp = new LLNormalTextSegment(sp, cur_length, cur_length + wide_text.size(), *this);
@@ -1717,17 +1753,7 @@ void LLTextBase::appendAndHighlightText(const std::string &new_text, bool prepen
else
{
LLWString wide_text;
-
- // Add carriage return if not first line
- if (getLength() != 0
- && prepend_newline)
- {
- wide_text = utf8str_to_wstring(std::string("\n") + new_text);
- }
- else
- {
- wide_text = utf8str_to_wstring(new_text);
- }
+ wide_text = utf8str_to_wstring(new_text);
segment_vec_t segments;
S32 segment_start = old_length;
@@ -1755,11 +1781,32 @@ void LLTextBase::appendAndHighlightText(const std::string &new_text, bool prepen
{
setCursorPos(cursor_pos);
}
+}
+
+void LLTextBase::appendAndHighlightText(const std::string &new_text, bool prepend_newline, S32 highlight_part, const LLStyle::Params& style_params)
+{
+ if (new_text.empty()) return;
+
+ if(prepend_newline)
+ appendLineBreakSegment(style_params);
+
+ std::string::size_type start = 0;
+ std::string::size_type pos = new_text.find("\n",start);
+
+ while(pos!=-1)
+ {
+ if(pos!=start)
+ {
+ std::string str = std::string(new_text,start,pos-start);
+ appendAndHighlightTextImpl(str,highlight_part, style_params);
+ }
+ appendLineBreakSegment(style_params);
+ start = pos+1;
+ pos = new_text.find("\n",start);
+ }
- //if( !allow_undo )
- //{
- // blockUndo();
- //}
+ std::string str = std::string(new_text,start,new_text.length()-start);
+ appendAndHighlightTextImpl(str,highlight_part, style_params);
}
@@ -1852,14 +1899,19 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round,
S32 text_width, text_height;
bool newline = segmentp->getDimensions(line_seg_offset, segment_line_length, text_width, text_height);
+ if(newline)
+ {
+ pos = segment_line_start + segmentp->getOffset(local_x - start_x, line_seg_offset, segment_line_length, round);
+ break;
+ }
+
// if we've reached a line of text *below* the mouse cursor, doc index is first character on that line
if (hit_past_end_of_line && local_y - mVisibleTextRect.mBottom + visible_region.mBottom > line_iter->mRect.mTop)
{
pos = segment_line_start;
break;
}
- if (local_x < start_x + text_width // cursor to left of right edge of text
- || newline) // or this line ends with a newline, set doc pos to newline char
+ if (local_x < start_x + text_width) // cursor to left of right edge of text
{
// Figure out which character we're nearest to.
S32 offset;
@@ -1883,13 +1935,13 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round,
pos = segment_line_start + offset;
break;
}
- else if (hit_past_end_of_line && segmentp->getEnd() >= line_iter->mDocIndexEnd - 1)
+ else if (hit_past_end_of_line && segmentp->getEnd() > line_iter->mDocIndexEnd - 1)
{
- // segment wraps to next line, so just set doc pos to start of next line (represented by mDocIndexEnd)
- pos = llmin(getLength(), line_iter->mDocIndexEnd);
+ // segment wraps to next line, so just set doc pos to the end of the line
+ // segment wraps to next line, so just set doc pos to start of next line (represented by mDocIndexEnd)
+ pos = llmin(getLength(), line_iter->mDocIndexEnd);
break;
}
-
start_x += text_width;
}
@@ -2346,25 +2398,6 @@ F32 LLNormalTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selec
{
if( end - start > 0 )
{
- if ( mStyle->isImage() && (start >= 0) && (end <= mEnd - mStart))
- {
- // ...for images, only render the image, not the underlying text,
- // which is only a placeholder space
- LLColor4 color = LLColor4::white % mEditor.getDrawContext().mAlpha;
- LLUIImagePtr image = mStyle->getImage();
- S32 style_image_height = image->getHeight();
- S32 style_image_width = image->getWidth();
- // Text is drawn from the top of the draw_rect downward
- S32 text_center = draw_rect.mTop - (mFontHeight / 2);
- // Align image to center of text
- S32 image_bottom = text_center - (style_image_height / 2);
- image->draw(draw_rect.mLeft, image_bottom,
- style_image_width, style_image_height, color);
-
- const S32 IMAGE_HPAD = 3;
- return draw_rect.mLeft + style_image_width + IMAGE_HPAD;
- }
-
return drawClippedSegment( getStart() + start, getStart() + end, selection_start, selection_end, draw_rect);
}
return draw_rect.mLeft;
@@ -2377,11 +2410,6 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele
const LLWString &text = mEditor.getWText();
- if ( text[seg_end-1] == '\n' )
- {
- --seg_end;
- }
-
F32 right_x = rect.mLeft;
if (!mStyle->isVisible())
{
@@ -2540,33 +2568,14 @@ bool LLNormalTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& widt
{
height = 0;
width = 0;
- bool force_newline = false;
if (num_chars > 0)
{
height = mFontHeight;
const LLWString &text = mEditor.getWText();
// if last character is a newline, then return true, forcing line break
- llwchar last_char = text[mStart + first_char + num_chars - 1];
- if (last_char == '\n')
- {
- force_newline = true;
- // don't count newline in font width
- width = mStyle->getFont()->getWidth(text.c_str(), mStart + first_char, num_chars - 1);
- }
- else
- {
- width = mStyle->getFont()->getWidth(text.c_str(), mStart + first_char, num_chars);
- }
- }
-
- LLUIImagePtr image = mStyle->getImage();
- if( image.notNull())
- {
- width += image->getWidth();
- height = llmax(height, image->getHeight());
+ width = mStyle->getFont()->getWidth(text.c_str(), mStart + first_char, num_chars);
}
-
- return force_newline;
+ return false;
}
S32 LLNormalTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const
@@ -2589,15 +2598,7 @@ S32 LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 lin
num_pixels = llmax(0, num_pixels - image->getWidth());
}
- // search for newline and if found, truncate there
- S32 last_char = mStart + segment_offset;
- for (; last_char != mEnd; ++last_char)
- {
- if (text[last_char] == '\n')
- {
- break;
- }
- }
+ S32 last_char = mEnd;
// set max characters to length of segment, or to first newline
max_chars = llmin(max_chars, last_char - (mStart + segment_offset));
@@ -2625,8 +2626,7 @@ S32 LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 lin
S32 last_char_in_run = mStart + segment_offset + num_chars;
// check length first to avoid indexing off end of string
if (last_char_in_run < mEnd
- && (last_char_in_run >= mEditor.getLength()
- || text[last_char_in_run] == '\n'))
+ && (last_char_in_run >= mEditor.getLength() ))
{
num_chars++;
}
@@ -2721,3 +2721,87 @@ void LLInlineViewSegment::linkToDocument(LLTextBase* editor)
{
editor->addDocumentChild(mView);
}
+
+LLLineBreakTextSegment::LLLineBreakTextSegment(LLStyleConstSP style,S32 pos):LLTextSegment(pos,pos+1)
+{
+ mFontHeight = llceil(style->getFont()->getLineHeight());
+}
+LLLineBreakTextSegment::~LLLineBreakTextSegment()
+{
+}
+bool LLLineBreakTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const
+{
+ width = 0;
+ height = mFontHeight;
+
+ return true;
+}
+S32 LLLineBreakTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const
+{
+ return 1;
+}
+F32 LLLineBreakTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect)
+{
+ return draw_rect.mLeft;
+}
+
+LLImageTextSegment::LLImageTextSegment(LLStyleConstSP style,S32 pos,class LLTextBase& editor)
+ :LLTextSegment(pos,pos+1)
+ ,mStyle( style )
+ ,mEditor(editor)
+{
+}
+
+LLImageTextSegment::~LLImageTextSegment()
+{
+}
+
+static const S32 IMAGE_HPAD = 3;
+
+bool LLImageTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const
+{
+ width = 0;
+ height = llceil(mStyle->getFont()->getLineHeight());;
+
+ LLUIImagePtr image = mStyle->getImage();
+ if( image.notNull())
+ {
+ width += image->getWidth() + IMAGE_HPAD;
+ height = llmax(height, image->getHeight() + IMAGE_HPAD );
+ }
+ return false;
+}
+
+S32 LLImageTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const
+{
+ LLUIImagePtr image = mStyle->getImage();
+ S32 image_width = image->getWidth();
+ if(num_pixels>image_width + IMAGE_HPAD)
+ {
+ return 1;
+ }
+
+ return 0;
+}
+F32 LLImageTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect)
+{
+ if ( (start >= 0) && (end <= mEnd - mStart))
+ {
+ LLColor4 color = LLColor4::white % mEditor.getDrawContext().mAlpha;
+ LLUIImagePtr image = mStyle->getImage();
+ S32 style_image_height = image->getHeight();
+ S32 style_image_width = image->getWidth();
+ // Text is drawn from the top of the draw_rect downward
+
+ S32 text_center = draw_rect.mTop - (draw_rect.getHeight() / 2);
+ // Align image to center of draw rect
+ S32 image_bottom = text_center - (style_image_height / 2);
+ image->draw(draw_rect.mLeft, image_bottom,
+ style_image_width, style_image_height, color);
+
+ const S32 IMAGE_HPAD = 3;
+ return draw_rect.mLeft + style_image_width + IMAGE_HPAD;
+ }
+ return 0.0;
+}
+
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 8ed0680df9..176308c61a 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -316,6 +316,13 @@ protected:
void needsScroll() { mScrollNeeded = TRUE; }
void replaceUrlLabel(const std::string &url, const std::string &label);
+ void appendLineBreakSegment(const LLStyle::Params& style_params);
+ void appendImageSegment(S32 highlight_part, const LLStyle::Params& style_params);
+
+ void appendTextImpl(const std::string &new_text, const LLStyle::Params& input_params = LLStyle::Params());
+ void appendAndHighlightTextImpl(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params);
+
+
protected:
// text segmentation and flow
segment_set_t mSegments;
@@ -507,5 +514,32 @@ private:
bool mForceNewLine;
};
+class LLLineBreakTextSegment : public LLTextSegment
+{
+public:
+
+ LLLineBreakTextSegment(LLStyleConstSP style,S32 pos);
+ ~LLLineBreakTextSegment();
+ bool getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const;
+ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const;
+ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect);
+
+private:
+ S32 mFontHeight;
+};
+
+class LLImageTextSegment : public LLTextSegment
+{
+public:
+ LLImageTextSegment(LLStyleConstSP style,S32 pos,class LLTextBase& editor);
+ ~LLImageTextSegment();
+ bool getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const;
+ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const;
+ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect);
+
+private:
+ class LLTextBase& mEditor;
+ LLStyleConstSP mStyle;
+};
#endif
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 4fd62045e8..c9474d66b7 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -1083,6 +1083,28 @@ void LLTextEditor::addChar(llwchar wc)
setCursorPos(mCursorPos + addChar( mCursorPos, wc ));
}
+void LLTextEditor::addLineBreakChar()
+{
+ if( !getEnabled() )
+ {
+ return;
+ }
+ if( hasSelection() )
+ {
+ deleteSelection(TRUE);
+ }
+ else if (LL_KIM_OVERWRITE == gKeyboard->getInsertMode())
+ {
+ removeChar(mCursorPos);
+ }
+
+ LLStyleConstSP sp(new LLStyle(LLStyle::Params()));
+ LLTextSegmentPtr segment = new LLLineBreakTextSegment(sp, mCursorPos);
+
+ S32 pos = execute(new TextCmdAddChar(mCursorPos, FALSE, '\n', segment));
+
+ setCursorPos(mCursorPos + pos);
+}
BOOL LLTextEditor::handleSelectionKey(const KEY key, const MASK mask)
@@ -1404,7 +1426,27 @@ void LLTextEditor::pasteHelper(bool is_primary)
}
// Insert the new text into the existing text.
- setCursorPos(mCursorPos + insert(mCursorPos, clean_string, FALSE, LLTextSegmentPtr()));
+
+ //paste text with linebreaks.
+ std::basic_string<llwchar>::size_type start = 0;
+ std::basic_string<llwchar>::size_type pos = clean_string.find('\n',start);
+
+ while(pos!=-1)
+ {
+ if(pos!=start)
+ {
+ std::basic_string<llwchar> str = std::basic_string<llwchar>(clean_string,start,pos-start);
+ setCursorPos(mCursorPos + insert(mCursorPos, str, FALSE, LLTextSegmentPtr()));
+ }
+ addLineBreakChar();
+
+ start = pos+1;
+ pos = clean_string.find('\n',start);
+ }
+
+ std::basic_string<llwchar> str = std::basic_string<llwchar>(clean_string,start,clean_string.length()-start);
+ setCursorPos(mCursorPos + insert(mCursorPos, str, FALSE, LLTextSegmentPtr()));
+
deselect();
onKeyStroke();
@@ -2169,7 +2211,10 @@ void LLTextEditor::autoIndent()
}
// Insert that number of spaces on the new line
- addChar( '\n' );
+
+ //appendLineBreakSegment(LLStyle::Params());//addChar( '\n' );
+ addLineBreakChar();
+
for( i = 0; i < space_count; i++ )
{
addChar( ' ' );
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index 9b3ab9414c..7b68974fd8 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -240,6 +240,7 @@ protected:
// Undoable operations
void addChar(llwchar c); // at mCursorPos
S32 addChar(S32 pos, llwchar wc);
+ void addLineBreakChar();
S32 overwriteChar(S32 pos, llwchar wc);
void removeChar();
S32 removeChar(S32 pos);
diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h
index 71f030677a..3c21fe8d61 100644
--- a/indra/llui/llurlentry.h
+++ b/indra/llui/llurlentry.h
@@ -94,6 +94,8 @@ public:
/// is this a match for a URL that should not be hyperlinked?
bool isLinkDisabled() const { return mDisabledLink; }
+ virtual LLUUID getID(const std::string &string) const { return LLUUID::null; }
+
protected:
std::string getIDStringFromUrl(const std::string &url) const;
std::string escapeUrl(const std::string &url) const;
diff --git a/indra/llui/llurlmatch.cpp b/indra/llui/llurlmatch.cpp
index 72a199c220..7c96665ce4 100644
--- a/indra/llui/llurlmatch.cpp
+++ b/indra/llui/llurlmatch.cpp
@@ -51,7 +51,7 @@ void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url,
const std::string &label, const std::string &tooltip,
const std::string &icon, const LLUIColor& color,
const std::string &menu, const std::string &location,
- bool disabled_link)
+ bool disabled_link, const LLUUID& id)
{
mStart = start;
mEnd = end;
@@ -63,4 +63,5 @@ void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url,
mMenuName = menu;
mLocation = location;
mDisabledLink = disabled_link;
+ mID = id;
}
diff --git a/indra/llui/llurlmatch.h b/indra/llui/llurlmatch.h
index e86762548b..78dd2c528f 100644
--- a/indra/llui/llurlmatch.h
+++ b/indra/llui/llurlmatch.h
@@ -90,7 +90,10 @@ public:
void setValues(U32 start, U32 end, const std::string &url, const std::string &label,
const std::string &tooltip, const std::string &icon,
const LLUIColor& color, const std::string &menu,
- const std::string &location, bool disabled_link);
+ const std::string &location, bool disabled_link
+ , const LLUUID& id );
+
+ const LLUUID& getID() const { return mID;}
private:
U32 mStart;
@@ -101,6 +104,8 @@ private:
std::string mIcon;
std::string mMenuName;
std::string mLocation;
+
+ LLUUID mID;
LLUIColor mColor;
bool mDisabledLink;
};
diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp
index 4341286eb4..1f86f72faa 100644
--- a/indra/llui/llurlregistry.cpp
+++ b/indra/llui/llurlregistry.cpp
@@ -183,7 +183,8 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL
match_entry->getColor(),
match_entry->getMenuName(),
match_entry->getLocation(url),
- match_entry->isLinkDisabled());
+ match_entry->isLinkDisabled(),
+ match_entry->getID(url));
return true;
}
@@ -217,7 +218,8 @@ bool LLUrlRegistry::findUrl(const LLWString &text, LLUrlMatch &match, const LLUr
match.getColor(),
match.getMenuName(),
match.getLocation(),
- match.isLinkDisabled());
+ match.isLinkDisabled(),
+ match.getID());
return true;
}
return false;
diff --git a/indra/llui/tests/llurlmatch_test.cpp b/indra/llui/tests/llurlmatch_test.cpp
index 24a32de268..06b850d233 100644
--- a/indra/llui/tests/llurlmatch_test.cpp
+++ b/indra/llui/tests/llurlmatch_test.cpp
@@ -54,7 +54,7 @@ namespace tut
LLUrlMatch match;
ensure("empty()", match.empty());
- match.setValues(0, 1, "http://secondlife.com", "Second Life", "", "", LLUIColor(), "", "", false);
+ match.setValues(0, 1, "http://secondlife.com", "Second Life", "", "", LLUIColor(), "", "", false,LLUUID::null);
ensure("! empty()", ! match.empty());
}
@@ -67,7 +67,7 @@ namespace tut
LLUrlMatch match;
ensure_equals("getStart() == 0", match.getStart(), 0);
- match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false);
+ match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false,LLUUID::null);
ensure_equals("getStart() == 10", match.getStart(), 10);
}
@@ -80,7 +80,7 @@ namespace tut
LLUrlMatch match;
ensure_equals("getEnd() == 0", match.getEnd(), 0);
- match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false);
+ match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false,LLUUID::null);
ensure_equals("getEnd() == 20", match.getEnd(), 20);
}
@@ -93,10 +93,10 @@ namespace tut
LLUrlMatch match;
ensure_equals("getUrl() == ''", match.getUrl(), "");
- match.setValues(10, 20, "http://slurl.com/", "", "", "", LLUIColor(), "", "", false);
+ match.setValues(10, 20, "http://slurl.com/", "", "", "", LLUIColor(), "", "", false,LLUUID::null);
ensure_equals("getUrl() == 'http://slurl.com/'", match.getUrl(), "http://slurl.com/");
- match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false);
+ match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false,LLUUID::null);
ensure_equals("getUrl() == '' (2)", match.getUrl(), "");
}
@@ -109,10 +109,10 @@ namespace tut
LLUrlMatch match;
ensure_equals("getLabel() == ''", match.getLabel(), "");
- match.setValues(10, 20, "", "Label", "", "", LLUIColor(), "", "", false);
+ match.setValues(10, 20, "", "Label", "", "", LLUIColor(), "", "", false,LLUUID::null);
ensure_equals("getLabel() == 'Label'", match.getLabel(), "Label");
- match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false);
+ match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false,LLUUID::null);
ensure_equals("getLabel() == '' (2)", match.getLabel(), "");
}
@@ -125,10 +125,10 @@ namespace tut
LLUrlMatch match;
ensure_equals("getTooltip() == ''", match.getTooltip(), "");
- match.setValues(10, 20, "", "", "Info", "", LLUIColor(), "", "", false);
+ match.setValues(10, 20, "", "", "Info", "", LLUIColor(), "", "", false,LLUUID::null);
ensure_equals("getTooltip() == 'Info'", match.getTooltip(), "Info");
- match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false);
+ match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false,LLUUID::null);
ensure_equals("getTooltip() == '' (2)", match.getTooltip(), "");
}
@@ -141,10 +141,10 @@ namespace tut
LLUrlMatch match;
ensure_equals("getIcon() == ''", match.getIcon(), "");
- match.setValues(10, 20, "", "", "", "Icon", LLUIColor(), "", "", false);
+ match.setValues(10, 20, "", "", "", "Icon", LLUIColor(), "", "", false,LLUUID::null);
ensure_equals("getIcon() == 'Icon'", match.getIcon(), "Icon");
- match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false);
+ match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false,LLUUID::null);
ensure_equals("getIcon() == '' (2)", match.getIcon(), "");
}
@@ -157,10 +157,10 @@ namespace tut
LLUrlMatch match;
ensure("getMenuName() empty", match.getMenuName().empty());
- match.setValues(10, 20, "", "", "", "Icon", LLUIColor(), "xui_file.xml", "", false);
+ match.setValues(10, 20, "", "", "", "Icon", LLUIColor(), "xui_file.xml", "", false,LLUUID::null);
ensure_equals("getMenuName() == \"xui_file.xml\"", match.getMenuName(), "xui_file.xml");
- match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false);
+ match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false,LLUUID::null);
ensure("getMenuName() empty (2)", match.getMenuName().empty());
}
@@ -173,10 +173,10 @@ namespace tut
LLUrlMatch match;
ensure("getLocation() empty", match.getLocation().empty());
- match.setValues(10, 20, "", "", "", "Icon", LLUIColor(), "xui_file.xml", "Paris", false);
+ match.setValues(10, 20, "", "", "", "Icon", LLUIColor(), "xui_file.xml", "Paris", false,LLUUID::null);
ensure_equals("getLocation() == \"Paris\"", match.getLocation(), "Paris");
- match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false);
+ match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false,LLUUID::null);
ensure("getLocation() empty (2)", match.getLocation().empty());
}
}
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 9ba44e787b..b00104c427 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -466,6 +466,7 @@ set(viewer_SOURCE_FILES
llviewchildren.cpp
llviewerassetstorage.cpp
llviewerassettype.cpp
+ llviewerattachmenu.cpp
llvieweraudio.cpp
llviewercamera.cpp
llviewerchat.cpp
@@ -984,6 +985,7 @@ set(viewer_HEADER_FILES
llviewchildren.h
llviewerassetstorage.h
llviewerassettype.h
+ llviewerattachmenu.h
llvieweraudio.h
llviewercamera.h
llviewerchat.h
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index c0be54a105..e86f50ce20 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -8294,17 +8294,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>ShowSidebarButton</key>
- <map>
- <key>Comment</key>
- <string>Shows/hides Sidebar button in the bottom tray.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>ShowSnapshotButton</key>
<map>
<key>Comment</key>
@@ -8847,17 +8836,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>SidebarWithButtonsVisibility</key>
- <map>
- <key>Comment</key>
- <string>Sets visibility of sidebar with its tabs' buttons</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>SkinCurrent</key>
<map>
<key>Comment</key>
@@ -11384,5 +11362,16 @@
<string>mini_map</string>
</array>
</map>
+ <key>LandmarksSortedByDate</key>
+ <map>
+ <key>Comment</key>
+ <string>Reflects landmarks panel sorting order.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
</map>
</llsd>
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index e5796f8e63..d2a01aba16 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -1974,6 +1974,32 @@ bool LLAgentWearables::moveWearable(const LLViewerInventoryItem* item, bool clos
}
// static
+void LLAgentWearables::createWearable(LLWearableType::EType type, bool wear, const LLUUID& parent_id)
+{
+ LLWearable* wearable = LLWearableList::instance().createNewWearable(type);
+ LLAssetType::EType asset_type = wearable->getAssetType();
+ LLInventoryType::EType inv_type = LLInventoryType::IT_WEARABLE;
+ LLPointer<LLInventoryCallback> cb = wear ? new WearOnAvatarCallback : NULL;
+ LLUUID folder_id;
+
+ if (parent_id.notNull())
+ {
+ folder_id = parent_id;
+ }
+ else
+ {
+ LLFolderType::EType folder_type = LLFolderType::assetTypeToFolderType(asset_type);
+ folder_id = gInventory.findCategoryUUIDForType(folder_type);
+ }
+
+ create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
+ folder_id, wearable->getTransactionID(), wearable->getName(),
+ wearable->getDescription(), asset_type, inv_type, wearable->getType(),
+ wearable->getPermissions().getMaskNextOwner(),
+ cb);
+}
+
+// static
void LLAgentWearables::editWearable(const LLUUID& item_id)
{
LLViewerInventoryItem* item;
diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h
index 5d5c5ae371..6d379746ba 100644
--- a/indra/newview/llagentwearables.h
+++ b/indra/newview/llagentwearables.h
@@ -144,6 +144,7 @@ protected:
//--------------------------------------------------------------------
public:
+ static void createWearable(LLWearableType::EType type, bool wear = false, const LLUUID& parent_id = LLUUID::null);
static void editWearable(const LLUUID& item_id);
bool moveWearable(const LLViewerInventoryItem* item, bool closer_to_body);
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index f27e632180..75ffb9f329 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -704,6 +704,40 @@ void LLAppearanceMgr::replaceCurrentOutfit(const LLUUID& new_outfit)
wearInventoryCategory(cat, false, false);
}
+// Open outfit renaming dialog.
+void LLAppearanceMgr::renameOutfit(const LLUUID& outfit_id)
+{
+ LLViewerInventoryCategory* cat = gInventory.getCategory(outfit_id);
+ if (!cat)
+ {
+ return;
+ }
+
+ LLSD args;
+ args["NAME"] = cat->getName();
+
+ LLSD payload;
+ payload["cat_id"] = outfit_id;
+
+ LLNotificationsUtil::add("RenameOutfit", args, payload, boost::bind(onOutfitRename, _1, _2));
+}
+
+// User typed new outfit name.
+// static
+void LLAppearanceMgr::onOutfitRename(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option != 0) return; // canceled
+
+ std::string outfit_name = response["new_name"].asString();
+ LLStringUtil::trim(outfit_name);
+ if (!outfit_name.empty())
+ {
+ LLUUID cat_id = notification["payload"]["cat_id"].asUUID();
+ rename_category(&gInventory, cat_id, outfit_name);
+ }
+}
+
void LLAppearanceMgr::addCategoryToCurrentOutfit(const LLUUID& cat_id)
{
LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
@@ -714,7 +748,7 @@ void LLAppearanceMgr::takeOffOutfit(const LLUUID& cat_id)
{
LLInventoryModel::cat_array_t cats;
LLInventoryModel::item_array_t items;
- LLFindWearables collector;
+ LLFindWorn collector;
gInventory.collectDescendentsIf(cat_id, cats, items, FALSE, collector);
@@ -842,6 +876,41 @@ BOOL LLAppearanceMgr::getCanMakeFolderIntoOutfit(const LLUUID& folder_id)
return ((required_wearables & folder_wearables) == required_wearables);
}
+bool LLAppearanceMgr::getCanRemoveOutfit(const LLUUID& outfit_cat_id)
+{
+ // Disallow removing the base outfit.
+ if (outfit_cat_id == getBaseOutfitUUID())
+ {
+ return false;
+ }
+
+ // Check if the outfit folder itself is removable.
+ if (!get_is_category_removable(&gInventory, outfit_cat_id))
+ {
+ return false;
+ }
+
+ // Check if the folder contains worn items.
+ LLInventoryModel::cat_array_t cats;
+ LLInventoryModel::item_array_t items;
+ LLFindWorn filter_worn;
+ gInventory.collectDescendentsIf(outfit_cat_id, cats, items, false, filter_worn);
+ if (!items.empty())
+ {
+ return false;
+ }
+
+ // Check for the folder's non-removable descendants.
+ LLFindNonRemovableObjects filter_non_removable;
+ LLInventoryModel::item_array_t::const_iterator it;
+ gInventory.collectDescendentsIf(outfit_cat_id, cats, items, false, filter_non_removable);
+ if (!cats.empty() || !items.empty())
+ {
+ return false;
+ }
+
+ return true;
+}
void LLAppearanceMgr::purgeBaseOutfitLink(const LLUUID& category)
{
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index dbde055c3a..f1beef5857 100644
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -59,6 +59,7 @@ public:
void wearOutfitByName(const std::string& name);
void changeOutfit(bool proceed, const LLUUID& category, bool append);
void replaceCurrentOutfit(const LLUUID& new_outfit);
+ void renameOutfit(const LLUUID& outfit_id);
void takeOffOutfit(const LLUUID& cat_id);
void addCategoryToCurrentOutfit(const LLUUID& cat_id);
@@ -69,6 +70,9 @@ public:
// Return whether this folder contains minimal contents suitable for making a full outfit.
BOOL getCanMakeFolderIntoOutfit(const LLUUID& folder_id);
+ // Determine whether a given outfit can be removed.
+ bool getCanRemoveOutfit(const LLUUID& outfit_cat_id);
+
// Copy all items in a category.
void shallowCopyCategoryContents(const LLUUID& src_id, const LLUUID& dst_id,
LLPointer<LLInventoryCallback> cb);
@@ -180,6 +184,8 @@ private:
void purgeCategory(const LLUUID& category, bool keep_outfit_links);
void purgeBaseOutfitLink(const LLUUID& category);
+ static void onOutfitRename(const LLSD& notification, const LLSD& response);
+
std::set<LLUUID> mRegisteredAttachments;
bool mAttachmentInvLinkEnabled;
bool mOutfitIsDirty;
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 875ed72a12..01d6c3a8d5 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -475,32 +475,83 @@ namespace action_give_inventory
return acceptable;
}
- /**
- * Performs "give inventory" operations for provided avatars.
- *
- * Sends one requests to give all selected inventory items for each passed avatar.
- * Avatars are represent by two vectors: names and UUIDs which must be sychronized with each other.
- *
- * @param avatar_names - avatar names request to be sent.
- * @param avatar_uuids - avatar names request to be sent.
- */
- static void give_inventory(const std::vector<std::string>& avatar_names, const uuid_vec_t& avatar_uuids)
+ static void build_residents_string(const std::vector<std::string>& avatar_names, std::string& residents_string)
{
- llassert(avatar_names.size() == avatar_uuids.size());
+ llassert(avatar_names.size() > 0);
+
+ const std::string& separator = LLTrans::getString("words_separator");
+ for (std::vector<std::string>::const_iterator it = avatar_names.begin(); ; )
+ {
+ residents_string.append(*it);
+ if (++it == avatar_names.end())
+ {
+ break;
+ }
+ residents_string.append(separator);
+ }
+ }
+
+ static void build_items_string(const uuid_set_t& inventory_selected_uuids , std::string& items_string)
+ {
+ llassert(inventory_selected_uuids.size() > 0);
+
+ const std::string& separator = LLTrans::getString("words_separator");
+ for (uuid_set_t::const_iterator it = inventory_selected_uuids.begin(); ; )
+ {
+ LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it);
+ if (NULL != inv_cat)
+ {
+ items_string = inv_cat->getName();
+ break;
+ }
+ LLViewerInventoryItem* inv_item = gInventory.getItem(*it);
+ if (NULL != inv_item)
+ {
+ items_string.append(inv_item->getName());
+ }
+ if(++it == inventory_selected_uuids.end())
+ {
+ break;
+ }
+ items_string.append(separator);
+ }
+ }
+
+ struct LLShareInfo : public LLSingleton<LLShareInfo>
+ {
+ std::vector<std::string> mAvatarNames;
+ uuid_vec_t mAvatarUuids;
+ };
+
+ static void give_inventory_cb(const LLSD& notification, const LLSD& response)
+ {
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ // if Cancel pressed
+ if (option == 1)
+ {
+ return;
+ }
LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE);
- if (NULL == active_panel) return;
+ if (NULL == active_panel)
+ {
+ return;
+ }
const uuid_set_t inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList();
- if (inventory_selected_uuids.empty()) return;
+ if (inventory_selected_uuids.empty())
+ {
+ return;
+ }
- S32 count = llmin(avatar_names.size(), avatar_uuids.size());
+ S32 count = LLShareInfo::instance().mAvatarNames.size();
+ bool shared = false;
// iterate through avatars
for(S32 i = 0; i < count; ++i)
{
- const std::string& avatar_name = avatar_names[i];
- const LLUUID& avatar_uuid = avatar_uuids[i];
+ const std::string& avatar_name = LLShareInfo::instance().mAvatarNames[i];
+ const LLUUID& avatar_uuid = LLShareInfo::instance().mAvatarUuids[i];
// Start up IM before give the item
const LLUUID session_id = gIMMgr->addSession(avatar_name, IM_NOTHING_SPECIAL, avatar_uuid);
@@ -508,6 +559,9 @@ namespace action_give_inventory
uuid_set_t::const_iterator it = inventory_selected_uuids.begin();
const uuid_set_t::const_iterator it_end = inventory_selected_uuids.end();
+ const std::string& separator = LLTrans::getString("words_separator");
+ std::string noncopy_item_names;
+ LLSD noncopy_items = LLSD::emptyArray();
// iterate through selected inventory objects
for (; it != it_end; ++it)
{
@@ -515,12 +569,82 @@ namespace action_give_inventory
if (inv_cat)
{
LLGiveInventory::doGiveInventoryCategory(avatar_uuid, inv_cat, session_id);
+ shared = true;
break;
}
LLViewerInventoryItem* inv_item = gInventory.getItem(*it);
- LLGiveInventory::doGiveInventoryItem(avatar_uuid, inv_item, session_id);
+ if (!inv_item->getPermissions().allowCopyBy(gAgentID))
+ {
+ if (!noncopy_item_names.empty())
+ {
+ noncopy_item_names.append(separator);
+ }
+ noncopy_item_names.append(inv_item->getName());
+ noncopy_items.append(*it);
+ }
+ else
+ {
+ LLGiveInventory::doGiveInventoryItem(avatar_uuid, inv_item, session_id);
+ shared = true;
+ }
+ }
+ if (noncopy_items.beginArray() != noncopy_items.endArray())
+ {
+ LLSD substitutions;
+ substitutions["ITEMS"] = noncopy_item_names;
+ LLSD payload;
+ payload["agent_id"] = avatar_uuid;
+ payload["items"] = noncopy_items;
+ LLNotificationsUtil::add("CannotCopyWarning", substitutions, payload,
+ &LLGiveInventory::handleCopyProtectedItem);
+ break;
}
}
+ if (shared)
+ {
+ LLFloaterReg::hideInstance("avatar_picker");
+ LLNotificationsUtil::add("ItemsShared");
+ }
+ }
+
+ /**
+ * Performs "give inventory" operations for provided avatars.
+ *
+ * Sends one requests to give all selected inventory items for each passed avatar.
+ * Avatars are represent by two vectors: names and UUIDs which must be sychronized with each other.
+ *
+ * @param avatar_names - avatar names request to be sent.
+ * @param avatar_uuids - avatar names request to be sent.
+ */
+ static void give_inventory(const std::vector<std::string>& avatar_names, const uuid_vec_t& avatar_uuids)
+ {
+ llassert(avatar_names.size() == avatar_uuids.size());
+
+
+ LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE);
+ if (NULL == active_panel)
+ {
+ return;
+ }
+
+ const uuid_set_t inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList();
+ if (inventory_selected_uuids.empty())
+ {
+ return;
+ }
+
+ std::string residents;
+ build_residents_string(avatar_names, residents);
+
+ std::string items;
+ build_items_string(inventory_selected_uuids, items);
+
+ LLSD substitutions;
+ substitutions["RESIDENTS"] = residents;
+ substitutions["ITEMS"] = items;
+ LLShareInfo::instance().mAvatarNames = avatar_names;
+ LLShareInfo::instance().mAvatarUuids = avatar_uuids;
+ LLNotificationsUtil::add("ShareItemsConfirmation", substitutions, LLSD(), &give_inventory_cb);
}
}
@@ -532,7 +656,6 @@ void LLAvatarActions::shareWithAvatars()
LLFloaterAvatarPicker* picker =
LLFloaterAvatarPicker::show(boost::bind(give_inventory, _1, _2), TRUE, FALSE);
picker->setOkBtnEnableCb(boost::bind(is_give_inventory_acceptable));
- LLNotificationsUtil::add("ShareNotification");
}
// static
diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp
index a057421135..7a3eddf7a6 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* ?
@@ -1164,7 +1170,6 @@ void LLBottomTray::initResizeStateContainers()
mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_MOVEMENT, getChild<LLPanel>("movement_panel")));
mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_CAMERA, getChild<LLPanel>("cam_panel")));
mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_SNAPSHOT, getChild<LLPanel>("snapshot_panel")));
- mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_SIDEBAR, getChild<LLPanel>("sidebar_btn_panel")));
mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_BUILD, getChild<LLPanel>("build_btn_panel")));
mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_SEARCH, getChild<LLPanel>("search_btn_panel")));
mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_WORLD_MAP, getChild<LLPanel>("world_map_btn_panel")));
@@ -1175,7 +1180,6 @@ void LLBottomTray::initResizeStateContainers()
mButtonsProcessOrder.push_back(RS_BUTTON_MOVEMENT);
mButtonsProcessOrder.push_back(RS_BUTTON_CAMERA);
mButtonsProcessOrder.push_back(RS_BUTTON_SNAPSHOT);
- mButtonsProcessOrder.push_back(RS_BUTTON_SIDEBAR);
mButtonsProcessOrder.push_back(RS_BUTTON_BUILD);
mButtonsProcessOrder.push_back(RS_BUTTON_SEARCH);
mButtonsProcessOrder.push_back(RS_BUTTON_WORLD_MAP);
@@ -1211,7 +1215,6 @@ void LLBottomTray::initButtonsVisibility()
setVisibleAndFitWidths(RS_BUTTON_MOVEMENT, gSavedSettings.getBOOL("ShowMoveButton"));
setVisibleAndFitWidths(RS_BUTTON_CAMERA, gSavedSettings.getBOOL("ShowCameraButton"));
setVisibleAndFitWidths(RS_BUTTON_SNAPSHOT, gSavedSettings.getBOOL("ShowSnapshotButton"));
- setVisibleAndFitWidths(RS_BUTTON_SIDEBAR, gSavedSettings.getBOOL("ShowSidebarButton"));
setVisibleAndFitWidths(RS_BUTTON_BUILD, gSavedSettings.getBOOL("ShowBuildButton"));
setVisibleAndFitWidths(RS_BUTTON_SEARCH, gSavedSettings.getBOOL("ShowSearchButton"));
setVisibleAndFitWidths(RS_BUTTON_WORLD_MAP, gSavedSettings.getBOOL("ShowWorldMapButton"));
@@ -1224,7 +1227,6 @@ void LLBottomTray::setButtonsControlsAndListeners()
gSavedSettings.getControl("ShowMoveButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_MOVEMENT, _2));
gSavedSettings.getControl("ShowCameraButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_CAMERA, _2));
gSavedSettings.getControl("ShowSnapshotButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_SNAPSHOT, _2));
- gSavedSettings.getControl("ShowSidebarButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_SIDEBAR, _2));
gSavedSettings.getControl("ShowBuildButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_BUILD, _2));
gSavedSettings.getControl("ShowSearchButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_SEARCH, _2));
gSavedSettings.getControl("ShowWorldMapButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_WORLD_MAP, _2));
diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h
index c0887df39a..05fed53936 100644
--- a/indra/newview/llbottomtray.h
+++ b/indra/newview/llbottomtray.h
@@ -124,7 +124,6 @@ private:
, RS_BUTTON_SEARCH = 0x0400
, RS_BUTTON_WORLD_MAP = 0x0800
, RS_BUTTON_MINI_MAP = 0x1000
- , RS_BUTTON_SIDEBAR = 0x2000
/*
Once new button that can be hidden on resize is added don't forget to update related places:
@@ -139,7 +138,6 @@ private:
*/
, RS_BUTTONS_CAN_BE_HIDDEN = RS_BUTTON_SNAPSHOT | RS_BUTTON_CAMERA | RS_BUTTON_MOVEMENT | RS_BUTTON_GESTURES
| RS_BUTTON_BUILD | RS_BUTTON_SEARCH | RS_BUTTON_WORLD_MAP | RS_BUTTON_MINI_MAP
- | RS_BUTTON_SIDEBAR
}EResizeState;
/**
diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp
index ee366f4e3c..7ac3d14c72 100644
--- a/indra/newview/llcofwearables.cpp
+++ b/indra/newview/llcofwearables.cpp
@@ -45,8 +45,7 @@
#include "llwearableitemslist.h"
#include "llpaneloutfitedit.h"
#include "llsidetray.h"
-
-static LLRegisterPanelClassWrapper<LLCOFAccordionListAdaptor> t_cof_accodion_list_adaptor("accordion_list_adaptor");
+#include "lltrans.h"
static LLRegisterPanelClassWrapper<LLCOFWearables> t_cof_wearables("cof_wearables");
@@ -54,6 +53,39 @@ const LLSD REARRANGE = LLSD().with("rearrange", LLSD());
static const LLWearableItemNameComparator WEARABLE_NAME_COMPARATOR;
+//////////////////////////////////////////////////////////////////////////
+
+class CofContextMenu : public LLListContextMenu
+{
+protected:
+ static void updateCreateWearableLabel(LLMenuGL* menu, const LLUUID& item_id)
+ {
+ LLMenuItemGL* menu_item = menu->getChild<LLMenuItemGL>("create_new");
+
+ // Hide the "Create new <WEARABLE_TYPE>" if it's irrelevant.
+ LLViewerInventoryItem* item = gInventory.getLinkedItem(item_id);
+ if (!item || !item->isWearableType())
+ {
+ menu_item->setVisible(FALSE);
+ return;
+ }
+
+ // Set proper label for the "Create new <WEARABLE_TYPE>" menu item.
+ LLStringUtil::format_map_t args;
+ LLWearableType::EType w_type = item->getWearableType();
+ args["[WEARABLE_TYPE]"] = LLWearableType::getTypeDefaultNewName(w_type);
+ std::string new_label = LLTrans::getString("CreateNewWearable", args);
+ menu_item->setLabel(new_label);
+ }
+
+ static void createNew(const LLUUID& item_id)
+ {
+ LLViewerInventoryItem* item = gInventory.getLinkedItem(item_id);
+ if (!item || !item->isWearableType()) return;
+
+ LLAgentWearables::createWearable(item->getWearableType(), true);
+ }
+};
//////////////////////////////////////////////////////////////////////////
@@ -74,7 +106,7 @@ protected:
//////////////////////////////////////////////////////////////////////////
-class CofClothingContextMenu : public LLListContextMenu
+class CofClothingContextMenu : public CofContextMenu
{
protected:
@@ -89,10 +121,17 @@ protected:
registrar.add("Clothing.MoveUp", boost::bind(moveWearable, selected_id, false));
registrar.add("Clothing.MoveDown", boost::bind(moveWearable, selected_id, true));
registrar.add("Clothing.Edit", boost::bind(LLAgentWearables::editWearable, selected_id));
+ registrar.add("Clothing.Create", boost::bind(createNew, selected_id));
enable_registrar.add("Clothing.OnEnable", boost::bind(&CofClothingContextMenu::onEnable, this, _2));
- return createFromFile("menu_cof_clothing.xml");
+ LLContextMenu* menu = createFromFile("menu_cof_clothing.xml");
+ llassert(menu);
+ if (menu)
+ {
+ updateCreateWearableLabel(menu, selected_id);
+ }
+ return menu;
}
bool onEnable(const LLSD& data)
@@ -108,6 +147,10 @@ protected:
{
return gAgentWearables.canMoveWearable(selected_id, true);
}
+ else if ("take_off" == param)
+ {
+ return get_is_item_worn(selected_id);
+ }
else if ("edit" == param)
{
return gAgentWearables.isWearableModifiable(selected_id);
@@ -122,12 +165,11 @@ protected:
LLViewerInventoryItem* item = gInventory.getItem(item_id);
return LLAppearanceMgr::instance().moveWearable(item, closer_to_body);
}
-
};
//////////////////////////////////////////////////////////////////////////
-class CofBodyPartContextMenu : public LLListContextMenu
+class CofBodyPartContextMenu : public CofContextMenu
{
protected:
@@ -142,10 +184,17 @@ protected:
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));
+ registrar.add("BodyPart.Create", boost::bind(createNew, selected_id));
enable_registrar.add("BodyPart.OnEnable", boost::bind(&CofBodyPartContextMenu::onEnable, this, _2));
- return createFromFile("menu_cof_body_part.xml");
+ LLContextMenu* menu = createFromFile("menu_cof_body_part.xml");
+ llassert(menu);
+ if (menu)
+ {
+ updateCreateWearableLabel(menu, selected_id);
+ }
+ return menu;
}
bool onEnable(const LLSD& data)
@@ -338,7 +387,13 @@ LLPanelClothingListItem* LLCOFWearables::buildClothingListItem(LLViewerInventory
item_panel->childSetAction("btn_edit", mCOFCallbacks.mEditWearable);
//turning on gray separator line for the last item in the items group of the same wearable type
- item_panel->childSetVisible("wearable_type_separator_panel", last);
+ if (last)
+ {
+ LLRect rect = item_panel->getRect();
+ item_panel->reshape(rect.getWidth(), rect.getHeight() +
+ item_panel->getChild<LLView>("wearable_type_separator_icon")->getRect().getHeight());
+ item_panel->childSetVisible("wearable_type_separator_icon", true);
+ }
return item_panel;
}
diff --git a/indra/newview/llcofwearables.h b/indra/newview/llcofwearables.h
index 8f8bda2be8..f99f2662e6 100644
--- a/indra/newview/llcofwearables.h
+++ b/indra/newview/llcofwearables.h
@@ -45,53 +45,6 @@ class LLPanelClothingListItem;
class LLPanelBodyPartsListItem;
class LLPanelDeletableWearableListItem;
-/**
- * Adaptor between LLAccordionCtrlTab and LLFlatListView to facilitate communication between them
- * (notify, notifyParent) regarding size changes of a list and selection changes across accordion tabs.
- * Besides that it acts as a container for the LLFlatListView and a button bar on top of it.
- */
-class LLCOFAccordionListAdaptor : public LLPanel
-{
-public:
- LLCOFAccordionListAdaptor() : LLPanel() {};
- ~LLCOFAccordionListAdaptor() {};
-
- S32 notifyParent(const LLSD& info)
- {
- LLView* parent = getParent();
- if (!parent) return -1;
-
- if (!(info.has("action") && "size_changes" == info["action"].asString()))
- {
- return parent->notifyParent(info);
- }
-
- LLRect rc;
- childGetRect("button_bar", rc);
-
- LLSD params;
- params["action"] = "size_changes";
- params["width"] = info["width"];
- params["height"] = info["height"].asInteger() + rc.getHeight();
-
- return parent->notifyParent(params);
- }
-
-
- S32 notify(const LLSD& info)
- {
- for (child_list_const_iter_t iter = beginChild(); iter != endChild(); iter++)
- {
- if (dynamic_cast<LLFlatListView*>(*iter))
- {
- return (*iter)->notify(info);
- }
- }
- return LLPanel::notify(info);
- };
-};
-
-
class LLCOFWearables : public LLPanel
{
public:
diff --git a/indra/newview/llfilteredwearablelist.cpp b/indra/newview/llfilteredwearablelist.cpp
index 28e159421c..306fa5ad6d 100644
--- a/indra/newview/llfilteredwearablelist.cpp
+++ b/indra/newview/llfilteredwearablelist.cpp
@@ -54,6 +54,15 @@ LLFilteredWearableListManager::~LLFilteredWearableListManager()
void LLFilteredWearableListManager::changed(U32 mask)
{
+ if (LLInventoryObserver::CALLING_CARD == mask
+ || LLInventoryObserver::GESTURE == mask
+ || LLInventoryObserver::SORT == mask
+ )
+ {
+ // skip non-related changes
+ return;
+ }
+
if(!gInventory.isInventoryUsable())
{
return;
diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index b40c19c2c6..96364f9418 100644
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -437,7 +437,7 @@ BOOL LLFloaterAvatarPicker::handleDragAndDrop(S32 x, S32 y, MASK mask,
session_id = gIMMgr->addSession(avatar_name, IM_NOTHING_SPECIAL, dest_agent_id);
}
return LLToolDragAndDrop::handleGiveDragAndDrop(dest_agent_id, session_id, drop,
- cargo_type, cargo_data, accept);
+ cargo_type, cargo_data, accept, getName());
}
}
}
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index abdb55ec17..7c5586ec96 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -572,7 +572,7 @@ void LLPanelLandGeneral::refresh()
if (regionp)
{
insert_maturity_into_textbox(mContentRating, gFloaterView->getParentFloater(this), MATURITY);
- mLandType->setText(regionp->getSimProductName());
+ mLandType->setText(LLTrans::getString(regionp->getSimProductName()));
}
// estate owner/manager cannot edit other parts of the parcel
diff --git a/indra/newview/llfloatermap.cpp b/indra/newview/llfloatermap.cpp
index 725fc17136..c259659083 100644
--- a/indra/newview/llfloatermap.cpp
+++ b/indra/newview/llfloatermap.cpp
@@ -106,6 +106,8 @@ BOOL LLFloaterMap::postBuild()
mPopupMenu->setItemEnabled ("Stop Tracking", false);
}
+ stretchMiniMap(getRect().getWidth(),getRect().getHeight());
+
updateMinorDirections();
// Get the drag handle all the way in back
@@ -229,10 +231,8 @@ void LLFloaterMap::onFocusLost()
LLPanel::onFocusLost();
}
-void LLFloaterMap::reshape(S32 width, S32 height, BOOL called_from_parent)
+void LLFloaterMap::stretchMiniMap(S32 width,S32 height)
{
- LLFloater::reshape(width, height, called_from_parent);
-
//fix for ext-7112
//by default ctrl can't overlap caption area
if(mMap)
@@ -242,6 +242,13 @@ void LLFloaterMap::reshape(S32 width, S32 height, BOOL called_from_parent)
mMap->reshape( width, height, 1);
mMap->setRect(map_rect);
}
+}
+
+void LLFloaterMap::reshape(S32 width, S32 height, BOOL called_from_parent)
+{
+ LLFloater::reshape(width, height, called_from_parent);
+
+ stretchMiniMap(width, height);
updateMinorDirections();
}
diff --git a/indra/newview/llfloatermap.h b/indra/newview/llfloatermap.h
index 9ff2f03180..3c063adfb8 100644
--- a/indra/newview/llfloatermap.h
+++ b/indra/newview/llfloatermap.h
@@ -61,6 +61,8 @@ private:
void handleStopTracking (const LLSD& userdata);
void setDirectionPos( LLTextBox* text_box, F32 rotation );
void updateMinorDirections();
+
+ void stretchMiniMap(S32 width,S32 height);
LLMenuGL* mPopupMenu;
diff --git a/indra/newview/llgiveinventory.cpp b/indra/newview/llgiveinventory.cpp
index d83d895dd0..aebf1b4c26 100644
--- a/indra/newview/llgiveinventory.cpp
+++ b/indra/newview/llgiveinventory.cpp
@@ -192,15 +192,16 @@ bool LLGiveInventory::isInventoryGroupGiveAcceptable(const LLInventoryItem* item
}
// static
-void LLGiveInventory::doGiveInventoryItem(const LLUUID& to_agent,
+bool LLGiveInventory::doGiveInventoryItem(const LLUUID& to_agent,
const LLInventoryItem* item,
const LLUUID& im_session_id/* = LLUUID::null*/)
{
+ bool res = true;
llinfos << "LLGiveInventory::giveInventory()" << llendl;
if (!isInventoryGiveAcceptable(item))
{
- return;
+ return false;
}
if (item->getPermissions().allowCopyBy(gAgentID))
{
@@ -210,12 +211,19 @@ void LLGiveInventory::doGiveInventoryItem(const LLUUID& to_agent,
else
{
// ask if the agent is sure.
+ LLSD substitutions;
+ substitutions["ITEMS"] = item->getName();
LLSD payload;
payload["agent_id"] = to_agent;
- payload["item_id"] = item->getUUID();
- LLNotificationsUtil::add("CannotCopyWarning", LLSD(), payload,
+ LLSD items = LLSD::emptyArray();
+ items.append(item->getUUID());
+ payload["items"] = items;
+ LLNotificationsUtil::add("CannotCopyWarning", substitutions, payload,
&LLGiveInventory::handleCopyProtectedItem);
+ res = false;
}
+
+ return res;
}
void LLGiveInventory::doGiveInventoryCategory(const LLUUID& to_agent,
@@ -318,23 +326,27 @@ void LLGiveInventory::logInventoryOffer(const LLUUID& to_agent, const LLUUID &im
bool LLGiveInventory::handleCopyProtectedItem(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ LLSD itmes = notification["payload"]["items"];
LLInventoryItem* item = NULL;
switch(option)
{
case 0: // "Yes"
- item = gInventory.getItem(notification["payload"]["item_id"].asUUID());
- if (item)
+ for (LLSD::array_iterator it = itmes.beginArray(); it != itmes.endArray(); it++)
{
- LLGiveInventory::commitGiveInventoryItem(notification["payload"]["agent_id"].asUUID(),
- item);
- // delete it for now - it will be deleted on the server
- // quickly enough.
- gInventory.deleteObject(notification["payload"]["item_id"].asUUID());
- gInventory.notifyObservers();
- }
- else
- {
- LLNotificationsUtil::add("CannotGiveItem");
+ item = gInventory.getItem((*it).asUUID());
+ if (item)
+ {
+ LLGiveInventory::commitGiveInventoryItem(notification["payload"]["agent_id"].asUUID(),
+ item);
+ // delete it for now - it will be deleted on the server
+ // quickly enough.
+ gInventory.deleteObject(item->getUUID());
+ gInventory.notifyObservers();
+ }
+ else
+ {
+ LLNotificationsUtil::add("CannotGiveItem");
+ }
}
break;
diff --git a/indra/newview/llgiveinventory.h b/indra/newview/llgiveinventory.h
index e589a0cc69..86f0f2fe86 100644
--- a/indra/newview/llgiveinventory.h
+++ b/indra/newview/llgiveinventory.h
@@ -61,7 +61,7 @@ public:
/**
* Gives passed inventory item to specified avatar in specified session.
*/
- static void doGiveInventoryItem(const LLUUID& to_agent,
+ static bool doGiveInventoryItem(const LLUUID& to_agent,
const LLInventoryItem* item,
const LLUUID& im_session_id = LLUUID::null);
@@ -72,6 +72,9 @@ public:
const LLInventoryCategory* item,
const LLUUID &session_id = LLUUID::null);
+ // give inventory item functionality
+ static bool handleCopyProtectedItem(const LLSD& notification, const LLSD& response);
+
private:
// this class is not intended to be instantiated.
LLGiveInventory();
@@ -82,8 +85,6 @@ private:
static void logInventoryOffer(const LLUUID& to_agent,
const LLUUID &im_session_id = LLUUID::null);
- // give inventory item functionality
- static bool handleCopyProtectedItem(const LLSD& notification, const LLSD& response);
static void commitGiveInventoryItem(const LLUUID& to_agent,
const LLInventoryItem* item,
const LLUUID &im_session_id = LLUUID::null);
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 577652fc79..b7495f7dbe 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -164,38 +164,7 @@ time_t LLInvFVBridge::getCreationDate() const
// Can be destroyed (or moved to trash)
BOOL LLInvFVBridge::isItemRemovable() const
{
- const LLInventoryModel* model = getInventoryModel();
- if(!model)
- {
- return FALSE;
- }
-
- // Can't delete an item that's in the library.
- if(!model->isObjectDescendentOf(mUUID, gInventory.getRootFolderID()))
- {
- return FALSE;
- }
-
- // Disable delete from COF folder; have users explicitly choose "detach/take off",
- // unless the item is not worn but in the COF (i.e. is bugged).
- if (LLAppearanceMgr::instance().getIsProtectedCOFItem(mUUID))
- {
- if (get_is_item_worn(mUUID))
- {
- return FALSE;
- }
- }
-
- const LLInventoryObject *obj = model->getItem(mUUID);
- if (obj && obj->getIsLinkType())
- {
- return TRUE;
- }
- if (get_is_item_worn(mUUID))
- {
- return FALSE;
- }
- return TRUE;
+ return get_is_item_removable(getInventoryModel(), mUUID);
}
// Can be moved to another folder
@@ -833,24 +802,7 @@ void LLInvFVBridge::changeCategoryParent(LLInventoryModel* model,
const LLUUID& new_parent_id,
BOOL restamp)
{
- // Can't move a folder into a child of itself.
- if (model->isObjectDescendentOf(new_parent_id, cat->getUUID()))
- {
- return;
- }
-
- LLInventoryModel::update_list_t update;
- LLInventoryModel::LLCategoryUpdate old_folder(cat->getParentUUID(), -1);
- update.push_back(old_folder);
- LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1);
- update.push_back(new_folder);
- model->accountForUpdate(update);
-
- LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(cat);
- new_cat->setParent(new_parent_id);
- new_cat->updateParentOnServer(restamp);
- model->updateCategory(new_cat);
- model->notifyObservers();
+ change_category_parent(model, cat, new_parent_id, restamp);
}
LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type,
@@ -1538,26 +1490,7 @@ public:
// Can be destroyed (or moved to trash)
BOOL LLFolderBridge::isItemRemovable() const
{
- LLInventoryModel* model = getInventoryModel();
- if(!model)
- {
- return FALSE;
- }
-
- if(!model->isObjectDescendentOf(mUUID, gInventory.getRootFolderID()))
- {
- return FALSE;
- }
-
- if (!isAgentAvatarValid()) return FALSE;
-
- LLInventoryCategory* category = model->getCategory(mUUID);
- if(!category)
- {
- return FALSE;
- }
-
- if(LLFolderType::lookupIsProtectedType(category->getPreferredType()))
+ if (!get_is_category_removable(getInventoryModel(), mUUID))
{
return FALSE;
}
@@ -1573,6 +1506,7 @@ BOOL LLFolderBridge::isItemRemovable() const
return FALSE;
}
}
+
return TRUE;
}
@@ -2333,10 +2267,20 @@ LLUIImagePtr LLFolderBridge::getIcon(LLFolderType::EType preferred_type, BOOL is
else
return LLUI::getUIImage("Inv_FolderClosed_Link");
}
- if (preferred_type == LLFolderType::FT_OUTFIT)
+
+ switch (preferred_type)
+ {
+ case LLFolderType::FT_OUTFIT:
return LLUI::getUIImage("Inv_LookFolderClosed");
- else
+ case LLFolderType::FT_LOST_AND_FOUND:
+ return LLUI::getUIImage("Inv_LostClosed");
+ case LLFolderType::FT_TRASH:
+ return LLUI::getUIImage("Inv_TrashClosed");
+ case LLFolderType::FT_NONE:
return LLUI::getUIImage("Inv_FolderClosed");
+ default:
+ return LLUI::getUIImage("Inv_SysClosed");
+ }
}
LLUIImagePtr LLFolderBridge::getOpenIcon() const
@@ -2350,29 +2294,27 @@ LLUIImagePtr LLFolderBridge::getOpenIcon() const
else
return LLUI::getUIImage("Inv_FolderOpen_Link");
}
- if (getPreferredType() == LLFolderType::FT_OUTFIT)
+
+ switch (getPreferredType())
+ {
+ case LLFolderType::FT_OUTFIT:
return LLUI::getUIImage("Inv_LookFolderOpen");
- else
+ case LLFolderType::FT_LOST_AND_FOUND:
+ return LLUI::getUIImage("Inv_LostOpen");
+ case LLFolderType::FT_TRASH:
+ return LLUI::getUIImage("Inv_TrashOpen");
+ case LLFolderType::FT_NONE:
return LLUI::getUIImage("Inv_FolderOpen");
+ default:
+ return LLUI::getUIImage("Inv_SysOpen");
+ }
+
}
BOOL LLFolderBridge::renameItem(const std::string& new_name)
{
- if(!isItemRenameable())
- return FALSE;
- LLInventoryModel* model = getInventoryModel();
- if(!model)
- return FALSE;
- LLViewerInventoryCategory* cat = getCategory();
- if(cat && (cat->getName() != new_name))
- {
- LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(cat);
- new_cat->rename(new_name);
- new_cat->updateServer(FALSE);
- model->updateCategory(new_cat);
+ rename_category(getInventoryModel(), mUUID, new_name);
- model->notifyObservers();
- }
// return FALSE because we either notified observers (& therefore
// rebuilt) or we didn't update.
return FALSE;
@@ -2426,36 +2368,7 @@ bool LLFolderBridge::removeItemResponse(const LLSD& notification, const LLSD& re
{
// move it to the trash
LLPreview::hide(mUUID);
- LLInventoryModel* model = getInventoryModel();
- if(!model) return FALSE;
-
- const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
-
- // Look for any gestures and deactivate them
- LLInventoryModel::cat_array_t descendent_categories;
- LLInventoryModel::item_array_t descendent_items;
- gInventory.collectDescendents( mUUID, descendent_categories, descendent_items, FALSE );
-
- for (LLInventoryModel::item_array_t::const_iterator iter = descendent_items.begin();
- iter != descendent_items.end();
- ++iter)
- {
- const LLViewerInventoryItem* item = (*iter);
- const LLUUID& item_id = item->getUUID();
- if (item->getType() == LLAssetType::AT_GESTURE
- && LLGestureMgr::instance().isGestureActive(item_id))
- {
- LLGestureMgr::instance().deactivateGesture(item_id);
- }
- }
-
- // go ahead and do the normal remove if no 'last calling
- // cards' are being removed.
- LLViewerInventoryCategory* cat = getCategory();
- if(cat)
- {
- LLInvFVBridge::changeCategoryParent(model, cat, trash_id, TRUE);
- }
+ remove_category(getInventoryModel(), mUUID);
return TRUE;
}
return FALSE;
@@ -2651,22 +2564,6 @@ BOOL LLFolderBridge::checkFolderForContentsOfType(LLInventoryModel* model, LLInv
return ((item_array.count() > 0) ? TRUE : FALSE );
}
-class LLFindWorn : public LLInventoryCollectFunctor
-{
-public:
- LLFindWorn() {}
- virtual ~LLFindWorn() {}
- virtual bool operator()(LLInventoryCategory* cat,
- LLInventoryItem* item)
- {
- if (item && get_is_item_worn(item->getUUID()))
- {
- return TRUE;
- }
- return FALSE;
- }
-};
-
BOOL LLFolderBridge::areAnyContentsWorn(LLInventoryModel* model) const
{
LLInventoryModel::cat_array_t cat_array;
@@ -2985,22 +2882,7 @@ void LLFolderBridge::createWearable(LLFolderBridge* bridge, LLWearableType::ETyp
{
if(!bridge) return;
LLUUID parent_id = bridge->getUUID();
- createWearable(parent_id, type);
-}
-
-// Separate function so can be called by global menu as well as right-click
-// menu.
-// static
-void LLFolderBridge::createWearable(const LLUUID &parent_id, LLWearableType::EType type)
-{
- LLWearable* wearable = LLWearableList::instance().createNewWearable(type);
- LLAssetType::EType asset_type = wearable->getAssetType();
- LLInventoryType::EType inv_type = LLInventoryType::IT_WEARABLE;
- create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
- parent_id, wearable->getTransactionID(), wearable->getName(),
- wearable->getDescription(), asset_type, inv_type, wearable->getType(),
- wearable->getPermissions().getMaskNextOwner(),
- LLPointer<LLInventoryCallback>(NULL));
+ LLAgentWearables::createWearable(type, false, parent_id);
}
void LLFolderBridge::modifyOutfit(BOOL append)
@@ -4877,13 +4759,7 @@ void LLWearableBridge::onEditOnAvatar(void* user_data)
void LLWearableBridge::editOnAvatar()
{
- LLWearable* wearable = gAgentWearables.getWearableFromItemID(mUUID);
- if( wearable )
- {
- LLPanel * panel = LLSideTray::getInstance()->getPanel("sidepanel_appearance");
-
- LLSidepanelAppearance::editWearable(wearable, panel);
- }
+ LLAgentWearables::editWearable(mUUID);
}
// static
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index c5efefac7e..59c1f3d6fb 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -270,7 +270,6 @@ public:
virtual BOOL copyToClipboard() const;
static void createWearable(LLFolderBridge* bridge, LLWearableType::EType type);
- static void createWearable(const LLUUID &parent_folder_id, LLWearableType::EType type);
LLViewerInventoryCategory* getCategory() const;
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index 0cc4b0e389..817da34c61 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -130,6 +130,90 @@ void change_item_parent(LLInventoryModel* model,
}
}
+void change_category_parent(LLInventoryModel* model,
+ LLViewerInventoryCategory* cat,
+ const LLUUID& new_parent_id,
+ BOOL restamp)
+{
+ if (!model || !cat)
+ {
+ return;
+ }
+
+ // Can't move a folder into a child of itself.
+ if (model->isObjectDescendentOf(new_parent_id, cat->getUUID()))
+ {
+ return;
+ }
+
+ LLInventoryModel::update_list_t update;
+ LLInventoryModel::LLCategoryUpdate old_folder(cat->getParentUUID(), -1);
+ update.push_back(old_folder);
+ LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1);
+ update.push_back(new_folder);
+ model->accountForUpdate(update);
+
+ LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(cat);
+ new_cat->setParent(new_parent_id);
+ new_cat->updateParentOnServer(restamp);
+ model->updateCategory(new_cat);
+ model->notifyObservers();
+}
+
+void remove_category(LLInventoryModel* model, const LLUUID& cat_id)
+{
+ if (!model || !get_is_category_removable(model, cat_id))
+ {
+ return;
+ }
+
+ // Look for any gestures and deactivate them
+ LLInventoryModel::cat_array_t descendent_categories;
+ LLInventoryModel::item_array_t descendent_items;
+ gInventory.collectDescendents(cat_id, descendent_categories, descendent_items, FALSE);
+
+ for (LLInventoryModel::item_array_t::const_iterator iter = descendent_items.begin();
+ iter != descendent_items.end();
+ ++iter)
+ {
+ const LLViewerInventoryItem* item = (*iter);
+ const LLUUID& item_id = item->getUUID();
+ if (item->getType() == LLAssetType::AT_GESTURE
+ && LLGestureMgr::instance().isGestureActive(item_id))
+ {
+ LLGestureMgr::instance().deactivateGesture(item_id);
+ }
+ }
+
+ // go ahead and do the normal remove if no 'last calling
+ // cards' are being removed.
+ LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
+ if (cat)
+ {
+ const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ change_category_parent(model, cat, trash_id, TRUE);
+ }
+}
+
+void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::string& new_name)
+{
+ LLViewerInventoryCategory* cat;
+
+ if (!model ||
+ !get_is_category_renameable(model, cat_id) ||
+ (cat = model->getCategory(cat_id)) == NULL ||
+ cat->getName() == new_name)
+ {
+ return;
+ }
+
+ LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(cat);
+ new_cat->rename(new_name);
+ new_cat->updateServer(FALSE);
+ model->updateCategory(new_cat);
+
+ model->notifyObservers();
+}
BOOL get_is_item_worn(const LLUUID& id)
{
@@ -160,6 +244,83 @@ BOOL get_is_item_worn(const LLUUID& id)
return FALSE;
}
+BOOL get_is_item_removable(const LLInventoryModel* model, const LLUUID& id)
+{
+ if (!model)
+ {
+ return FALSE;
+ }
+
+ // Can't delete an item that's in the library.
+ if (!model->isObjectDescendentOf(id, gInventory.getRootFolderID()))
+ {
+ return FALSE;
+ }
+
+ // Disable delete from COF folder; have users explicitly choose "detach/take off",
+ // unless the item is not worn but in the COF (i.e. is bugged).
+ if (LLAppearanceMgr::instance().getIsProtectedCOFItem(id))
+ {
+ if (get_is_item_worn(id))
+ {
+ return FALSE;
+ }
+ }
+
+ const LLInventoryObject *obj = model->getItem(id);
+ if (obj && obj->getIsLinkType())
+ {
+ return TRUE;
+ }
+ if (get_is_item_worn(id))
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+BOOL get_is_category_removable(const LLInventoryModel* model, const LLUUID& id)
+{
+ // This function doesn't check the folder's children.
+
+ if (!model)
+ {
+ return FALSE;
+ }
+
+ if (!model->isObjectDescendentOf(id, gInventory.getRootFolderID()))
+ {
+ return FALSE;
+ }
+
+ if (!isAgentAvatarValid()) return FALSE;
+
+ LLInventoryCategory* category = model->getCategory(id);
+ if (!category)
+ {
+ return FALSE;
+ }
+
+ if (LLFolderType::lookupIsProtectedType(category->getPreferredType()))
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+BOOL get_is_category_renameable(const LLInventoryModel* model, const LLUUID& id)
+{
+ LLViewerInventoryCategory* cat = model->getCategory(id);
+
+ if (cat && !LLFolderType::lookupIsProtectedType(cat->getPreferredType()) &&
+ cat->getOwnerID() == gAgent.getID())
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
void show_item_profile(const LLUUID& item_uuid)
{
LLUUID linked_uuid = gInventory.getLinkedItemID(item_uuid);
@@ -376,6 +537,26 @@ void LLFindWearablesOfType::setType(LLWearableType::EType type)
mWearableType = type;
}
+bool LLFindWorn::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
+{
+ return item && get_is_item_worn(item->getUUID());
+}
+
+bool LLFindNonRemovableObjects::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
+{
+ if (item)
+ {
+ return !get_is_item_removable(&gInventory, item->getUUID());
+ }
+ if (cat)
+ {
+ return !get_is_category_removable(&gInventory, cat->getUUID());
+ }
+
+ llwarns << "Not a category and not an item?" << llendl;
+ return false;
+}
+
///----------------------------------------------------------------------------
/// LLAssetIDMatches
///----------------------------------------------------------------------------
diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h
index bb365573d7..33b52cfd5e 100644
--- a/indra/newview/llinventoryfunctions.h
+++ b/indra/newview/llinventoryfunctions.h
@@ -46,6 +46,12 @@
// Is this item or its baseitem is worn, attached, etc...
BOOL get_is_item_worn(const LLUUID& id);
+BOOL get_is_item_removable(const LLInventoryModel* model, const LLUUID& id);
+
+BOOL get_is_category_removable(const LLInventoryModel* model, const LLUUID& id);
+
+BOOL get_is_category_renameable(const LLInventoryModel* model, const LLUUID& id);
+
void show_item_profile(const LLUUID& item_uuid);
void show_item_original(const LLUUID& item_uuid);
@@ -55,6 +61,15 @@ void change_item_parent(LLInventoryModel* model,
const LLUUID& new_parent_id,
BOOL restamp);
+void change_category_parent(LLInventoryModel* model,
+ LLViewerInventoryCategory* cat,
+ const LLUUID& new_parent_id,
+ BOOL restamp);
+
+void remove_category(LLInventoryModel* model, const LLUUID& cat_id);
+
+void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::string& new_name);
+
// Generates a string containing the path to the item specified by item_id.
void append_path(const LLUUID& id, std::string& path);
@@ -309,6 +324,22 @@ private:
LLWearableType::EType mWearableType;
};
+// Find worn items.
+class LLFindWorn : public LLInventoryCollectFunctor
+{
+public:
+ LLFindWorn() {}
+ virtual ~LLFindWorn() {}
+ virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item);
+};
+
+// Collect non-removable folders and items.
+class LLFindNonRemovableObjects : public LLInventoryCollectFunctor
+{
+public:
+ virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item);
+};
+
/** Inventory Collector Functions
** **
*******************************************************************************/
diff --git a/indra/newview/llinventoryitemslist.cpp b/indra/newview/llinventoryitemslist.cpp
index 750cdfb678..cd0e976a79 100644
--- a/indra/newview/llinventoryitemslist.cpp
+++ b/indra/newview/llinventoryitemslist.cpp
@@ -132,7 +132,8 @@ BOOL LLPanelInventoryListItemBase::postBuild()
setIconCtrl(getChild<LLIconCtrl>("item_icon"));
setTitleCtrl(getChild<LLTextBox>("item_name"));
- mIconImage = LLInventoryIcon::getIcon(mItem->getType(), mItem->getInventoryType(), mItem->getIsLinkType(), mItem->getFlags(), FALSE);
+ BOOL show_links = mForceNoLinksOnIcons ? FALSE : mItem->getIsLinkType();
+ mIconImage = LLInventoryIcon::getIcon(mItem->getType(), mItem->getInventoryType(), show_links, mItem->getFlags(), FALSE);
setNeedsRefresh(true);
@@ -198,6 +199,7 @@ LLPanelInventoryListItemBase::LLPanelInventoryListItemBase(LLViewerInventoryItem
, mLeftWidgetsWidth(0)
, mRightWidgetsWidth(0)
, mNeedsRefresh(false)
+, mForceNoLinksOnIcons(false)
{
}
diff --git a/indra/newview/llinventoryitemslist.h b/indra/newview/llinventoryitemslist.h
index 807952948b..0dd6f53be7 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:
@@ -176,6 +179,9 @@ protected:
/** Set item title - inventory item name usually */
void setTitle(const std::string& title, const std::string& highlit_text);
+ // force not showing link icon on item's icon
+ bool mForceNoLinksOnIcons;
+
private:
/** reshape left side widgets
diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp
index 0ff6ab2644..b4f0947b2c 100644
--- a/indra/newview/llinventorymodelbackgroundfetch.cpp
+++ b/indra/newview/llinventorymodelbackgroundfetch.cpp
@@ -112,6 +112,8 @@ void LLInventoryModelBackgroundFetch::start(const LLUUID& cat_id, BOOL recursive
{
if (!mAllFoldersFetched)
{
+ LL_DEBUGS("InventoryFetch") << "Start fetching category: " << cat_id << ", recursive: " << recursive << LL_ENDL;
+
mBackgroundFetchActive = TRUE;
if (cat_id.isNull())
{
diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp
index 8557548887..d2b402fe14 100644
--- a/indra/newview/llinventoryobserver.cpp
+++ b/indra/newview/llinventoryobserver.cpp
@@ -68,7 +68,7 @@
// you're fetching an item and a notification gets triggered because
// you renamed some other item). This counter is to specify how many
// notification to wait for before giving up.
-static const U32 MAX_NUM_NOTIFICATIONS_TO_PROCESS = 20;
+static const U32 MAX_NUM_NOTIFICATIONS_TO_PROCESS = 127;
LLInventoryObserver::LLInventoryObserver()
{
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 4766c1c227..bb3f34dde2 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -49,6 +49,7 @@
#include "llsidepanelinventory.h"
#include "llsidetray.h"
#include "llscrollcontainer.h"
+#include "llviewerattachmenu.h"
#include "llviewerfoldertype.h"
#include "llvoavatarself.h"
@@ -877,48 +878,19 @@ bool LLInventoryPanel::beginIMSession()
bool LLInventoryPanel::attachObject(const LLSD& userdata)
{
+ // Copy selected item UUIDs to a vector.
std::set<LLUUID> selected_items = mFolderRoot->getSelectionList();
-
- std::string joint_name = userdata.asString();
- LLViewerJointAttachment* attachmentp = NULL;
- for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
- iter != gAgentAvatarp->mAttachmentPoints.end(); )
- {
- LLVOAvatar::attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
- if (attachment->getName() == joint_name)
- {
- attachmentp = attachment;
- break;
- }
- }
- if (attachmentp == NULL)
- {
- return true;
- }
-
+ uuid_vec_t items;
for (std::set<LLUUID>::const_iterator set_iter = selected_items.begin();
set_iter != selected_items.end();
++set_iter)
{
- const LLUUID &id = *set_iter;
- LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(id);
- if(item && gInventory.isObjectDescendentOf(id, gInventory.getRootFolderID()))
- {
- rez_attachment(item, attachmentp);
- }
- else if(item && item->isFinished())
- {
- // must be in library. copy it to our inventory and put it on.
- LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(attachmentp);
- copy_inventory_item(gAgent.getID(),
- item->getPermissions().getOwner(),
- item->getUUID(),
- LLUUID::null,
- std::string(),
- cb);
- }
+ items.push_back(*set_iter);
}
+
+ // Attach selected items.
+ LLViewerAttachMenu::attachObjects(items, userdata.asString());
+
gFocusMgr.setKeyboardFocus(NULL);
return true;
diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp
index 251c60b5bf..e5548007bd 100644
--- a/indra/newview/llnavigationbar.cpp
+++ b/indra/newview/llnavigationbar.cpp
@@ -713,6 +713,7 @@ void LLNavigationBar::onNavigationButtonHeldUp(LLButton* nav_button)
void LLNavigationBar::handleLoginComplete()
{
+ LLTeleportHistory::getInstance()->handleLoginComplete();
mCmbLocation->handleLoginComplete();
}
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..77db280487 100644
--- a/indra/newview/lloutfitslist.cpp
+++ b/indra/newview/lloutfitslist.cpp
@@ -43,12 +43,16 @@
#include "llinventoryfunctions.h"
#include "llinventorymodel.h"
#include "lllistcontextmenu.h"
+#include "llnotificationsutil.h"
+#include "llsidetray.h"
#include "lltransutil.h"
#include "llviewermenu.h"
#include "llvoavatar.h"
#include "llvoavatarself.h"
#include "llwearableitemslist.h"
+static bool is_tab_header_clicked(LLAccordionCtrlTab* tab, S32 y);
+
//////////////////////////////////////////////////////////////////////////
class OutfitContextMenu : public LLListContextMenu
@@ -66,12 +70,63 @@ protected:
boost::bind(&LLAppearanceMgr::addCategoryToCurrentOutfit, &LLAppearanceMgr::instance(), selected_id));
registrar.add("Outfit.TakeOff",
boost::bind(&LLAppearanceMgr::takeOffOutfit, &LLAppearanceMgr::instance(), selected_id));
- // *TODO: implement this
- // registrar.add("Outfit.Rename", boost::bind());
- // registrar.add("Outfit.Delete", boost::bind());
+ registrar.add("Outfit.Edit", boost::bind(editOutfit));
+ registrar.add("Outfit.Rename", boost::bind(renameOutfit, selected_id));
+ registrar.add("Outfit.Delete", boost::bind(deleteOutfit, selected_id));
+
+ enable_registrar.add("Outfit.OnEnable", boost::bind(&OutfitContextMenu::onEnable, this, _2));
return createFromFile("menu_outfit_tab.xml");
}
+
+ bool onEnable(const LLSD& data)
+ {
+ std::string param = data.asString();
+ LLUUID outfit_cat_id = mUUIDs.back();
+ bool is_worn = LLAppearanceMgr::instance().getBaseOutfitUUID() == outfit_cat_id;
+
+ if ("wear_replace" == param)
+ {
+ return !is_worn;
+ }
+ else if ("wear_add" == param)
+ {
+ return !is_worn;
+ }
+ else if ("take_off" == param)
+ {
+ return is_worn;
+ }
+ else if ("edit" == param)
+ {
+ return is_worn;
+ }
+ else if ("rename" == param)
+ {
+ return get_is_category_renameable(&gInventory, outfit_cat_id);
+ }
+ else if ("delete" == param)
+ {
+ return LLAppearanceMgr::instance().getCanRemoveOutfit(outfit_cat_id);
+ }
+
+ return true;
+ }
+
+ static void editOutfit()
+ {
+ LLSideTray::getInstance()->showPanel("sidepanel_appearance", LLSD().with("type", "edit_outfit"));
+ }
+
+ static void renameOutfit(const LLUUID& outfit_cat_id)
+ {
+ LLAppearanceMgr::instance().renameOutfit(outfit_cat_id);
+ }
+
+ static void deleteOutfit(const LLUUID& outfit_cat_id)
+ {
+ remove_category(&gInventory, outfit_cat_id);
+ }
};
//////////////////////////////////////////////////////////////////////////
@@ -82,12 +137,9 @@ LLOutfitsList::LLOutfitsList()
: LLPanel()
, mAccordion(NULL)
, mListCommands(NULL)
- , mSelectedList(NULL)
+ , mIsInitialized(false)
{
mCategoriesObserver = new LLInventoryCategoriesObserver();
- gInventory.addObserver(mCategoriesObserver);
-
- gInventory.addObserver(this);
mOutfitMenu = new OutfitContextMenu();
}
@@ -101,11 +153,6 @@ LLOutfitsList::~LLOutfitsList()
gInventory.removeObserver(mCategoriesObserver);
delete mCategoriesObserver;
}
-
- if (gInventory.containsObserver(this))
- {
- gInventory.removeObserver(this);
- }
}
BOOL LLOutfitsList::postBuild()
@@ -116,32 +163,36 @@ BOOL LLOutfitsList::postBuild()
}
//virtual
-void LLOutfitsList::changed(U32 mask)
+void LLOutfitsList::onOpen(const LLSD& /*info*/)
{
- if (!gInventory.isInventoryUsable())
- return;
+ if (!mIsInitialized)
+ {
+ // *TODO: I'm not sure is this check necessary but it never match while developing.
+ if (!gInventory.isInventoryUsable())
+ return;
- const LLUUID outfits = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
- LLViewerInventoryCategory* category = gInventory.getCategory(outfits);
- if (!category)
- return;
+ const LLUUID outfits = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
+
+ // *TODO: I'm not sure is this check necessary but it never match while developing.
+ LLViewerInventoryCategory* category = gInventory.getCategory(outfits);
+ if (!category)
+ return;
+
+ gInventory.addObserver(mCategoriesObserver);
- // Start observing changes in "My Outfits" category.
- mCategoriesObserver->addCategory(outfits,
+ // Start observing changes in "My Outfits" category.
+ mCategoriesObserver->addCategory(outfits,
boost::bind(&LLOutfitsList::refreshList, this, outfits));
- // 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
- // arrive.
- category->fetch();
- refreshList(outfits);
-
- // This observer is used to start the initial outfits fetch
- // when inventory becomes usable. It is no longer needed because
- // "My Outfits" category is now observed by
- // LLInventoryCategoriesObserver.
- gInventory.removeObserver(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
+ // arrive.
+ category->fetch();
+ refreshList(outfits);
+
+ mIsInitialized = true;
+ }
}
void LLOutfitsList::refreshList(const LLUUID& category_id)
@@ -177,8 +228,6 @@ void LLOutfitsList::refreshList(const LLUUID& category_id)
static LLXMLNodePtr accordionXmlNode = getAccordionTabXMLNode();
LLAccordionCtrlTab* tab = LLUICtrlFactory::defaultBuilder<LLAccordionCtrlTab>(accordionXmlNode, NULL, NULL);
- tab->setRightMouseDownCallback(boost::bind(&LLOutfitsList::onAccordionTabRightClick, this,
- _1, _2, _3, cat_id));
tab->setName(name);
tab->setTitle(name);
@@ -199,6 +248,12 @@ void LLOutfitsList::refreshList(const LLUUID& category_id)
// Map the new tab with outfit category UUID.
mOutfitsMap.insert(LLOutfitsList::outfits_map_value_t(cat_id, tab));
+ tab->setRightMouseDownCallback(boost::bind(&LLOutfitsList::onAccordionTabRightClick, this,
+ _1, _2, _3, cat_id));
+
+ tab->setDoubleClickCallback(boost::bind(&LLOutfitsList::onAccordionTabDoubleClick, this,
+ _1, _2, _3, cat_id));
+
// Setting tab focus callback to monitor currently selected outfit.
tab->setFocusReceivedCallback(boost::bind(&LLOutfitsList::changeOutfitSelection, this, list, cat_id));
@@ -208,6 +263,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 +294,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 +344,8 @@ void LLOutfitsList::onSelectionChange(LLUICtrl* ctrl)
void LLOutfitsList::performAction(std::string action)
{
+ if (mSelectedOutfitUUID.isNull()) return;
+
LLViewerInventoryCategory* cat = gInventory.getCategory(mSelectedOutfitUUID);
if (!cat) return;
@@ -294,6 +357,10 @@ void LLOutfitsList::performAction(std::string action)
{
LLAppearanceMgr::instance().wearInventoryCategory( cat, FALSE, TRUE );
}
+ else if ("rename_outfit" == action)
+ {
+ LLAppearanceMgr::instance().renameOutfit(mSelectedOutfitUUID);
+ }
}
void LLOutfitsList::setFilterSubString(const std::string& string)
@@ -367,14 +434,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;
}
@@ -405,6 +486,10 @@ void LLOutfitsList::onFilteredWearableItemsListRefresh(LLUICtrl* ctrl)
// hide tab if its title doesn't pass filter
// and it has no visible items
tab->setVisible(list->size() != 0);
+
+ // remove title highlighting because it might
+ // have been previously highlighted by less restrictive filter
+ tab->setTitle(tab->getTitle());
}
else
{
@@ -457,6 +542,10 @@ void LLOutfitsList::applyFilter(const std::string& new_filter_substring)
// hide tab if its title doesn't pass filter
// and it has no visible items
tab->setVisible(list->size() != 0);
+
+ // remove title highlighting because it might
+ // have been previously highlighted by less restrictive filter
+ tab->setTitle(tab->getTitle());
}
else
{
@@ -489,16 +578,62 @@ void LLOutfitsList::applyFilter(const std::string& new_filter_substring)
void LLOutfitsList::onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id)
{
LLAccordionCtrlTab* tab = dynamic_cast<LLAccordionCtrlTab*>(ctrl);
- if(mOutfitMenu && tab && tab->getHeaderVisible() && cat_id.notNull())
+ if(mOutfitMenu && is_tab_header_clicked(tab, y) && cat_id.notNull())
{
- 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)
{
- uuid_vec_t selected_uuids;
- selected_uuids.push_back(cat_id);
- mOutfitMenu->show(ctrl, selected_uuids, x, y);
+ header->setFocus(TRUE);
}
+
+ uuid_vec_t selected_uuids;
+ selected_uuids.push_back(cat_id);
+ mOutfitMenu->show(ctrl, selected_uuids, x, y);
}
}
+void LLOutfitsList::onAccordionTabDoubleClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id)
+{
+ LLAccordionCtrlTab* tab = dynamic_cast<LLAccordionCtrlTab*>(ctrl);
+ if(is_tab_header_clicked(tab, y) && cat_id.notNull())
+ {
+ LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
+ if (!cat) return;
+
+ LLAppearanceMgr::instance().wearInventoryCategory( cat, FALSE, FALSE );
+ }
+}
+
+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);
+}
+
+bool is_tab_header_clicked(LLAccordionCtrlTab* tab, S32 y)
+{
+ if(!tab || !tab->getHeaderVisible()) return false;
+
+ S32 header_bottom = tab->getLocalRect().getHeight() - tab->getHeaderHeight();
+ return y >= header_bottom;
+}
+
// EOF
diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h
index b6b3d6ae46..44f6ec908b 100644
--- a/indra/newview/lloutfitslist.h
+++ b/indra/newview/lloutfitslist.h
@@ -49,12 +49,10 @@ class LLListContextMenu;
* A list of agents's outfits from "My Outfits" inventory category
* which displays each outfit in an accordion tab with a flat list
* of items inside it.
- * Uses LLInventoryCategoriesObserver to monitor changes to "My Outfits"
- * inventory category and refresh the outfits listed in it.
- * This class is derived from LLInventoryObserver to know when inventory
- * becomes usable and it is safe to request data from inventory model.
+ *
+ * Starts fetching nevessary inventory content on first openning.
*/
-class LLOutfitsList : public LLPanel, public LLInventoryObserver
+class LLOutfitsList : public LLPanel
{
public:
LLOutfitsList();
@@ -62,16 +60,16 @@ public:
/*virtual*/ BOOL postBuild();
- /*virtual*/ void changed(U32 mask);
+ /*virtual*/ void onOpen(const LLSD& info);
void refreshList(const LLUUID& category_id);
- void onSelectionChange(LLUICtrl* ctrl);
-
void performAction(std::string action);
void setFilterSubString(const std::string& string);
+ const LLUUID& getSelectedOutfitUUID() const { return mSelectedOutfitUUID; }
+
private:
/**
* Reads xml with accordion tab and Flat list from xml file.
@@ -107,13 +105,22 @@ private:
void applyFilter(const std::string& new_filter_substring);
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 onSelectionChange(LLUICtrl* ctrl);
+
+ static void onOutfitRename(const LLSD& notification, const LLSD& response);
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;
@@ -123,6 +130,8 @@ private:
outfits_map_t mOutfitsMap;
LLListContextMenu* mOutfitMenu;
+
+ bool mIsInitialized;
};
#endif //LL_LLOUTFITSLIST_H
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index 4bf4f9eac1..7fb46fc84f 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -221,8 +221,6 @@ BOOL LLLandmarksPanel::postBuild()
// mast be called before any other initXXX methods to init Gear menu
initListCommandsHandlers();
- U32 sort_order = gSavedSettings.getU32(LLInventoryPanel::DEFAULT_SORT_ORDER);
- mSortByDate = sort_order & LLInventoryFilter::SO_DATE;
initFavoritesInventoryPanel();
initLandmarksInventoryPanel();
initMyInventoryPanel();
@@ -607,7 +605,8 @@ void LLLandmarksPanel::initLandmarksPanel(LLPlacesInventoryPanel* inventory_list
inventory_list->setSelectCallback(boost::bind(&LLLandmarksPanel::onSelectionChange, this, inventory_list, _1, _2));
inventory_list->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
- updateSortOrder(inventory_list, mSortByDate);
+ bool sorting_order = gSavedSettings.getBOOL("LandmarksSortedByDate");
+ updateSortOrder(inventory_list, sorting_order);
LLPlacesFolderView* root_folder = dynamic_cast<LLPlacesFolderView*>(inventory_list->getRootFolder());
if (root_folder)
@@ -875,10 +874,12 @@ void LLLandmarksPanel::onFoldingAction(const LLSD& userdata)
}
else if ("sort_by_date" == command_name)
{
- mSortByDate = !mSortByDate;
- updateSortOrder(mLandmarksInventoryPanel, mSortByDate);
- updateSortOrder(mMyInventoryPanel, mSortByDate);
- updateSortOrder(mLibraryInventoryPanel, mSortByDate);
+ bool sorting_order = gSavedSettings.getBOOL("LandmarksSortedByDate");
+ sorting_order=!sorting_order;
+ gSavedSettings.setBOOL("LandmarksSortedByDate",sorting_order);
+ updateSortOrder(mLandmarksInventoryPanel, sorting_order);
+ updateSortOrder(mMyInventoryPanel, sorting_order);
+ updateSortOrder(mLibraryInventoryPanel, sorting_order);
}
else
{
@@ -895,7 +896,8 @@ bool LLLandmarksPanel::isActionChecked(const LLSD& userdata) const
if ( "sort_by_date" == command_name)
{
- return mSortByDate;
+ bool sorting_order = gSavedSettings.getBOOL("LandmarksSortedByDate");
+ return sorting_order;
}
return false;
diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h
index 8f8d9c2708..0e70c72f11 100644
--- a/indra/newview/llpanellandmarks.h
+++ b/indra/newview/llpanellandmarks.h
@@ -167,7 +167,6 @@ private:
LLInventoryObserver* mInventoryObserver;
LLPanel* mListCommands;
- bool mSortByDate;
typedef std::vector<LLAccordionCtrlTab*> accordion_tabs_t;
accordion_tabs_t mAccordionTabs;
diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index c1dfd7d13b..4982e98f8e 100644
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -79,6 +79,70 @@ const U64 ALL_ITEMS_MASK = WEARABLE_MASK | ATTACHMENT_MASK;
static const std::string REVERT_BTN("revert_btn");
+class LLPanelOutfitEditGearMenu
+{
+public:
+ static LLMenuGL* create()
+ {
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+
+ registrar.add("Wearable.Create", boost::bind(onCreate, _2));
+
+ LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>(
+ "menu_cof_gear.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance());
+ llassert(menu);
+ if (menu)
+ {
+ populateCreateWearableSubmenus(menu);
+ menu->buildDrawLabels();
+ }
+
+ return menu;
+ }
+
+private:
+ static void onCreate(const LLSD& param)
+ {
+ LLWearableType::EType type = LLWearableType::typeNameToType(param.asString());
+ if (type == LLWearableType::WT_NONE)
+ {
+ llwarns << "Invalid wearable type" << llendl;
+ return;
+ }
+
+ LLAgentWearables::createWearable(type, true);
+ }
+
+ // Populate the menu with items like "New Skin", "New Pants", etc.
+ static void populateCreateWearableSubmenus(LLMenuGL* menu)
+ {
+ LLView* menu_clothes = gMenuHolder->findChildView("COF.Gear.New_Clothes", FALSE);
+ LLView* menu_bp = gMenuHolder->findChildView("COF.Geear.New_Body_Parts", FALSE);
+
+ if (!menu_clothes || !menu_bp)
+ {
+ llassert(menu_clothes && menu_bp);
+ return;
+ }
+
+ for (U8 i = LLWearableType::WT_SHAPE; i != (U8) LLWearableType::WT_COUNT; ++i)
+ {
+ LLWearableType::EType type = (LLWearableType::EType) i;
+ const std::string& type_name = LLWearableType::getTypeName(type);
+
+ LLMenuItemCallGL::Params p;
+ p.name = type_name;
+ p.label = LLWearableType::getTypeDefaultNewName(type);
+ p.on_click.function_name = "Wearable.Create";
+ p.on_click.parameter = LLSD(type_name);
+
+ LLView* parent = LLWearableType::getAssetType(type) == LLAssetType::AT_CLOTHING ?
+ menu_clothes : menu_bp;
+ LLUICtrlFactory::create<LLMenuItemCallGL>(p, parent);
+ }
+ }
+};
+
class LLCOFObserver : public LLInventoryObserver
{
public:
@@ -263,7 +327,6 @@ BOOL LLPanelOutfitEdit::postBuild()
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");
@@ -275,8 +338,6 @@ BOOL LLPanelOutfitEdit::postBuild()
mCOFWearables->getCOFCallbacks().mMoveWearableCloser = boost::bind(&LLPanelOutfitEdit::moveWearable, this, true);
mCOFWearables->getCOFCallbacks().mMoveWearableFurther = boost::bind(&LLPanelOutfitEdit::moveWearable, this, false);
- mCOFWearables->childSetAction("add_btn", boost::bind(&LLPanelOutfitEdit::toggleAddWearablesPanel, this));
-
mAddWearablesPanel = getChild<LLPanel>("add_wearables_panel");
mInventoryItemsPanel = getChild<LLInventoryPanel>("inventory_items");
@@ -298,7 +359,8 @@ BOOL LLPanelOutfitEdit::postBuild()
mSearchFilter = getChild<LLFilterEditor>("look_item_filter");
mSearchFilter->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onSearchEdit, this, _2));
-
+
+ childSetAction("show_add_wearables_btn", boost::bind(&LLPanelOutfitEdit::toggleAddWearablesPanel, this));
childSetAction("add_to_outfit_btn", boost::bind(&LLPanelOutfitEdit::onAddToOutfitClicked, this));
mEditWearableBtn = getChild<LLButton>("edit_wearable_btn");
@@ -313,7 +375,6 @@ BOOL LLPanelOutfitEdit::postBuild()
mWearableItemsPanel = getChild<LLPanel>("filtered_wearables_panel");
mWearableItemsList = getChild<LLInventoryItemsList>("filtered_wearables_list");
- mWearableListManager = new LLFilteredWearableListManager(mWearableItemsList, mWearableListMaskCollector);
mSaveComboBtn.reset(new LLSaveOutfitComboBtn(this));
return TRUE;
@@ -324,6 +385,10 @@ void LLPanelOutfitEdit::onOpen(const LLSD& key)
{
if (!mInitialized)
{
+ // *TODO: this method is called even panel is not visible to user because its parent layout panel is hidden.
+ // So, we can defer initializing a bit.
+ mWearableListManager = new LLFilteredWearableListManager(mWearableItemsList, mWearableListMaskCollector);
+ mWearableListManager->populateList();
displayCurrentOutfit();
mInitialized = true;
}
@@ -341,7 +406,28 @@ void LLPanelOutfitEdit::moveWearable(bool closer_to_body)
void LLPanelOutfitEdit::toggleAddWearablesPanel()
{
BOOL current_visibility = mAddWearablesPanel->getVisible();
- mAddWearablesPanel->setVisible(!current_visibility);
+ showAddWearablesPanel(!current_visibility);
+}
+
+void LLPanelOutfitEdit::showAddWearablesPanel(bool show_add_wearables)
+{
+ mAddWearablesPanel->setVisible(show_add_wearables);
+
+ childSetValue("show_add_wearables_btn", show_add_wearables);
+
+ childSetVisible("filter_wearables_combobox", show_add_wearables);
+ childSetVisible("filter_button", show_add_wearables);
+
+ //search filter should be disabled
+ if (!show_add_wearables)
+ {
+ childSetValue("filter_button", false);
+ showWearablesFilter();
+ }
+
+ //switching button bars
+ childSetVisible("no_add_wearables_button_bar", !show_add_wearables);
+ childSetVisible("add_wearables_button_bar", show_add_wearables);
}
void LLPanelOutfitEdit::showWearablesFilter()
@@ -700,34 +786,18 @@ void LLPanelOutfitEdit::onGearButtonClick(LLUICtrl* clicked_button)
{
if(!mGearMenu)
{
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-
- registrar.add("Gear.OnClick", boost::bind(&LLPanelOutfitEdit::onGearMenuItemClick, this, _2));
-
- mGearMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>(
- "menu_cof_gear.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance());
- mGearMenu->buildDrawLabels();
- mGearMenu->updateParent(LLMenuGL::sMenuContainer);
+ mGearMenu = LLPanelOutfitEditGearMenu::create();
}
S32 menu_y = mGearMenu->getRect().getHeight() + clicked_button->getRect().getHeight();
LLMenuGL::showPopup(clicked_button, mGearMenu, 0, menu_y);
}
-void LLPanelOutfitEdit::onGearMenuItemClick(const LLSD& data)
-{
- std::string param = data.asString();
- if("add" == param)
- {
- // TODO
- }
-}
-
void LLPanelOutfitEdit::showFilteredWearableItemsList(LLWearableType::EType type)
{
mWearableListTypeCollector->setType(type);
mWearableListManager->setFilterCollector(mWearableListTypeCollector);
- mAddWearablesPanel->setVisible(TRUE);
+ showAddWearablesPanel(true);
showFilteredWearablesPanel();
}
diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h
index c0ee6c5fcb..802386c573 100644
--- a/indra/newview/llpaneloutfitedit.h
+++ b/indra/newview/llpaneloutfitedit.h
@@ -93,6 +93,7 @@ public:
void moveWearable(bool closer_to_body);
void toggleAddWearablesPanel();
+ void showAddWearablesPanel(bool show__add_wearables);
void showWearablesFilter();
void showFilteredWearablesPanel();
void showFilteredFolderWearablesPanel();
@@ -131,7 +132,6 @@ public:
private:
void onGearButtonClick(LLUICtrl* clicked_button);
- void onGearMenuItemClick(const LLSD& data);
void showFilteredWearableItemsList(LLWearableType::EType type);
diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp
index 21f69d3470..5f67f3d989 100644
--- a/indra/newview/llpaneloutfitsinventory.cpp
+++ b/indra/newview/llpaneloutfitsinventory.cpp
@@ -42,6 +42,7 @@
#include "llfloaterworldmap.h"
#include "llfloaterinventory.h"
#include "llfoldervieweventlistener.h"
+#include "llinventorybridge.h"
#include "llinventoryfunctions.h"
#include "llinventorymodelbackgroundfetch.h"
#include "llinventorypanel.h"
@@ -70,11 +71,134 @@ static const std::string COF_TAB_NAME = "cof_tab";
static LLRegisterPanelClassWrapper<LLPanelOutfitsInventory> t_inventory("panel_outfits_inventory");
+class LLOutfitListGearMenu
+{
+public:
+ LLOutfitListGearMenu(LLOutfitsList* olist)
+ : mOutfitList(olist),
+ mMenu(NULL)
+ {
+ llassert_always(mOutfitList);
+
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+ LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
+
+ registrar.add("Gear.Wear", boost::bind(&LLOutfitListGearMenu::onWear, this));
+ registrar.add("Gear.TakeOff", boost::bind(&LLOutfitListGearMenu::onTakeOff, this));
+ registrar.add("Gear.Rename", boost::bind(&LLOutfitListGearMenu::onRename, this));
+ registrar.add("Gear.Delete", boost::bind(&LLOutfitListGearMenu::onDelete, this));
+ registrar.add("Gear.Create", boost::bind(&LLOutfitListGearMenu::onCreate, this, _2));
+
+ enable_registrar.add("Gear.OnEnable", boost::bind(&LLOutfitListGearMenu::onEnable, this, _2));
+
+ mMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>(
+ "menu_outfit_gear.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ llassert(mMenu);
+ }
+
+ LLMenuGL* getMenu() { return mMenu; }
+
+private:
+ const LLUUID& getSelectedOutfitID()
+ {
+ return mOutfitList->getSelectedOutfitUUID();
+ }
+
+ LLViewerInventoryCategory* getSelectedOutfit()
+ {
+ const LLUUID& selected_outfit_id = getSelectedOutfitID();
+ if (selected_outfit_id.isNull())
+ {
+ return NULL;
+ }
+
+ LLViewerInventoryCategory* cat = gInventory.getCategory(selected_outfit_id);
+ return cat;
+ }
+
+ void onWear()
+ {
+ LLViewerInventoryCategory* selected_outfit = getSelectedOutfit();
+ if (selected_outfit)
+ {
+ LLAppearanceMgr::instance().wearInventoryCategory(
+ selected_outfit, /*copy=*/ FALSE, /*append=*/ FALSE);
+ }
+ }
+
+ void onTakeOff()
+ {
+ const LLUUID& selected_outfit_id = getSelectedOutfitID();
+ if (selected_outfit_id.notNull())
+ {
+ LLAppearanceMgr::instance().takeOffOutfit(selected_outfit_id);
+ }
+ }
+
+ void onRename()
+ {
+ const LLUUID& selected_outfit_id = getSelectedOutfitID();
+ if (selected_outfit_id.notNull())
+ {
+ LLAppearanceMgr::instance().renameOutfit(selected_outfit_id);
+ }
+ }
+
+ void onDelete()
+ {
+ const LLUUID& selected_outfit_id = getSelectedOutfitID();
+ if (selected_outfit_id.notNull())
+ {
+ remove_category(&gInventory, selected_outfit_id);
+ }
+ }
+
+ void onCreate(const LLSD& data)
+ {
+ LLWearableType::EType type = LLWearableType::typeNameToType(data.asString());
+ if (type == LLWearableType::WT_NONE)
+ {
+ llwarns << "Invalid wearable type" << llendl;
+ return;
+ }
+
+ LLAgentWearables::createWearable(type, true);
+ }
+
+ bool onEnable(LLSD::String param)
+ {
+ const LLUUID& selected_outfit_id = getSelectedOutfitID();
+ bool is_worn = LLAppearanceMgr::instance().getBaseOutfitUUID() == selected_outfit_id;
+
+ if ("wear" == param)
+ {
+ return !is_worn;
+ }
+ else if ("take_off" == param)
+ {
+ return is_worn;
+ }
+ else if ("rename" == param)
+ {
+ return get_is_category_renameable(&gInventory, selected_outfit_id);
+ }
+ else if ("delete" == param)
+ {
+ return LLAppearanceMgr::instance().getCanRemoveOutfit(selected_outfit_id);
+ }
+
+ return true;
+ }
+
+ LLOutfitsList* mOutfitList;
+ LLMenuGL* mMenu;
+};
LLPanelOutfitsInventory::LLPanelOutfitsInventory() :
mMyOutfitsPanel(NULL),
mCurrentOutfitPanel(NULL),
mParent(NULL),
+ mGearMenu(NULL),
mInitialized(false)
{
mSavedFolderState = new LLSaveFolderState();
@@ -84,6 +208,7 @@ LLPanelOutfitsInventory::LLPanelOutfitsInventory() :
LLPanelOutfitsInventory::~LLPanelOutfitsInventory()
{
+ delete mGearMenu;
delete mSavedFolderState;
}
@@ -374,7 +499,7 @@ void LLPanelOutfitsInventory::initListCommandsHandlers()
{
mListCommands = getChild<LLPanel>("bottom_panel");
- mListCommands->childSetAction("options_gear_btn", boost::bind(&LLPanelOutfitsInventory::onGearButtonClick, this));
+ mListCommands->childSetAction("options_gear_btn", boost::bind(&LLPanelOutfitsInventory::showGearMenu, this));
mListCommands->childSetAction("trash_btn", boost::bind(&LLPanelOutfitsInventory::onTrashButtonClick, this));
mListCommands->childSetAction("wear_btn", boost::bind(&LLPanelOutfitsInventory::onWearButtonClick, this));
@@ -385,8 +510,7 @@ void LLPanelOutfitsInventory::initListCommandsHandlers()
, _7 // EAcceptance* accept
));
- mMenuGearDefault = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_outfit_gear.xml",
- gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ mGearMenu = new LLOutfitListGearMenu(mMyOutfitsPanel);
}
void LLPanelOutfitsInventory::updateListCommands()
@@ -401,18 +525,14 @@ void LLPanelOutfitsInventory::updateListCommands()
mSaveComboBtn->setSaveBtnEnabled(make_outfit_enabled);
}
-void LLPanelOutfitsInventory::onGearButtonClick()
-{
- showActionMenu(mMenuGearDefault,"options_gear_btn");
-}
-
-void LLPanelOutfitsInventory::showActionMenu(LLMenuGL* menu, std::string spawning_view_name)
+void LLPanelOutfitsInventory::showGearMenu()
{
+ LLMenuGL* menu = mGearMenu ? mGearMenu->getMenu() : NULL;
if (menu)
{
menu->buildDrawLabels();
menu->updateParent(LLMenuGL::sMenuContainer);
- LLView* spawning_view = getChild<LLView> (spawning_view_name);
+ LLView* spawning_view = getChild<LLView>("options_gear_btn");
S32 menu_x, menu_y;
//show menu in co-ordinates of panel
spawning_view->localPointToOtherView(0, spawning_view->getRect().getHeight(), &menu_x, &menu_y, this);
@@ -632,6 +752,7 @@ void LLPanelOutfitsInventory::onTabChange()
else
{
mMyOutfitsPanel->setFilterSubString(mFilterSubString);
+ mMyOutfitsPanel->onOpen(LLSD());
}
updateVerbs();
diff --git a/indra/newview/llpaneloutfitsinventory.h b/indra/newview/llpaneloutfitsinventory.h
index 7bdd37c16c..aff7839bcc 100644
--- a/indra/newview/llpaneloutfitsinventory.h
+++ b/indra/newview/llpaneloutfitsinventory.h
@@ -47,6 +47,7 @@ class LLMenuGL;
class LLSidepanelAppearance;
class LLTabContainer;
class LLSaveOutfitComboBtn;
+class LLOutfitListGearMenu;
class LLPanelOutfitsInventory : public LLPanel
{
@@ -116,9 +117,8 @@ private:
protected:
void initListCommandsHandlers();
void updateListCommands();
- void onGearButtonClick();
void onWearButtonClick();
- void showActionMenu(LLMenuGL* menu, std::string spawning_view_name);
+ void showGearMenu();
void onTrashButtonClick();
void onClipboardAction(const LLSD& userdata);
BOOL isActionEnabled(const LLSD& command_name);
@@ -129,7 +129,7 @@ protected:
void onWearablesLoaded();
private:
LLPanel* mListCommands;
- LLMenuGL* mMenuGearDefault;
+ LLOutfitListGearMenu* mGearMenu;
LLMenuGL* mMenuAdd;
// List Commands //
////////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index 4f0946774a..f020ad9bc2 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -827,7 +827,8 @@ void LLParticipantList::LLParticipantListMenu::moderateVoiceAllParticipants(bool
void LLParticipantList::LLParticipantListMenu::confirmMuteAllCallback(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- if (option != 1)
+ // if Cancel pressed
+ if (option == 1)
{
return;
}
diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp
index 9159f42968..3c97f01887 100644
--- a/indra/newview/llsidetray.cpp
+++ b/indra/newview/llsidetray.cpp
@@ -66,21 +66,6 @@ static const std::string TAB_PANEL_CAPTION_TITLE_BOX = "sidetray_tab_title";
LLSideTray* LLSideTray::sInstance = 0;
-/**
- * Updates visibility of sidetray tabs buttons according to "SidebarWithButtonsVisibility" setting
- *
- * @param force_set_visible if true method ignores setting value and set buttons visible.
- */
-static void update_tabs_buttons_visibility(bool force_set_visible = false)
-{
- LLView* side_bar_tabs = gViewerWindow->getRootView()->getChildView("side_bar_tabs");
- if (side_bar_tabs)
- {
- BOOL visible = LLUI::sSettingGroups["config"]->getBOOL("SidebarWithButtonsVisibility");
- side_bar_tabs->setVisible(force_set_visible || visible);
- }
-}
-
LLSideTray* LLSideTray::getInstance()
{
if (!sInstance)
@@ -273,8 +258,6 @@ LLSideTray::LLSideTray(Params& params)
p.name = "buttons_panel";
p.mouse_opaque = false;
mButtonsPanel = LLUICtrlFactory::create<LLPanel>(p);
-
- initControlSettings();
}
@@ -563,8 +546,6 @@ void LLSideTray::collapseSideBar()
//mActiveTab->setVisible(FALSE);
reflectCollapseChange();
setFocus( FALSE );
-
- update_tabs_buttons_visibility();
}
void LLSideTray::expandSideBar()
@@ -589,8 +570,6 @@ void LLSideTray::expandSideBar()
LLButton* btn = btn_it->second;
btn->setImageOverlay( mActiveTab->mImageSelected );
}
-
- update_tabs_buttons_visibility(true);
}
void LLSideTray::highlightFocused()
@@ -658,8 +637,6 @@ LLPanel* LLSideTray::showPanel (const std::string& panel_name, const LLSD& para
panel->onOpen(params);
}
- update_tabs_buttons_visibility(true);
-
return panel;
}
}
@@ -751,35 +728,3 @@ void LLSideTray::updateSidetrayVisibility()
}
}
-void LLSideTray::initControlSettings()
-{
- // set listeners to process runtime setting changes
- LLUI::sSettingGroups["config"]->getControl("SidebarWithButtonsVisibility")->getSignal()->connect(boost::bind(&LLSideTray::toggleSidetrayAndTabButtonsVisibility, this, _2));
-
- // update visibility according to current value
- toggleSidetrayAndTabButtonsVisibility(LLUI::sSettingGroups["config"]->getBOOL("SidebarWithButtonsVisibility"));
-}
-
-// sidebar visibility is implemented via its expanding/collapsing
-void LLSideTray::toggleSidetrayAndTabButtonsVisibility(const LLSD::Boolean& new_visibility)
-{
- // If new_visibility==FALSE it gets invisible but still can be expanded in other ways (Ctrl+I to see My Inventory)
-
- // store collapsed state to restore it properly on next call
- static bool was_collapsed = false;
-
- if (!new_visibility && !mCollapsed)
- {
- collapseSideBar();
- was_collapsed = true;
- }
- // should be visible: expand only if it was expanded when has been collapsed on previous call
- else if (new_visibility && was_collapsed)
- {
- if (mCollapsed) expandSideBar();
- was_collapsed = false;
- }
-
- update_tabs_buttons_visibility(new_visibility);
-}
-
diff --git a/indra/newview/llsidetray.h b/indra/newview/llsidetray.h
index ed6b376d5c..e8fdee9430 100644
--- a/indra/newview/llsidetray.h
+++ b/indra/newview/llsidetray.h
@@ -179,16 +179,6 @@ private:
LLSideTray::getInstance()->setEnabled(FALSE);
}
- /**
- * Initializes listener of SidebarWithButtonsVisibility setting and updates state according to it.
- */
- void initControlSettings();
-
- /**
- * Updates Sidebar and its Tab Buttons visibility according to passed value.
- */
- void toggleSidetrayAndTabButtonsVisibility(const LLSD::Boolean& new_visibility);
-
private:
LLPanel* mButtonsPanel;
diff --git a/indra/newview/llteleporthistory.cpp b/indra/newview/llteleporthistory.cpp
index 15684337f4..cac3b58464 100644
--- a/indra/newview/llteleporthistory.cpp
+++ b/indra/newview/llteleporthistory.cpp
@@ -38,6 +38,7 @@
#include "llsdserialize.h"
#include "llagent.h"
+#include "llvoavatarself.h"
#include "llslurl.h"
#include "llviewercontrol.h" // for gSavedSettings
#include "llviewerparcelmgr.h"
@@ -108,6 +109,16 @@ void LLTeleportHistory::onTeleportFailed()
}
}
+void LLTeleportHistory::handleLoginComplete()
+{
+ if( mGotInitialUpdate )
+ {
+ return;
+ }
+ updateCurrentLocation(gAgent.getPositionGlobal());
+}
+
+
void LLTeleportHistory::updateCurrentLocation(const LLVector3d& new_pos)
{
if (mRequestedItem != -1) // teleport within the history in progress?
@@ -117,6 +128,17 @@ void LLTeleportHistory::updateCurrentLocation(const LLVector3d& new_pos)
}
else
{
+ //EXT-7034
+ //skip initial update if agent avatar is no valid yet
+ //this may happen when updateCurrentLocation called while login process
+ //sometimes isAgentAvatarValid return false and in this case new_pos
+ //(which actually is gAgent.getPositionGlobal() ) is invalid
+ //if this position will be saved then teleport back will teleport user to wrong position
+ if ( !mGotInitialUpdate && !isAgentAvatarValid() )
+ {
+ return ;
+ }
+
// If we're getting the initial location update
// while we already have a (loaded) non-empty history,
// there's no need to purge forward items or add a new item.
diff --git a/indra/newview/llteleporthistory.h b/indra/newview/llteleporthistory.h
index a82bec7c4f..e035451e71 100644
--- a/indra/newview/llteleporthistory.h
+++ b/indra/newview/llteleporthistory.h
@@ -136,6 +136,10 @@ public:
* @see load()
*/
void dump() const;
+ /**
+ * Process login complete event. Basically put current location into history
+ */
+ void handleLoginComplete();
private:
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 8a8bdd2dba..bc77ac5fd1 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -48,7 +48,7 @@
#include "llgiveinventory.h"
#include "llhudmanager.h"
#include "llhudeffecttrail.h"
-//#include "llimview.h"
+#include "llimview.h"
#include "llinventorybridge.h"
#include "llinventorydefines.h"
#include "llinventoryfunctions.h"
@@ -1422,12 +1422,42 @@ EAcceptance LLToolDragAndDrop::willObjectAcceptInventory(LLViewerObject* obj, LL
}
+static void give_inventory_cb(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ // if Cancel pressed
+ if (option == 1)
+ {
+ return;
+ }
+
+ LLSD payload = notification["payload"];
+ const LLUUID& session_id = payload["session_id"];
+ const LLUUID& agent_id = payload["agent_id"];
+ LLViewerInventoryItem * inv_item = gInventory.getItem(payload["item_id"]);
+ if (NULL == inv_item)
+ {
+ llassert(NULL != inv_item);
+ return;
+ }
+
+ if (LLGiveInventory::doGiveInventoryItem(agent_id, inv_item, session_id))
+ {
+ if ("avatarpicker" == payload["d&d_dest"].asString())
+ {
+ LLFloaterReg::hideInstance("avatar_picker");
+ }
+ LLNotificationsUtil::add("ItemsShared");
+ }
+}
+
// function used as drag-and-drop handler for simple agent give inventory requests
//static
bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_id, BOOL drop,
EDragAndDropType cargo_type,
void* cargo_data,
- EAcceptance* accept)
+ EAcceptance* accept,
+ const LLSD& dest)
{
// check the type
switch(cargo_type)
@@ -1452,7 +1482,21 @@ bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_
*accept = ACCEPT_YES_COPY_SINGLE;
if (drop)
{
- LLGiveInventory::doGiveInventoryItem(dest_agent, inv_item, session_id);
+ LLIMModel::LLIMSession * session = LLIMModel::instance().findIMSession(session_id);
+ if (NULL == session)
+ {
+ llassert(NULL != session);
+ return false;
+ }
+ LLSD substitutions;
+ substitutions["RESIDENTS"] = session->mName;
+ substitutions["ITEMS"] = inv_item->getName();
+ LLSD payload;
+ payload["agent_id"] = dest_agent;
+ payload["item_id"] = inv_item->getUUID();
+ payload["session_id"] = session_id;
+ payload["d&d_dest"] = dest.asString();
+ LLNotificationsUtil::add("ShareItemsConfirmation", substitutions, payload, &give_inventory_cb);
}
}
else
diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h
index 18334b5ee1..36e69c1db3 100644
--- a/indra/newview/lltooldraganddrop.h
+++ b/indra/newview/lltooldraganddrop.h
@@ -246,7 +246,8 @@ public:
static bool handleGiveDragAndDrop(LLUUID agent, LLUUID session, BOOL drop,
EDragAndDropType cargo_type,
void* cargo_data,
- EAcceptance* accept);
+ EAcceptance* accept,
+ const LLSD& dest = LLSD());
// Classes used for determining 3d drag and drop types.
private:
diff --git a/indra/newview/llviewerattachmenu.cpp b/indra/newview/llviewerattachmenu.cpp
new file mode 100644
index 0000000000..f7f5ec72fd
--- /dev/null
+++ b/indra/newview/llviewerattachmenu.cpp
@@ -0,0 +1,139 @@
+/**
+ * @file llviewerattachmenu.cpp
+ * @brief "Attach to" / "Attach to HUD" submenus.
+ *
+ * $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 "llviewerattachmenu.h"
+
+// project includes
+#include "llagent.h"
+#include "llinventorybridge.h" // for rez_attachment()
+#include "llinventorymodel.h"
+#include "llviewerinventory.h"
+#include "llviewermenu.h" // for gMenuHolder
+#include "llvoavatarself.h"
+
+// linden libraries
+#include "llmenugl.h"
+#include "lltrans.h"
+
+// static
+void LLViewerAttachMenu::populateMenus(const std::string& attach_to_menu_name, const std::string& attach_to_hud_menu_name)
+{
+ // *TODO: share this code with other similar menus
+ // (inventory panel context menu, in-world object menu).
+
+ if (attach_to_menu_name.empty() || attach_to_hud_menu_name.empty() || !isAgentAvatarValid()) return;
+
+ LLContextMenu* attach_menu = gMenuHolder->getChild<LLContextMenu>(attach_to_menu_name);
+ LLContextMenu* attach_hud_menu = gMenuHolder->getChild<LLContextMenu>(attach_to_hud_menu_name);
+
+ if (!attach_menu || attach_menu->getChildCount() != 0 ||
+ !attach_hud_menu || attach_hud_menu->getChildCount() != 0)
+ {
+ return;
+ }
+
+ // Populate "Attach to..." / "Attach to HUD..." submenus.
+ for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
+ iter != gAgentAvatarp->mAttachmentPoints.end(); )
+ {
+ LLVOAvatar::attachment_map_t::iterator curiter = iter++;
+ LLViewerJointAttachment* attachment = curiter->second;
+ LLMenuItemCallGL::Params p;
+ std::string submenu_name = attachment->getName();
+ std::string translated_submenu_name;
+
+ if (LLTrans::findString(translated_submenu_name, submenu_name))
+ {
+ p.name = (" ") + translated_submenu_name + " ";
+ }
+ else
+ {
+ p.name = submenu_name;
+ }
+
+ LLSD cbparams;
+ cbparams["index"] = curiter->first;
+ cbparams["label"] = attachment->getName();
+ p.on_click.function_name = "Object.Attach";
+ p.on_click.parameter = LLSD(attachment->getName());
+ p.on_enable.function_name = "Attachment.Label";
+ p.on_enable.parameter = cbparams;
+
+ LLMenuItemCallGL* item = LLUICtrlFactory::create<LLMenuItemCallGL>(p);
+ LLView* parent_menu = attachment->getIsHUDAttachment() ? attach_hud_menu : attach_menu;
+ parent_menu->addChild(item);
+ }
+}
+
+// static
+void LLViewerAttachMenu::attachObjects(const uuid_vec_t& items, const std::string& joint_name)
+{
+ LLViewerJointAttachment* attachmentp = NULL;
+ for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
+ iter != gAgentAvatarp->mAttachmentPoints.end(); )
+ {
+ LLVOAvatar::attachment_map_t::iterator curiter = iter++;
+ LLViewerJointAttachment* attachment = curiter->second;
+ if (attachment->getName() == joint_name)
+ {
+ attachmentp = attachment;
+ break;
+ }
+ }
+ if (attachmentp == NULL)
+ {
+ return;
+ }
+
+ for (uuid_vec_t::const_iterator it = items.begin(); it != items.end(); ++it)
+ {
+ const LLUUID &id = *it;
+ LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getLinkedItem(id);
+ if(item && gInventory.isObjectDescendentOf(id, gInventory.getRootFolderID()))
+ {
+ rez_attachment(item, attachmentp);
+ }
+ else if(item && item->isFinished())
+ {
+ // must be in library. copy it to our inventory and put it on.
+ LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(attachmentp);
+ copy_inventory_item(gAgent.getID(),
+ item->getPermissions().getOwner(),
+ item->getUUID(),
+ LLUUID::null,
+ std::string(),
+ cb);
+ }
+ }
+}
diff --git a/indra/newview/llviewerattachmenu.h b/indra/newview/llviewerattachmenu.h
new file mode 100644
index 0000000000..d1db9914f3
--- /dev/null
+++ b/indra/newview/llviewerattachmenu.h
@@ -0,0 +1,43 @@
+/**
+ * @file llviewerattachmenu.h
+ * @brief "Attach to" / "Attach to HUD" submenus.
+ *
+ * $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_LLVIEWERATTACHMENU_H
+#define LL_LLVIEWERATTACHMENU_H
+
+class LLViewerAttachMenu
+{
+public:
+ static void populateMenus(const std::string& attach_to_menu_name, const std::string& attach_to_hud_menu_name);
+ static void attachObjects(const uuid_vec_t& items, const std::string& joint_name);
+};
+
+#endif // LL_LLVIEWERATTACHMENU_H
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index e2be49e4cc..d745356dcd 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -39,6 +39,7 @@
#include "llagent.h"
#include "llagentcamera.h"
+#include "llagentwearables.h"
#include "llviewerfoldertype.h"
#include "llfolderview.h"
#include "llviewercontrol.h"
@@ -119,10 +120,10 @@ public:
mInventoryItemsDict["Male - Wow"] = LLTrans::getString("Male - Wow");
//female
- mInventoryItemsDict["FeMale - Excuse me"] = LLTrans::getString("FeMale - Excuse me");
- mInventoryItemsDict["FeMale - Get lost"] = LLTrans::getString("FeMale - Get lost");
- mInventoryItemsDict["FeMale - Blow kiss"] = LLTrans::getString("FeMale - Blow kiss");
- mInventoryItemsDict["FeMale - Boo"] = LLTrans::getString("FeMale - Boo");
+ mInventoryItemsDict["Female - Excuse me"] = LLTrans::getString("Female - Excuse me");
+ mInventoryItemsDict["Female - Get lost"] = LLTrans::getString("Female - Get lost");
+ mInventoryItemsDict["Female - Blow kiss"] = LLTrans::getString("Female - Blow kiss");
+ mInventoryItemsDict["Female - Boo"] = LLTrans::getString("Female - Boo");
mInventoryItemsDict["Female - Bored"] = LLTrans::getString("Female - Bored");
mInventoryItemsDict["Female - Hey"] = LLTrans::getString("Female - Hey");
mInventoryItemsDict["Female - Laugh"] = LLTrans::getString("Female - Laugh");
@@ -606,6 +607,7 @@ bool LLViewerInventoryCategory::fetch()
if((VERSION_UNKNOWN == mVersion)
&& mDescendentsRequested.hasExpired()) //Expired check prevents multiple downloads.
{
+ LL_DEBUGS("InventoryFetch") << "Fetching category children: " << mName << ", UUID: " << mUUID << LL_ENDL;
const F32 FETCH_TIMER_EXPIRY = 10.0f;
mDescendentsRequested.reset();
mDescendentsRequested.setTimerExpirySec(FETCH_TIMER_EXPIRY);
@@ -880,6 +882,14 @@ void WearOnAvatarCallback::fire(const LLUUID& inv_item)
void ModifiedCOFCallback::fire(const LLUUID& inv_item)
{
LLAppearanceMgr::instance().updateAppearanceFromCOF();
+
+ if (LLSideTray::getInstance()->isPanelActive("sidepanel_appearance"))
+ {
+ // *HACK: Edit the wearable that has just been worn
+ // only if the Appearance SP is currently opened.
+ LLAgentWearables::editWearable(inv_item);
+ }
+
// TODO: camera mode may not be changed if a debug setting is tweaked
if( gAgentCamera.cameraCustomizeAvatar() )
{
@@ -1240,10 +1250,8 @@ void menu_create_inventory_item(LLFolderView* root, LLFolderBridge *bridge, cons
LLWearableType::EType wearable_type = LLWearableType::typeNameToType(type_name);
if (wearable_type >= LLWearableType::WT_SHAPE && wearable_type < LLWearableType::WT_COUNT)
{
- LLAssetType::EType asset_type = LLWearableType::getAssetType(wearable_type);
- LLFolderType::EType folder_type = LLFolderType::assetTypeToFolderType(asset_type);
- const LLUUID parent_id = bridge ? bridge->getUUID() : gInventory.findCategoryUUIDForType(folder_type);
- LLFolderBridge::createWearable(parent_id, wearable_type);
+ const LLUUID parent_id = bridge ? bridge->getUUID() : LLUUID::null;
+ LLAgentWearables::createWearable(wearable_type, false, parent_id);
}
else
{
diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp
index 161cd40cfc..ba1d0b727d 100644
--- a/indra/newview/llwearableitemslist.cpp
+++ b/indra/newview/llwearableitemslist.cpp
@@ -41,6 +41,7 @@
#include "llinventorymodel.h"
#include "llmenugl.h" // for LLContextMenu
#include "lltransutil.h"
+#include "llviewerattachmenu.h"
class LLFindOutfitItems : public LLInventoryCollectFunctor
{
@@ -87,6 +88,49 @@ void LLPanelWearableListItem::onMouseLeave(S32 x, S32 y, MASK mask)
LLPanelWearableListItem::LLPanelWearableListItem(LLViewerInventoryItem* item)
: LLPanelInventoryListItemBase(item)
{
+ // icons should not be shown for this type of items (EXT-7511)
+ mForceNoLinksOnIcons = true;
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+// static
+LLPanelWearableOutfitItem* LLPanelWearableOutfitItem::create(LLViewerInventoryItem* item)
+{
+ LLPanelWearableOutfitItem* list_item = NULL;
+ if (item)
+ {
+ list_item = new LLPanelWearableOutfitItem(item);
+ list_item->init();
+ }
+ return list_item;
+}
+
+BOOL LLPanelWearableOutfitItem::handleDoubleClick(S32 x, S32 y, MASK mask)
+{
+ LLViewerInventoryItem* item = getItem();
+ if (item)
+ {
+ LLUUID id = item->getUUID();
+
+ if (get_is_item_worn(id))
+ {
+ LLAppearanceMgr::getInstance()->removeItemFromAvatar(id);
+ }
+ else
+ {
+ LLAppearanceMgr::getInstance()->wearItemOnAvatar(id, true, false);
+ }
+ }
+
+ return LLUICtrl::handleDoubleClick(x, y, mask);
+}
+
+LLPanelWearableOutfitItem::LLPanelWearableOutfitItem(LLViewerInventoryItem* item)
+: LLPanelInventoryListItemBase(item)
+{
}
//////////////////////////////////////////////////////////////////////////
@@ -126,7 +170,7 @@ BOOL LLPanelClothingListItem::postBuild()
addWidgetToRightSide("btn_move_up");
addWidgetToRightSide("btn_move_down");
addWidgetToRightSide("btn_lock");
- addWidgetToRightSide("btn_edit");
+ addWidgetToRightSide("btn_edit_panel");
setWidgetsVisible(false);
reshapeWidgets();
@@ -169,7 +213,7 @@ BOOL LLPanelBodyPartsListItem::postBuild()
LLPanelInventoryListItemBase::postBuild();
addWidgetToRightSide("btn_lock");
- addWidgetToRightSide("btn_edit");
+ addWidgetToRightSide("btn_edit_panel");
return TRUE;
}
@@ -402,6 +446,27 @@ LLWearableItemsList::LLWearableItemsList(const LLWearableItemsList::Params& p)
LLWearableItemsList::~LLWearableItemsList()
{}
+// virtual
+void LLWearableItemsList::addNewItem(LLViewerInventoryItem* item, bool rearrange /*= true*/)
+{
+ if (!item)
+ {
+ llwarns << "No inventory item. Couldn't create flat list item." << llendl;
+ llassert(item != NULL);
+ }
+
+ LLPanelWearableOutfitItem *list_item = LLPanelWearableOutfitItem::create(item);
+ if (!list_item)
+ return;
+
+ bool is_item_added = addItem(list_item, item->getUUID(), ADD_BOTTOM, rearrange);
+ if (!is_item_added)
+ {
+ llwarns << "Couldn't add flat list item." << llendl;
+ llassert(is_item_added);
+ }
+}
+
void LLWearableItemsList::updateList(const LLUUID& category_id)
{
LLInventoryModel::cat_array_t cat_array;
@@ -449,7 +514,9 @@ LLContextMenu* LLWearableItemsList::ContextMenu::createMenu()
// Register handlers common for all wearable types.
registrar.add("Wearable.Wear", boost::bind(handleMultiple, wear, ids));
registrar.add("Wearable.Edit", boost::bind(handleMultiple, LLAgentWearables::editWearable, ids));
+ registrar.add("Wearable.CreateNew", boost::bind(createNewWearable, selected_id));
registrar.add("Wearable.ShowOriginal", boost::bind(show_item_original, selected_id));
+ registrar.add("Wearable.TakeOffDetach", boost::bind(handleMultiple, take_off, ids));
// Register handlers for clothing.
registrar.add("Clothing.TakeOff", boost::bind(handleMultiple, take_off, ids));
@@ -459,12 +526,16 @@ LLContextMenu* LLWearableItemsList::ContextMenu::createMenu()
// Register handlers for attachments.
registrar.add("Attachment.Detach", boost::bind(handleMultiple, take_off, ids));
registrar.add("Attachment.Profile", boost::bind(show_item_profile, selected_id));
+ registrar.add("Object.Attach", boost::bind(LLViewerAttachMenu::attachObjects, ids, _2));
// Create the menu.
LLContextMenu* menu = createFromFile("menu_wearable_list_item.xml");
// Determine which items should be visible/enabled.
updateItemsVisibility(menu);
+
+ // Update labels for the items requiring that.
+ updateItemsLabels(menu);
return menu;
}
@@ -478,10 +549,10 @@ void LLWearableItemsList::ContextMenu::updateItemsVisibility(LLContextMenu* menu
const uuid_vec_t& ids = mUUIDs; // selected items IDs
U32 mask = 0; // mask of selected items' types
- U32 nitems = ids.size(); // number of selected items
- U32 nworn = 0; // number of worn items among the selected ones
- U32 nwornlinks = 0; // number of worn links among the selected items
- U32 neditable = 0; // number of editable items among the selected ones
+ U32 n_items = ids.size(); // number of selected items
+ U32 n_worn = 0; // number of worn items among the selected ones
+ U32 n_links = 0; // number of links among the selected items
+ U32 n_editable = 0; // number of editable items among the selected ones
for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it)
{
@@ -503,38 +574,82 @@ void LLWearableItemsList::ContextMenu::updateItemsVisibility(LLContextMenu* menu
if (is_worn)
{
- ++nworn;
-
- if (is_link)
- {
- ++nwornlinks;
- }
+ ++n_worn;
}
if (is_editable)
{
- ++neditable;
+ ++n_editable;
+ }
+ if (is_link)
+ {
+ ++n_links;
}
} // for
// *TODO: eliminate multiple traversals over the menu items
- // *TODO: try disabling items rather than hiding them
- // *FIX: we may hide *all* items and thus get an ugly empty menu
- setMenuItemVisible(menu, "wear", nworn == 0);
- setMenuItemVisible(menu, "edit", mask & (MASK_CLOTHING|MASK_BODYPART) && nitems == 1 && neditable == 1);
- setMenuItemVisible(menu, "show_original", nitems == 1 && nwornlinks == nitems);
- setMenuItemVisible(menu, "take_off", mask == MASK_CLOTHING && nworn == nitems); // selected only worn clothes
- setMenuItemVisible(menu, "detach", mask == MASK_ATTACHMENT && nworn == nitems);
- setMenuItemVisible(menu, "object_profile", mask == MASK_ATTACHMENT && nitems == 1);
+ setMenuItemVisible(menu, "wear", n_worn == 0);
+ setMenuItemVisible(menu, "edit", mask & (MASK_CLOTHING|MASK_BODYPART) && n_items == 1);
+ setMenuItemEnabled(menu, "edit", n_editable == 1 && n_worn == 1);
+ setMenuItemVisible(menu, "create_new", mask & (MASK_CLOTHING|MASK_BODYPART) && n_items == 1);
+ setMenuItemEnabled(menu, "show_original", n_items == 1 && n_links == n_items);
+ setMenuItemVisible(menu, "take_off", mask == MASK_CLOTHING && n_worn == n_items);
+ setMenuItemVisible(menu, "detach", mask == MASK_ATTACHMENT && n_worn == n_items);
+ setMenuItemVisible(menu, "take_off_or_detach", mask == (MASK_ATTACHMENT|MASK_CLOTHING));
+ setMenuItemEnabled(menu, "take_off_or_detach", n_worn == n_items);
+ setMenuItemVisible(menu, "object_profile", mask & (MASK_ATTACHMENT|MASK_CLOTHING));
+ setMenuItemEnabled(menu, "object_profile", n_items == 1);
+
+ // Populate or hide the "Attach to..." / "Attach to HUD..." submenus.
+ if (mask == MASK_ATTACHMENT && n_worn == 0)
+ {
+ LLViewerAttachMenu::populateMenus("wearable_attach_to", "wearable_attach_to_hud");
+ }
+ else
+ {
+ setMenuItemVisible(menu, "wearable_attach_to", false);
+ setMenuItemVisible(menu, "wearable_attach_to_hud", false);
+ }
+
+ if (mask & MASK_UNKNOWN)
+ {
+ llwarns << "Non-wearable items passed." << llendl;
+ }
+}
+
+void LLWearableItemsList::ContextMenu::updateItemsLabels(LLContextMenu* menu)
+{
+ llassert(menu);
+ if (!menu) return;
+
+ // Set proper label for the "Create new <WEARABLE_TYPE>" menu item.
+ LLViewerInventoryItem* item = gInventory.getLinkedItem(mUUIDs.back());
+ if (!item || !item->isWearableType()) return;
+
+ LLStringUtil::format_map_t args;
+ LLWearableType::EType w_type = item->getWearableType();
+ args["[WEARABLE_TYPE]"] = LLWearableType::getTypeDefaultNewName(w_type);
+ std::string new_label = LLTrans::getString("CreateNewWearable", args);
+
+ LLMenuItemGL* menu_item = menu->getChild<LLMenuItemGL>("create_new");
+ menu_item->setLabel(new_label);
}
// We need this method to convert non-zero BOOL values to exactly 1 (TRUE).
// Otherwise code relying on a BOOL value being TRUE may fail
// (I experienced a weird assert in LLView::drawChildren() because of that.
+// static
void LLWearableItemsList::ContextMenu::setMenuItemVisible(LLContextMenu* menu, const std::string& name, bool val)
{
menu->setItemVisible(name, val);
}
+// static
+void LLWearableItemsList::ContextMenu::setMenuItemEnabled(LLContextMenu* menu, const std::string& name, bool val)
+{
+ menu->setItemEnabled(name, val);
+}
+
+// static
void LLWearableItemsList::ContextMenu::updateMask(U32& mask, LLAssetType::EType at)
{
if (at == LLAssetType::AT_CLOTHING)
@@ -551,8 +666,17 @@ void LLWearableItemsList::ContextMenu::updateMask(U32& mask, LLAssetType::EType
}
else
{
- llwarns << "Unsupported asset type: " << at << llendl;
+ mask |= MASK_UNKNOWN;
}
}
+// static
+void LLWearableItemsList::ContextMenu::createNewWearable(const LLUUID& item_id)
+{
+ LLViewerInventoryItem* item = gInventory.getLinkedItem(item_id);
+ if (!item || !item->isWearableType()) return;
+
+ LLAgentWearables::createWearable(item->getWearableType(), true);
+}
+
// EOF
diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h
index de024ed220..2fdb8f0ab8 100644
--- a/indra/newview/llwearableitemslist.h
+++ b/indra/newview/llwearableitemslist.h
@@ -70,6 +70,29 @@ protected:
LLPanelWearableListItem(LLViewerInventoryItem* item);
};
+/**
+ * @class LLPanelWearableOutfitItem
+ *
+ * Outfit item for "My Outfits" list.
+ * Extends LLPanelInventoryListItemBase with handling
+ * double click to wear the item.
+ */
+class LLPanelWearableOutfitItem : public LLPanelInventoryListItemBase
+{
+ LOG_CLASS(LLPanelWearableOutfitItem);
+public:
+ static LLPanelWearableOutfitItem* create(LLViewerInventoryItem* item);
+
+ /**
+ * Puts item on if it is not worn by agent
+ * otherwise takes it off on double click.
+ */
+ /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
+
+protected:
+
+ LLPanelWearableOutfitItem(LLViewerInventoryItem* item);
+};
class LLPanelDeletableWearableListItem : public LLPanelWearableListItem
{
@@ -116,7 +139,7 @@ public:
inline void setShowMoveDownButton(bool show) { setShowWidget("btn_move_down", show); }
inline void setShowLockButton(bool show) { setShowWidget("btn_lock", show); }
- inline void setShowEditButton(bool show) { setShowWidget("btn_edit", show); }
+ inline void setShowEditButton(bool show) { setShowWidget("btn_edit_panel", show); }
protected:
@@ -141,7 +164,7 @@ public:
* Make button visible during mouse over event.
*/
inline void setShowLockButton(bool show) { setShowWidget("btn_lock", show); }
- inline void setShowEditButton(bool show) { setShowWidget("btn_edit", show); }
+ inline void setShowEditButton(bool show) { setShowWidget("btn_edit_panel", show); }
protected:
LLPanelBodyPartsListItem(LLViewerInventoryItem* item);
@@ -292,12 +315,16 @@ public:
MASK_CLOTHING = 0x01,
MASK_BODYPART = 0x02,
MASK_ATTACHMENT = 0x04,
+ MASK_UNKNOWN = 0x08,
};
/* virtual */ LLContextMenu* createMenu();
void updateItemsVisibility(LLContextMenu* menu);
- void setMenuItemVisible(LLContextMenu* menu, const std::string& name, bool val);
- void updateMask(U32& mask, LLAssetType::EType at);
+ void updateItemsLabels(LLContextMenu* menu);
+ static void setMenuItemVisible(LLContextMenu* menu, const std::string& name, bool val);
+ static void setMenuItemEnabled(LLContextMenu* menu, const std::string& name, bool val);
+ static void updateMask(U32& mask, LLAssetType::EType at);
+ static void createNewWearable(const LLUUID& item_id);
};
struct Params : public LLInitParam::Block<Params, LLInventoryItemsList::Params>
@@ -309,6 +336,8 @@ public:
virtual ~LLWearableItemsList();
+ /*virtual*/ void addNewItem(LLViewerInventoryItem* item, bool rearrange = true);
+
void updateList(const LLUUID& category_id);
protected:
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/icons/Inv_LostClosed.png b/indra/newview/skins/default/textures/icons/Inv_LostClosed.png
new file mode 100644
index 0000000000..a800217e0d
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Inv_LostClosed.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_LostOpen.png b/indra/newview/skins/default/textures/icons/Inv_LostOpen.png
new file mode 100644
index 0000000000..8c4a1a9ac0
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Inv_LostOpen.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_SysClosed.png b/indra/newview/skins/default/textures/icons/Inv_SysClosed.png
new file mode 100644
index 0000000000..dcf998449f
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Inv_SysClosed.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_SysOpen.png b/indra/newview/skins/default/textures/icons/Inv_SysOpen.png
new file mode 100644
index 0000000000..0efd403c95
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Inv_SysOpen.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_TrashClosed.png b/indra/newview/skins/default/textures/icons/Inv_TrashClosed.png
new file mode 100644
index 0000000000..c5201e6f9a
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Inv_TrashClosed.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_TrashOpen.png b/indra/newview/skins/default/textures/icons/Inv_TrashOpen.png
new file mode 100644
index 0000000000..4a886a3f37
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Inv_TrashOpen.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/back_arrow_off.png b/indra/newview/skins/default/textures/icons/back_arrow_off.png
new file mode 100644
index 0000000000..422f67cf83
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/back_arrow_off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/back_arrow_over.png b/indra/newview/skins/default/textures/icons/back_arrow_over.png
new file mode 100644
index 0000000000..b4cc170f37
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/back_arrow_over.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/back_arrow_press.png b/indra/newview/skins/default/textures/icons/back_arrow_press.png
new file mode 100644
index 0000000000..a9e2f326a7
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/back_arrow_press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 29c72a414b..4b781dee8c 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -67,6 +67,10 @@ with the same filename but different name
<texture name="Avaline_Icon" file_name="icons/avaline_default_icon.jpg" preload="true" />
<texture name="BackArrow_Off" file_name="icons/BackArrow_Off.png" preload="false" />
+
+ <texture name="BackButton_Off" file_name="icons/back_arrow_off.png" preload="false" />
+ <texture name="BackButton_Over" file_name="icons/back_arrow_over.png" preload="false" />
+ <texture name="BackButton_Press" file_name="icons/back_arrow_press.png" preload="false" />
<texture name="Blank" file_name="Blank.png" preload="false" />
@@ -203,6 +207,8 @@ with the same filename but different name
<texture name="Inv_Jacket" file_name="icons/Inv_Jacket.png" preload="false" />
<texture name="Inv_LookFolderOpen" file_name="icons/Inv_LookFolderOpen.png" preload="false" />
<texture name="Inv_LookFolderClosed" file_name="icons/Inv_LookFolderClosed.png" preload="false" />
+ <texture name="Inv_LostClosed" file_name="icons/Inv_LostClosed.png" preload="false" />
+ <texture name="Inv_LostOpen" file_name="icons/Inv_LostOpen.png" preload="false" />
<texture name="Inv_Landmark" file_name="icons/Inv_Landmark.png" preload="false" />
<texture name="Inv_Notecard" file_name="icons/Inv_Notecard.png" preload="false" />
<texture name="Inv_Object" file_name="icons/Inv_Object.png" preload="false" />
@@ -216,8 +222,12 @@ with the same filename but different name
<texture name="Inv_Snapshot" file_name="icons/Inv_Snapshot.png" preload="false" />
<texture name="Inv_Socks" file_name="icons/Inv_Socks.png" preload="false" />
<texture name="Inv_Sound" file_name="icons/Inv_Sound.png" preload="false" />
+ <texture name="Inv_SysClosed" file_name="icons/Inv_SysClosed.png" preload="false" />
+ <texture name="Inv_SysOpen" file_name="icons/Inv_SysOpen.png" preload="false" />
<texture name="Inv_Tattoo" file_name="icons/Inv_Tattoo.png" preload="false" />
<texture name="Inv_Texture" file_name="icons/Inv_Texture.png" preload="false" />
+ <texture name="Inv_TrashClosed" file_name="icons/Inv_TrashClosed.png" preload="false" />
+ <texture name="Inv_TrashOpen" file_name="icons/Inv_TrashOpen.png" preload="false" />
<texture name="Inv_Underpants" file_name="icons/Inv_Underpants.png" preload="false" />
<texture name="Inv_Undershirt" file_name="icons/Inv_Undershirt.png" preload="false" />
@@ -527,15 +537,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" />
@@ -557,6 +570,8 @@ with the same filename but different name
<texture name="VoicePTT_Off" file_name="bottomtray/VoicePTT_Off.png" preload="false" />
<texture name="VoicePTT_On" file_name="bottomtray/VoicePTT_On.png" preload="false" />
+ <texture name="Wearables_Divider" file_name="windows/Wearables_Divider.png" preload="false" />
+
<texture name="WellButton_Lit" file_name="bottomtray/WellButton_Lit.png" preload="true" scale.left="4" scale.top="19" scale.right="28" scale.bottom="4" />
<texture name="WellButton_Lit_Selected" file_name="bottomtray/WellButton_Lit_Selected.png" preload="true" scale.left="4" scale.top="19" scale.right="28" scale.bottom="4" />
diff --git a/indra/newview/skins/default/textures/windows/Wearables_Divider.png b/indra/newview/skins/default/textures/windows/Wearables_Divider.png
new file mode 100644
index 0000000000..9dce7bf45c
--- /dev/null
+++ b/indra/newview/skins/default/textures/windows/Wearables_Divider.png
Binary files differ
diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml
index 5f28fa6495..54ef6d65a7 100644
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -756,7 +756,7 @@ Leyla Linden </text>
mouse_opaque="false"
name="resellable_clause"
word_wrap="true"
- width="330">
+ width="360">
Land in this region may not be resold.
</text>
<text
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_map.xml b/indra/newview/skins/default/xui/en/floater_map.xml
index 249b091800..a0e28f7a42 100644
--- a/indra/newview/skins/default/xui/en/floater_map.xml
+++ b/indra/newview/skins/default/xui/en/floater_map.xml
@@ -5,7 +5,7 @@
can_minimize="true"
can_resize="true"
follows="top|right"
- height="218"
+ height="174"
layout="topleft"
min_height="174"
min_width="174"
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_bottomtray.xml b/indra/newview/skins/default/xui/en/menu_bottomtray.xml
index ccd5388621..5beafef4e4 100644
--- a/indra/newview/skins/default/xui/en/menu_bottomtray.xml
+++ b/indra/newview/skins/default/xui/en/menu_bottomtray.xml
@@ -53,17 +53,6 @@
parameter="ShowSnapshotButton" />
</menu_item_check>
<menu_item_check
- label="Sidebar button"
- layout="topleft"
- name="ShowSidebarButton">
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="ShowSidebarButton" />
- <menu_item_check.on_check
- function="CheckControl"
- parameter="ShowSidebarButton" />
- </menu_item_check>
- <menu_item_check
label="Build button"
layout="topleft"
name="ShowBuildButton">
diff --git a/indra/newview/skins/default/xui/en/menu_cof_attachment.xml b/indra/newview/skins/default/xui/en/menu_cof_attachment.xml
index b422d87938..c402100fb1 100644
--- a/indra/newview/skins/default/xui/en/menu_cof_attachment.xml
+++ b/indra/newview/skins/default/xui/en/menu_cof_attachment.xml
@@ -10,12 +10,4 @@
function="Attachment.Detach"
parameter="detach"/>
</menu_item_call>
- <context_menu
- label="Attach to"
- layout="topleft"
- name="attach_to" />
- <context_menu
- label="Attach to HUD"
- layout="topleft"
- name="attach_to_hud" />
</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_cof_body_part.xml b/indra/newview/skins/default/xui/en/menu_cof_body_part.xml
index 01008ef203..f0e8461360 100644
--- a/indra/newview/skins/default/xui/en/menu_cof_body_part.xml
+++ b/indra/newview/skins/default/xui/en/menu_cof_body_part.xml
@@ -19,4 +19,15 @@
function="BodyPart.OnEnable"
parameter="edit" />
</menu_item_call>
+ <menu_item_call
+ label="Create New"
+ layout="topleft"
+ name="create_new"
+ translate="false">
+ <on_click
+ function="BodyPart.Create"/>
+ <on_enable
+ function="BodyPart.OnEnable"
+ parameter="create" />
+ </menu_item_call>
</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_cof_clothing.xml b/indra/newview/skins/default/xui/en/menu_cof_clothing.xml
index f9cb29f0d7..12ee9b045b 100644
--- a/indra/newview/skins/default/xui/en/menu_cof_clothing.xml
+++ b/indra/newview/skins/default/xui/en/menu_cof_clothing.xml
@@ -8,6 +8,9 @@
name="take_off">
<on_click
function="Clothing.TakeOff" />
+ <on_enable
+ function="Clothing.OnEnable"
+ parameter="take_off" />
</menu_item_call>
<menu_item_call
label="Move Up a Layer"
@@ -39,4 +42,15 @@
function="Clothing.OnEnable"
parameter="edit" />
</menu_item_call>
+ <menu_item_call
+ label="Create New"
+ layout="topleft"
+ name="create_new"
+ translate="false">
+ <on_click
+ function="Clothing.Create"/>
+ <on_enable
+ function="Clothing.OnEnable"
+ parameter="create" />
+ </menu_item_call>
</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_cof_gear.xml b/indra/newview/skins/default/xui/en/menu_cof_gear.xml
index 982d4f2015..c2a11a64ec 100644
--- a/indra/newview/skins/default/xui/en/menu_cof_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_cof_gear.xml
@@ -2,15 +2,12 @@
<menu
layout="topleft"
name="Gear COF">
- <menu_item_call
- label="Add To Outfit"
+ <menu
+ label="New Clothes"
layout="topleft"
- name="add">
- <on_click
- function="Gear.OnClick"
- parameter="add"/>
- <on_enable
- function="Gear.OnEnable"
- parameter="add" />
- </menu_item_call>
+ name="COF.Gear.New_Clothes" />
+ <menu
+ label="New Body Parts"
+ layout="topleft"
+ name="COF.Geear.New_Body_Parts" />
</menu>
diff --git a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml
index dfc72b557c..b5eda8e999 100644
--- a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml
@@ -7,31 +7,174 @@
layout="topleft"
name="wear">
<on_click
- function="Gear.OnClick"
- parameter="wear"/>
+ function="Gear.Wear" />
<on_enable
function="Gear.OnEnable"
parameter="wear" />
</menu_item_call>
<menu_item_call
- label="Take Off - Remove Current Outfit"
+ label="Take Off - Remove from Current Outfit"
layout="topleft"
name="take_off">
<on_click
- function="Gear.OnClick"
- parameter="take_off"/>
+ function="Gear.TakeOff" />
<on_enable
function="Gear.OnEnable"
parameter="take_off" />
</menu_item_call>
+
+ <menu_item_separator />
+ <!-- copied (with minor modifications) from menu_inventory_add.xml -->
+ <!-- *TODO: generate dynamically? -->
+ <menu
+ height="175"
+ label="New Clothes"
+ layout="topleft"
+ left_delta="0"
+ mouse_opaque="false"
+ name="New Clothes"
+ top_pad="514"
+ width="125">
+ <menu_item_call
+ label="New Shirt"
+ layout="topleft"
+ name="New Shirt">
+ <menu_item_call.on_click
+ function="Gear.Create"
+ parameter="shirt" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Pants"
+ layout="topleft"
+ name="New Pants">
+ <menu_item_call.on_click
+ function="Gear.Create"
+ parameter="pants" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Shoes"
+ layout="topleft"
+ name="New Shoes">
+ <menu_item_call.on_click
+ function="Gear.Create"
+ parameter="shoes" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Socks"
+ layout="topleft"
+ name="New Socks">
+ <menu_item_call.on_click
+ function="Gear.Create"
+ parameter="socks" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Jacket"
+ layout="topleft"
+ name="New Jacket">
+ <menu_item_call.on_click
+ function="Gear.Create"
+ parameter="jacket" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Skirt"
+ layout="topleft"
+ name="New Skirt">
+ <menu_item_call.on_click
+ function="Gear.Create"
+ parameter="skirt" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Gloves"
+ layout="topleft"
+ name="New Gloves">
+ <menu_item_call.on_click
+ function="Gear.Create"
+ parameter="gloves" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Undershirt"
+ layout="topleft"
+ name="New Undershirt">
+ <menu_item_call.on_click
+ function="Gear.Create"
+ parameter="undershirt" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Underpants"
+ layout="topleft"
+ name="New Underpants">
+ <menu_item_call.on_click
+ function="Gear.Create"
+ parameter="underpants" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Alpha"
+ layout="topleft"
+ name="New Alpha">
+ <menu_item_call.on_click
+ function="Gear.Create"
+ parameter="alpha" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Tattoo"
+ layout="topleft"
+ name="New Tattoo">
+ <menu_item_call.on_click
+ function="Gear.Create"
+ parameter="tattoo" />
+ </menu_item_call>
+ </menu>
+ <menu
+ height="85"
+ label="New Body Parts"
+ layout="topleft"
+ left_delta="0"
+ mouse_opaque="false"
+ name="New Body Parts"
+ top_pad="514"
+ width="118">
+ <menu_item_call
+ label="New Shape"
+ layout="topleft"
+ name="New Shape">
+ <menu_item_call.on_click
+ function="Gear.Create"
+ parameter="shape" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Skin"
+ layout="topleft"
+ name="New Skin">
+ <menu_item_call.on_click
+ function="Gear.Create"
+ parameter="skin" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Hair"
+ layout="topleft"
+ name="New Hair">
+ <menu_item_call.on_click
+ function="Gear.Create"
+ parameter="hair" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Eyes"
+ layout="topleft"
+ name="New Eyes">
+ <menu_item_call.on_click
+ function="Gear.Create"
+ parameter="eyes" />
+ </menu_item_call>
+ </menu>
+ <!-- copied from menu_inventory_add.xml -->
+
<menu_item_separator />
<menu_item_call
label="Rename"
layout="topleft"
name="rename">
<on_click
- function="Gear.OnClick"
- parameter="rename"/>
+ function="Gear.Rename" />
<on_enable
function="Gear.OnEnable"
parameter="rename" />
@@ -41,10 +184,9 @@
layout="topleft"
name="delete_outfit">
<on_click
- function="Gear.OnClick"
- parameter="delete_outfit"/>
+ function="Gear.Delete" />
<on_enable
function="Gear.OnEnable"
- parameter="delete_outfit" />
+ parameter="delete" />
</menu_item_call>
</menu>
diff --git a/indra/newview/skins/default/xui/en/menu_outfit_tab.xml b/indra/newview/skins/default/xui/en/menu_outfit_tab.xml
index 8f3e62157a..67559638d9 100644
--- a/indra/newview/skins/default/xui/en/menu_outfit_tab.xml
+++ b/indra/newview/skins/default/xui/en/menu_outfit_tab.xml
@@ -8,6 +8,9 @@
name="wear_replace">
<on_click
function="Outfit.WearReplace" />
+ <on_enable
+ function="Outfit.OnEnable"
+ parameter="wear_replace" />
</menu_item_call>
<menu_item_call
label="Wear - Add to Current Outfit"
@@ -15,13 +18,29 @@
name="wear_add">
<on_click
function="Outfit.WearAdd" />
+ <on_enable
+ function="Outfit.OnEnable"
+ parameter="wear_add" />
</menu_item_call>
<menu_item_call
- label="Take Off - Remove Current Outfit"
+ label="Take Off - Remove from Current Outfit"
layout="topleft"
name="take_off">
<on_click
function="Outfit.TakeOff" />
+ <on_enable
+ function="Outfit.OnEnable"
+ parameter="take_off" />
+ </menu_item_call>
+ <menu_item_call
+ label="Edit Outfit"
+ layout="topleft"
+ name="edit">
+ <on_click
+ function="Outfit.Edit" />
+ <on_enable
+ function="Outfit.OnEnable"
+ parameter="edit" />
</menu_item_call>
<menu_item_separator />
<menu_item_call
@@ -30,6 +49,9 @@
name="rename">
<on_click
function="Outfit.Rename" />
+ <on_enable
+ function="Outfit.OnEnable"
+ parameter="rename" />
</menu_item_call>
<menu_item_call
label="Delete Outfit"
@@ -37,5 +59,8 @@
name="delete">
<on_click
function="Outfit.Delete" />
+ <on_enable
+ function="Outfit.OnEnable"
+ parameter="delete" />
</menu_item_call>
</context_menu>
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 7ea7eaade5..e645702f93 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
@@ -9,22 +9,27 @@
function="Wearable.Wear" />
</menu_item_call>
<menu_item_call
+ label="Take Off / Detach"
+ layout="topleft"
+ name="take_off_or_detach">
+ <on_click
+ function="Wearable.TakeOffDetach" />
+ </menu_item_call>
+ <menu_item_call
label="Detach"
layout="topleft"
name="detach">
<on_click
function="Attachment.Detach" />
</menu_item_call>
-<!-- *TODO: implement the submenus
- <menu
- label="Attach to"
+ <context_menu
+ label="Attach to ▶"
layout="topleft"
- name="attach_to" />
- <menu
- label="Attach to HUD"
+ name="wearable_attach_to" />
+ <context_menu
+ label="Attach to HUD ▶"
layout="topleft"
- name="attach_to_hud" />
--->
+ name="wearable_attach_to_hud" />
<menu_item_call
label="Object Profile"
layout="topleft"
@@ -37,16 +42,14 @@
layout="topleft"
name="take_off">
<on_click
- function="Clothing.TakeOff"
- parameter="take_off"/>
+ function="Clothing.TakeOff" />
</menu_item_call>
<menu_item_call
label="Edit"
layout="topleft"
name="edit">
<on_click
- function="Wearable.Edit"
- parameter="edit"/>
+ function="Wearable.Edit" />
</menu_item_call>
<menu_item_call
label="Show Original"
@@ -55,4 +58,12 @@
<on_click
function="Wearable.ShowOriginal" />
</menu_item_call>
+ <menu_item_call
+ label="Create New"
+ layout="topleft"
+ name="create_new"
+ translate="false">
+ <on_click
+ function="Wearable.CreateNew" />
+ </menu_item_call>
</context_menu>
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 079d029eab..5ead756d20 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -1090,7 +1090,9 @@ The region [REGION] does not allow terraforming.
icon="alertmodal.tga"
name="CannotCopyWarning"
type="alertmodal">
-You do not have permission to copy this item and will lose it from your inventory if you give it away. Do you really want to offer this item?
+You do not have permission to copy the following items:
+[ITEMS]
+and will lose it from your inventory if you give it away. Do you really want to offer these items?
<usetemplate
name="okcancelbuttons"
notext="No"
@@ -2068,6 +2070,28 @@ Would you be my friend?
<notification
icon="alertmodal.tga"
+ label="Rename Outfit"
+ name="RenameOutfit"
+ type="alertmodal">
+ New outfit name:
+ <form name="form">
+ <input name="new_name" type="text">
+ [NAME]
+ </input>
+ <button
+ default="true"
+ index="0"
+ name="Offer"
+ text="OK"/>
+ <button
+ index="1"
+ name="Cancel"
+ text="Cancel"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="RemoveFromFriends"
type="alertmodal">
Do you want to remove [FIRST_NAME] [LAST_NAME] from your Friends List?
@@ -6120,6 +6144,28 @@ Drag items from inventory onto a person in the resident picker
</notification>
<notification
icon="notifytip.tga"
+ name="ShareItemsConfirmation"
+ type="alertmodal">
+Are you sure you want to share the following items:
+
+[ITEMS]
+
+With the following Residents:
+
+[RESIDENTS]
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="Ok"/>
+ </notification>
+ <notification
+ icon="notifytip.tga"
+ name="ItemsShared"
+ type="notifytip">
+Items are successfully shared.
+ </notification>
+ <notification
+ icon="notifytip.tga"
name="DeedToGroupFail"
type="notifytip">
Deed to group failed.
@@ -6263,8 +6309,8 @@ Mute everyone?
<usetemplate
ignoretext="Confirm before I mute all participants in a group call"
name="okcancelignore"
- notext="Ok"
- yestext="Cancel"/>
+ yestext="Ok"
+ notext="Cancel"/>
<unique/>
</notification>
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_block_list_sidetray.xml b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml
index d3f6695375..1e6a31d388 100644
--- a/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml
+++ b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml
@@ -11,14 +11,16 @@
width="280">
<button
follows="top|left"
- height="25"
- image_overlay="BackArrow_Off"
+ height="24"
+ image_hover_unselected="BackButton_Over"
+ image_pressed="BackButton_Press"
+ image_unselected="BackButton_Off"
layout="topleft"
name="back"
- left="10"
+ left="4"
tab_stop="false"
- top="0"
- width="25"/>
+ top="1"
+ width="30"/>
<text
follows="top|left|right"
font="SansSerifLargeBold"
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 2edd643cc5..a0bbc8f2ee 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
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
follows="top|right|left"
- height="23"
+ height="25"
layout="topleft"
left="0"
name="wearable_item"
@@ -9,22 +9,22 @@
width="380">
<icon
follows="top|right|left"
- height="23"
+ height="22"
image_name="ListItem_Over"
layout="topleft"
left="0"
name="hovered_icon"
- top="0"
+ top="1"
visible="false"
width="380" />
<icon
- height="23"
+ height="22"
follows="top|right|left"
image_name="ListItem_Select"
layout="topleft"
left="0"
name="selected_icon"
- top="0"
+ top="1"
visible="false"
width="380" />
<icon
@@ -53,7 +53,6 @@
name="btn_lock"
layout="topleft"
follows="top|right"
- image_name="Locked_Icon"
top="0"
left="0"
height="23"
@@ -70,24 +69,35 @@
width="9"
tab_stop="false" />
</panel>
- <button
- name="btn_edit"
+ <panel
+ background_visible="false"
+ name="btn_edit_panel"
layout="topleft"
follows="top|right"
- image_overlay="Edit_Wrench"
top="0"
left_pad="3"
- height="23"
- width="23"
- tab_stop="false" />
- <panel
- background_visible="true"
- bg_alpha_color="0.4 0.4 0.4 1.0"
- bottom="0"
+ height="24"
+ width="27"
+ tab_stop="false">
+ <button
+ name="btn_edit"
+ layout="topleft"
+ follows="top|right"
+ image_overlay="Edit_Wrench"
+ top="0"
+ left="0"
+ height="24"
+ width="24"
+ tab_stop="false" />
+ </panel>
+ <icon
follows="left|right|top"
- height="1"
+ height="3"
+ image_name="Wearables_Divider"
layout="bottomleft"
left="0"
- name="wearable_type_separator_panel"
+ name="wearable_type_separator_icon"
+ top="3"
+ visible="true"
width="380"/>
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
index ac61c7da5d..82b2405ec9 100644
--- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml
+++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
@@ -222,38 +222,6 @@
min_height="28"
min_width="52"
mouse_opaque="false"
- name="sidebar_btn_panel"
- user_resize="false"
- width="83">
-<!--*TODO: Implement toggle of sidebar with buttons
-Disabled for now.
--->
- <button
- control_name="SidebarWithButtonsVisibility"
- follows="left|right"
- height="23"
- image_pressed="PushButton_Press"
- image_pressed_selected="PushButton_Selected_Press"
- image_selected="PushButton_Selected_Press"
- is_toggle="true"
- label="Sidebar"
- layout="topleft"
- left="0"
- name="sidebar_btn"
- tool_tip="Shows/hides Sidebar"
- top="5"
- use_ellipses="true"
- width="80">
- </button>
- </layout_panel>
- <layout_panel
- auto_resize="false"
- follows="left|right"
- height="28"
- layout="topleft"
- min_height="28"
- min_width="52"
- mouse_opaque="false"
name="build_btn_panel"
user_resize="false"
width="83">
diff --git a/indra/newview/skins/default/xui/en/panel_classified_info.xml b/indra/newview/skins/default/xui/en/panel_classified_info.xml
index e3b331799c..859cc82e81 100644
--- a/indra/newview/skins/default/xui/en/panel_classified_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_classified_info.xml
@@ -40,15 +40,17 @@
</panel.string>
<button
follows="top|right"
- height="23"
- image_overlay="BackArrow_Off"
+ height="24"
+ image_hover_unselected="BackButton_Over"
+ image_pressed="BackButton_Press"
+ image_unselected="BackButton_Off"
layout="topleft"
name="back_btn"
picture_style="true"
- left="11"
+ left="9"
tab_stop="false"
top="2"
- width="23" />
+ width="30" />
<text
follows="top|left|right"
font="SansSerifHugeBold"
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 035e8607ec..e41141f6bd 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
@@ -9,22 +9,22 @@
width="380">
<icon
follows="top|right|left"
- height="23"
+ height="22"
image_name="ListItem_Over"
layout="topleft"
left="0"
name="hovered_icon"
- top="0"
+ top="1"
visible="false"
width="380" />
<icon
- height="23"
+ height="22"
follows="top|right|left"
image_name="ListItem_Select"
layout="topleft"
left="0"
name="selected_icon"
- top="0"
+ top="1"
visible="false"
width="380" />
<button
@@ -33,10 +33,10 @@
follows="top|left"
image_unselected="Toast_CloseBtn"
image_selected="Toast_CloseBtn"
- top="0"
+ top="2"
left="0"
- height="20"
- width="20"
+ height="18"
+ width="18"
tab_stop="false" />
<icon
height="16"
@@ -66,8 +66,8 @@
image_overlay="UpArrow_Off"
top="0"
left="0"
- height="23"
- width="23"
+ height="24"
+ width="24"
tab_stop="false" />
<button
name="btn_move_down"
@@ -76,15 +76,14 @@
image_overlay="DownArrow_Off"
top="0"
left_pad="3"
- height="23"
- width="23"
+ height="24"
+ width="24"
tab_stop="false" />
<panel
background_visible="false"
name="btn_lock"
layout="topleft"
follows="top|right"
- image_name="Locked_Icon"
top="0"
left="0"
height="23"
@@ -101,25 +100,35 @@
width="9"
tab_stop="false" />
</panel>
- <button
- name="btn_edit"
+ <panel
+ background_visible="false"
+ name="btn_edit_panel"
layout="topleft"
follows="top|right"
- image_overlay="Edit_Wrench"
top="0"
left_pad="3"
- height="23"
- width="23"
- tab_stop="false" />
- <panel
- background_visible="true"
- bg_alpha_color="0.4 0.4 0.4 1.0"
- bottom="0"
+ height="24"
+ width="27"
+ tab_stop="false">
+ <button
+ name="btn_edit"
+ layout="topleft"
+ follows="top|right"
+ image_overlay="Edit_Wrench"
+ top="0"
+ left="0"
+ height="24"
+ width="24"
+ tab_stop="false" />
+ </panel>
+ <icon
follows="left|right|top"
- height="1"
+ height="3"
+ image_name="Wearables_Divider"
layout="bottomleft"
left="0"
- name="wearable_type_separator_panel"
+ name="wearable_type_separator_icon"
+ top="0"
visible="false"
width="380"/>
</panel>
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 cf84c31078..5f34c24bca 100644
--- a/indra/newview/skins/default/xui/en/panel_cof_wearables.xml
+++ b/indra/newview/skins/default/xui/en/panel_cof_wearables.xml
@@ -9,6 +9,7 @@
name="cof_wearables"
width="311">
<accordion
+ fit_parent="true"
follows="all"
height="200"
layout="topleft"
@@ -38,73 +39,31 @@
layout="topleft"
name="tab_clothing"
title="Clothing">
-
- <!-- *NOTE there should be no any gaps between the button bar and the list -
- accordiong-list adaptor won't employ them while calculating new height when the size of the list changes -->
- <panel
- background_visible="false"
- class="accordion_list_adaptor"
+ <flat_list_view
+ allow_select="true"
follows="all"
- height="45"
+ height="10"
layout="topleft"
left="0"
- name="button_bar_adaptor"
+ multi_select="true"
+ name="list_clothing"
top="0"
- width="311">
- <panel
- bevel="none"
- filename="panel_clothing_list_button_bar.xml"
- height="35"
- name="button_bar"
- top="0"
- width="311" />
- <flat_list_view
- allow_select="true"
- follows="all"
- height="10"
- layout="topleft"
- left="0"
- multi_select="true"
- name="list_clothing"
- top_pad="0"
- width="311" />
- </panel>
+ width="311" />
</accordion_tab>
<accordion_tab
layout="topleft"
name="tab_body_parts"
title="Body Parts">
-
- <!-- *NOTE there should be no any gaps between the button bar and the list -
- accordiong-list adaptor won't employ them while calculating new height when the size of the list changes -->
- <panel
- background_visible="false"
- class="accordion_list_adaptor"
+ <flat_list_view
+ allow_select="true"
follows="all"
- height="45"
+ height="10"
layout="topleft"
left="0"
- name="button_bar_adaptor"
+ multi_select="true"
+ name="list_body_parts"
top="0"
- width="311">
- <panel
- bevel="none"
- filename="panel_bodyparts_list_button_bar.xml"
- height="35"
- name="button_bar"
- top="0"
- width="311"/>
- <flat_list_view
- allow_select="true"
- follows="all"
- height="10"
- layout="topleft"
- left="0"
- multi_select="true"
- name="list_body_parts"
- top_pad="0"
- width="311" />
- </panel>
+ width="311" />
</accordion_tab>
</accordion>
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_deletable_wearable_list_item.xml b/indra/newview/skins/default/xui/en/panel_deletable_wearable_list_item.xml
index 2f37b9d3c9..b006d125ee 100644
--- a/indra/newview/skins/default/xui/en/panel_deletable_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_deletable_wearable_list_item.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
follows="top|right|left"
- height="23"
+ height="25"
layout="topleft"
left="0"
name="deletable_wearable_item"
@@ -9,22 +9,22 @@
width="380">
<icon
follows="top|right|left"
- height="20"
+ height="22"
image_name="ListItem_Over"
layout="topleft"
left="0"
name="hovered_icon"
- top="0"
+ top="1"
visible="false"
width="380" />
<icon
- height="20"
+ height="22"
follows="top|right|left"
image_name="ListItem_Select"
layout="topleft"
left="0"
name="selected_icon"
- top="0"
+ top="1"
visible="false"
width="380" />
<button
@@ -33,10 +33,10 @@
follows="top|left"
image_unselected="Toast_CloseBtn"
image_selected="Toast_CloseBtn"
- top="0"
+ top="2"
left="0"
- height="20"
- width="20"
+ height="18"
+ width="18"
tab_stop="false" />
<icon
height="16"
@@ -59,15 +59,14 @@
top="4"
value="..."
width="359" />
- <panel
- background_visible="true"
- bg_alpha_color="0.4 0.4 0.4 1.0"
- bottom="0"
+ <icon
follows="left|right|top"
- height="1"
+ height="3"
+ image_name="Wearables_Divider"
layout="bottomleft"
left="0"
- name="wearable_type_separator_panel"
+ name="wearable_type_separator_icon"
+ top="3"
visible="true"
width="380"/>
</panel>
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 06371b7489..6c43635d49 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
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
follows="top|right|left"
- height="23"
+ height="25"
layout="topleft"
left="0"
name="dummy_clothing_item"
@@ -9,22 +9,22 @@
width="380">
<icon
follows="top|right|left"
- height="23"
+ height="22"
image_name="ListItem_Over"
layout="topleft"
left="0"
name="hovered_icon"
- top="0"
+ top="1"
visible="false"
width="380" />
<icon
- height="23"
+ height="22"
follows="top|right|left"
image_name="ListItem_Select"
layout="topleft"
left="0"
name="selected_icon"
- top="0"
+ top="1"
visible="false"
width="380" />
<icon
@@ -56,17 +56,17 @@
image_overlay="AddItem_Off"
top="0"
left="0"
- height="23"
- width="23"
+ height="24"
+ width="24"
tab_stop="false" />
- <panel
- background_visible="true"
- bg_alpha_color="0.4 0.4 0.4 1.0"
- bottom="0"
+ <icon
follows="left|right|top"
- height="1"
+ height="3"
+ image_name="Wearables_Divider"
layout="bottomleft"
left="0"
- name="wearable_type_separator_panel"
+ name="wearable_type_separator_icon"
+ top="3"
+ visible="true"
width="380"/>
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_edit_alpha.xml b/indra/newview/skins/default/xui/en/panel_edit_alpha.xml
index cfcdc25f81..7bcd4962d2 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_alpha.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_alpha.xml
@@ -21,126 +21,131 @@
name="avatar_alpha_color_panel"
top="0"
width="313" >
+ <check_box
+ control_name="LowerAlphaTextureInvisible"
+ follows="left"
+ height="16"
+ layout="topleft"
+ left="5"
+ name="lower alpha texture invisible"
+ top="10"
+ width="16" />
<texture_picker
can_apply_immediately="true"
default_image_name="Default"
follows="left|top"
- height="100"
+ height="115"
label="Lower Alpha"
layout="topleft"
- left="30"
+ left_pad="5"
name="Lower Alpha"
tool_tip="Click to choose a picture"
top="10"
- width="94" >
+ width="115" >
<texture_picker.commit_callback
function="TexturePicker.Commit" />
</texture_picker>
+
<check_box
- control_name="LowerAlphaTextureInvisible"
+ control_name="UpperAlphaTextureInvisible"
follows="left"
height="16"
layout="topleft"
- left_pad="6"
- name="lower alpha texture invisible"
- top_delta="4"
+ left_pad="20"
+ name="upper alpha texture invisible"
+ top="10"
width="16" />
<texture_picker
can_apply_immediately="true"
default_image_name="Default"
follows="left|top"
- height="100"
+ height="115"
label="Upper Alpha"
layout="topleft"
- left_pad="20"
+ left_pad="5"
name="Upper Alpha"
tool_tip="Click to choose a picture"
top="10"
- width="94">
+ width="115">
<texture_picker.commit_callback
function="TexturePicker.Commit" />
</texture_picker>
+
<check_box
- control_name="UpperAlphaTextureInvisible"
+ control_name="HeadAlphaTextureInvisible"
follows="left"
height="16"
layout="topleft"
- left_pad="6"
- name="upper alpha texture invisible"
- top_delta="4"
+ left="5"
+ name="head alpha texture invisible"
+ top_pad="15"
width="16" />
<texture_picker
can_apply_immediately="true"
default_image_name="Default"
follows="left|top"
- height="100"
+ height="115"
label="Head Alpha"
layout="topleft"
- left="30"
+ left_pad="5"
name="Head Alpha"
tool_tip="Click to choose a picture"
- top="120"
- width="94" >
+ top_delta="0"
+ width="115" >
<texture_picker.commit_callback
function="TexturePicker.Commit" />
</texture_picker>
+
<check_box
- control_name="HeadAlphaTextureInvisible"
+ control_name="Eye AlphaTextureInvisible"
follows="left"
height="16"
layout="topleft"
- left_pad="6"
- name="head alpha texture invisible"
- top_delta="4"
+ left_pad="20"
+ name="eye alpha texture invisible"
+ top_delta="0"
width="16" />
<texture_picker
can_apply_immediately="true"
default_image_name="Default"
follows="left|top"
- height="100"
+ height="115"
label="Eye Alpha"
layout="topleft"
- left_pad="20"
+ left_pad="5"
name="Eye Alpha"
tool_tip="Click to choose a picture"
- top="120"
- width="94" >
+ top_delta="0"
+ width="115" >
<texture_picker.commit_callback
function="TexturePicker.Commit" />
</texture_picker>
+
<check_box
- control_name="Eye AlphaTextureInvisible"
+ control_name="HairAlphaTextureInvisible"
follows="left"
height="16"
layout="topleft"
- left_pad="6"
- name="eye alpha texture invisible"
- top_delta="4"
+ left="5"
+ name="hair alpha texture invisible"
+ top_pad="15"
width="16" />
<texture_picker
can_apply_immediately="true"
default_image_name="Default"
follows="left|top"
- height="100"
+ height="115"
label="Hair Alpha"
layout="topleft"
left="30"
name="Hair Alpha"
tool_tip="Click to choose a picture"
- top="230"
- width="94" >
+ top_delta="0"
+ width="115" >
<texture_picker.commit_callback
function="TexturePicker.Commit" />
</texture_picker>
- <check_box
- control_name="HairAlphaTextureInvisible"
- follows="left"
- height="16"
- layout="topleft"
- left_pad="6"
- name="hair alpha texture invisible"
- top_delta="4"
- width="16" />
+
</panel>
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_edit_classified.xml b/indra/newview/skins/default/xui/en/panel_edit_classified.xml
index 7383edf63d..1b4f547f9d 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_classified.xml
@@ -24,15 +24,17 @@
</string>
<button
follows="top|right"
- height="23"
- image_overlay="BackArrow_Off"
+ height="24"
+ image_hover_unselected="BackButton_Over"
+ image_pressed="BackButton_Press"
+ image_unselected="BackButton_Off"
layout="topleft"
name="back_btn"
picture_style="true"
- left="12"
+ left="7"
tab_stop="false"
top="2"
- width="23" />
+ width="30" />
<text
type="string"
length="1"
diff --git a/indra/newview/skins/default/xui/en/panel_edit_eyes.xml b/indra/newview/skins/default/xui/en/panel_edit_eyes.xml
index 4149a0b06f..f173a2f3cb 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_eyes.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_eyes.xml
@@ -51,6 +51,7 @@
top_pad="10"
width="313">
<accordion
+ fit_parent="true"
follows="all"
height ="300"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_edit_gloves.xml b/indra/newview/skins/default/xui/en/panel_edit_gloves.xml
index 94fd2f9080..a490f27b9f 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_gloves.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_gloves.xml
@@ -65,6 +65,7 @@
top_pad="10"
width="313">
<accordion
+ fit_parent="true"
follows="all"
height ="300"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_edit_hair.xml b/indra/newview/skins/default/xui/en/panel_edit_hair.xml
index 9b60e83387..6bb5d2fa9b 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_hair.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_hair.xml
@@ -51,6 +51,7 @@
top_pad="10"
width="313">
<accordion
+ fit_parent="true"
follows="all"
height ="300"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_edit_jacket.xml b/indra/newview/skins/default/xui/en/panel_edit_jacket.xml
index 248ae9fe04..929cdffb3d 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_jacket.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_jacket.xml
@@ -80,6 +80,7 @@
top_pad="10"
width="313">
<accordion
+ fit_parent="true"
follows="all"
height ="300"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_edit_pants.xml b/indra/newview/skins/default/xui/en/panel_edit_pants.xml
index 3ed1df2399..f22cf983aa 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_pants.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_pants.xml
@@ -65,6 +65,7 @@
top_pad="10"
width="313">
<accordion
+ fit_parent="true"
follows="all"
height ="300"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_edit_pick.xml b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
index 08ee0306dd..589ea10e8d 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_pick.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
@@ -18,14 +18,16 @@
</panel.string>
<button
follows="top|right"
- height="23"
- image_overlay="BackArrow_Off"
+ height="24"
+ image_hover_unselected="BackButton_Over"
+ image_pressed="BackButton_Press"
+ image_unselected="BackButton_Off"
layout="topleft"
name="back_btn"
- left="12"
+ left="7"
tab_stop="false"
top="2"
- width="23" />
+ width="30" />
<text
type="string"
length="1"
diff --git a/indra/newview/skins/default/xui/en/panel_edit_shirt.xml b/indra/newview/skins/default/xui/en/panel_edit_shirt.xml
index e088aa05ac..85823073b5 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_shirt.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_shirt.xml
@@ -65,6 +65,7 @@
top_pad="10"
width="313">
<accordion
+ fit_parent="true"
follows="all"
height ="300"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_edit_shoes.xml b/indra/newview/skins/default/xui/en/panel_edit_shoes.xml
index e079047a86..b26fde68f1 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_shoes.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_shoes.xml
@@ -65,6 +65,7 @@
top_pad="10"
width="313">
<accordion
+ fit_parent="true"
follows="all"
height ="300"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_edit_skin.xml b/indra/newview/skins/default/xui/en/panel_edit_skin.xml
index 9158685c40..45591ba2ad 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_skin.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_skin.xml
@@ -85,6 +85,7 @@
width="313">
<accordion
layout="topleft"
+ fit_parent="true"
follows="all"
height ="300"
left="0"
diff --git a/indra/newview/skins/default/xui/en/panel_edit_skirt.xml b/indra/newview/skins/default/xui/en/panel_edit_skirt.xml
index 87f3270b31..bb8e0dca07 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_skirt.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_skirt.xml
@@ -65,6 +65,7 @@
top_pad="10"
width="313">
<accordion
+ fit_parent="true"
follows="all"
height ="300"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_edit_socks.xml b/indra/newview/skins/default/xui/en/panel_edit_socks.xml
index 5bd99969a2..d813d94d93 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_socks.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_socks.xml
@@ -65,6 +65,7 @@
top_pad="10"
width="313">
<accordion
+ fit_parent="true"
follows="all"
height ="300"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_edit_underpants.xml b/indra/newview/skins/default/xui/en/panel_edit_underpants.xml
index bbe5230341..19225e9757 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_underpants.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_underpants.xml
@@ -65,6 +65,7 @@
top_pad="10"
width="313">
<accordion
+ fit_parent="true"
follows="all"
height ="300"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_edit_undershirt.xml b/indra/newview/skins/default/xui/en/panel_edit_undershirt.xml
index a79c1b9eaa..720a55dcc2 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_undershirt.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_undershirt.xml
@@ -65,6 +65,7 @@
top_pad="10"
width="313">
<accordion
+ fit_parent="true"
follows="all"
height ="300"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml
index 0455086ef3..67ff71cef1 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml
@@ -132,12 +132,14 @@ left="0"
</string>
<button
follows="top|left"
- height="25"
- width="25"
- image_overlay="BackArrow_Off"
+ height="24"
+ width="30"
+ image_hover_unselected="BackButton_Over"
+ image_pressed="BackButton_Press"
+ image_unselected="BackButton_Off"
layout="topleft"
name="back_btn"
- left="10"
+ left="11"
top="7" />
<text
follows="top|left"
diff --git a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
index 789d69bc68..58b78cfa02 100644
--- a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
@@ -36,14 +36,16 @@ background_visible="true"
layout="topleft">
<button
follows="top|right"
- height="23"
- image_overlay="BackArrow_Off"
+ height="24"
+ image_hover_unselected="BackButton_Over"
+ image_pressed="BackButton_Press"
+ image_unselected="BackButton_Off"
layout="topleft"
name="back"
- left="8"
+ left="7"
tab_stop="false"
top="2"
- width="23" />
+ width="30" />
<text_editor
allow_scroll="false"
bg_visible="false"
diff --git a/indra/newview/skins/default/xui/en/panel_landmark_info.xml b/indra/newview/skins/default/xui/en/panel_landmark_info.xml
index 31ba539c44..25674a1a39 100644
--- a/indra/newview/skins/default/xui/en/panel_landmark_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_landmark_info.xml
@@ -55,15 +55,17 @@
value="Parcel_R_Dark" />
<button
follows="top|right"
- height="23"
- image_overlay="BackArrow_Off"
+ height="24"
+ image_hover_unselected="BackButton_Over"
+ image_pressed="BackButton_Press"
+ image_unselected="BackButton_Off"
layout="topleft"
- left="11"
+ left="8"
name="back_btn"
tool_tip="Back"
tab_stop="false"
top="4"
- width="23" />
+ width="30" />
<text
follows="top|left|right"
font="SansSerifHugeBold"
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..664dce1d71 100644
--- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
@@ -52,30 +52,19 @@
<string name="Filter.Clothes/Body" value="Clothes/Body"/>
<string name="Filter.Objects" value="Objects"/>
- <!--
- TODO remove this button. Added it temporary for QA to be able to test new edit wearable
- panel (see EXT-6564)
- -->
- <button
- follows="left|top|right"
- height="20"
- label="edit"
- left="0"
- top="0"
- layout="topleft"
- name="edit_wearable_btn"
- width="40" />
-
+
<button
follows="top|left"
- height="23"
- image_overlay="BackArrow_Off"
+ height="24"
+ image_hover_unselected="BackButton_Over"
+ image_pressed="BackButton_Press"
+ image_unselected="BackButton_Off"
layout="topleft"
name="back_btn"
left="5"
tab_stop="false"
top="2"
- width="23" />
+ width="30" />
<text
follows="top|right"
font="SansSerifHugeBold"
@@ -150,8 +139,8 @@
<!-- LIST OF WEARABLES (CURRENT OUTFIT/ WEARABLES TO ADD) -->
-<!-- *NOTE: border_size is used to calculate space between layout panel and for resize bar height
-required height for dragbar is 10, so resizebar height should be 10 px.
+<!-- *NOTE: border_size is used to calculate space between layout panels and also to calculate resize bar's height.
+Required height for dragbar (icon in spec) is 10, so resizebar height should be 10 px.
It is calculated as border_size + 2*UIResizeBarOverlap
-->
<layout_stack
@@ -160,7 +149,7 @@ It is calculated as border_size + 2*UIResizeBarOverlap
clip="false"
default_tab_group="2"
follows="all"
- height="495"
+ height="465"
width="313"
layout="topleft"
orientation="vertical"
@@ -170,7 +159,7 @@ It is calculated as border_size + 2*UIResizeBarOverlap
left="5">
<layout_panel
layout="topleft"
- height="220"
+ height="187"
label="IM Control Panel"
min_height="100"
name="outfit_wearables_panel"
@@ -178,128 +167,95 @@ It is calculated as border_size + 2*UIResizeBarOverlap
auto_resize="true"
user_resize="true">
- <!-- List containing items from the COF and Base outfit -->
- <panel
- background_visible="false"
- class="cof_wearables"
- filename="panel_cof_wearables.xml"
- follows="left|top|right|bottom"
- height="193"
- layout="topleft"
- left="1"
- 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>
-
-
- <layout_panel
- background_visible="true"
- bg_alpha_color="DkGray2"
- auto_resize="true"
- default_tab_group="3"
- height="211"
- min_height="210"
- name="add_wearables_panel"
- width="313"
- tab_group="2"
- user_resize="true"
- visible="false">
- <icon
- follows="left|top|right"
- height="10"
- image_name="Dragbar"
- left="0"
- top_pad="-9"
- width="313" />
- <text
- follows="top|left|right"
- font="SansSerifBold"
- height="13"
- layout="topleft"
- left="5"
- name="add_to_outfit_label"
- text_color="LtGray"
- top="4"
- value="Add to Outfit:"
- use_ellipses="true"
- width="150" />
- <button
- follows="top|right"
- height="20"
- image_overlay="Search_Icon"
- is_toggle="true"
- layout="topleft"
- left_pad="5"
- name="filter_button"
- top_delta="0"
- width="20" />
- <combo_box
- follows="top|left|right"
- height="20"
- layout="topleft"
- right="-5"
- name="filter_wearables_combobox"
- top_delta="0"
- width="110"/>
-
<layout_stack
animate="true"
+ border_size="0"
follows="all"
- height="155"
+ height="185"
width="313"
layout="topleft"
name="filter_panels"
- top_pad="5"
+ top="0"
left="0">
<layout_panel
- auto_resize="false"
+ auto_resize="true"
+ background_visible="true"
+ bg_alpha_color="DkGray2"
layout="topleft"
- follows="left|top|right"
+ height="154"
+ label="add_button_and_combobox"
+ name="add_button_and_combobox"
+ width="311"
+ user_resize="false"
+ visible="true">
+
+ <!-- List containing items from the COF and Base outfit -->
+ <panel
+ background_visible="false"
+ class="cof_wearables"
+ filename="panel_cof_wearables.xml"
+ follows="all"
+ height="129"
+ layout="topleft"
+ left="1"
+ name="cof_wearables_list"
+ top="0"
+ width="311" />
+
+ <button
+ follows="left|bottom"
+ height="22"
+ image_pressed="PushButton_Press"
+ image_pressed_selected="PushButton_Selected_Press"
+ image_selected="PushButton_Selected_Press"
+ is_toggle="true"
+ label="Add More..."
+ layout="topleft"
+ left="2"
+ name="show_add_wearables_btn"
+ top_pad="2"
+ width="125" />
+
+ <combo_box
+ follows="left|right|bottom"
+ height="22"
+ layout="topleft"
+ left_pad="5"
+ name="filter_wearables_combobox"
+ top_delta="0"
+ visible="false"
+ width="152"/>
+
+ <button
+ follows="bottom|right"
+ height="22"
+ image_overlay="Search_Icon"
+ image_pressed="PushButton_Press"
+ image_pressed_selected="PushButton_Selected_Press"
+ image_selected="PushButton_Selected_Press"
+ is_toggle="true"
+ layout="topleft"
+ name="filter_button"
+ right="-5"
+ top_delta="0"
+ visible="false"
+ width="20" />
+ </layout_panel>
+
+ <layout_panel
+ auto_resize="false"
+ background_visible="true"
+ bg_alpha_color="DkGray2"
height="30"
- label="IM Control Panel"
name="filter_panel"
width="311"
- user_resize="false"
- visible="false">
+ visible="false"
+ user_resize="false">
+
<filter_editor
background_image="TextField_Search_Off"
enabled="true"
- follows="left|top|right"
+ follows="left|right|top"
font="SansSerif"
label="Filter"
layout="topleft"
@@ -310,132 +266,189 @@ It is calculated as border_size + 2*UIResizeBarOverlap
text_color="black"
text_pad_left="25"
visible="true"/>
- </layout_panel>
- <layout_panel
- auto_resize="true"
- background_visible="true"
- bg_alpha_color="0.107 0.107 0.107 1"
- height="145"
- min_width="130"
- name="inventory_panel"
- width="311"
- user_resize="true">
- <inventory_panel
- allow_multi_select="true"
- background_visible="false"
- border="false"
- follows="left|top|right|bottom"
- height="140"
- layout="topleft"
- left="0"
- mouse_opaque="false"
- name="inventory_items"
- top_pad="5"
- width="310"
- visible="false"/>
- <panel
- name="filtered_wearables_panel"
- background_opaque="true"
- background_visible="false"
- layout="topleft"
- follows="left|top|right|bottom"
- border="false"
- height="140"
- left="0"
- mouse_opaque="false"
- width="311"
- top_delta="0"
- visible="true">
- <wearable_items_list
- color="0.107 0.107 0.107 1"
- name="filtered_wearables_list"
- allow_select="true"
- layout="topleft"
- follows="all"
- multi_select="true"
- width="310"
- height="140"
- left="0"
- top="0"/>
- </panel>
+
</layout_panel>
</layout_stack>
+ </layout_panel>
+
+ <layout_panel
+ background_visible="true"
+ bg_alpha_color="DkGray2"
+ auto_resize="true"
+ default_tab_group="3"
+ height="211"
+ min_height="210"
+ name="add_wearables_panel"
+ width="313"
+ tab_group="2"
+ user_resize="true"
+ visible="false">
+
+ <!-- this icon represent dragbar between layout panels.
+ This is a workaround implemented in EXT-7255 becouse of an issue with layout stack (EXT-7471) -->
+ <icon
+ follows="left|top|right"
+ height="10"
+ image_name="Dragbar"
+ left="0"
+ top_pad="-9"
+ width="313" />
+
+ <inventory_panel
+ allow_multi_select="true"
+ background_visible="false"
+ border="false"
+ follows="left|top|right|bottom"
+ height="210"
+ layout="topleft"
+ left="0"
+ mouse_opaque="false"
+ name="inventory_items"
+ top_pad="5"
+ width="310"
+ visible="false"/>
<panel
- background_visible="true"
- bevel_style="none"
- follows="left|right|bottom"
- height="27"
- label="add_wearables_button_bar"
+ name="filtered_wearables_panel"
+ background_opaque="true"
+ background_visible="false"
layout="topleft"
+ follows="left|top|right|bottom"
+ border="false"
+ height="210"
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"
+ mouse_opaque="false"
+ width="311"
+ top_delta="0"
+ visible="true">
+ <wearable_items_list
+ color="0.107 0.107 0.107 1"
+ name="filtered_wearables_list"
+ allow_select="true"
layout="topleft"
+ follows="all"
+ multi_select="true"
+ width="310"
+ height="210"
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>
+ top="0"/>
</panel>
+
</layout_panel>
</layout_stack>
+
+ <!-- BUTTON BAR -->
+ <panel
+ background_visible="true"
+ bevel_style="none"
+ follows="bottom|left|right"
+ height="27"
+ label="bottom_panel"
+ layout="topleft"
+ left="5"
+ name="no_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="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>
+
+
+ <!-- BUTTON BAR - WEARABLES ADDING MODE -->
+ <panel
+ background_visible="true"
+ bevel_style="none"
+ follows="left|right|bottom"
+ height="27"
+ label="add_wearables_button_bar"
+ layout="topleft"
+ left="5"
+ name="add_wearables_button_bar"
+ top_delta="0"
+ visible="false"
+ 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>
+
+ <!-- SAVE AND REVERT BUTTONS -->
<panel
follows="left|right|bottom"
height="30"
diff --git a/indra/newview/skins/default/xui/en/panel_pick_info.xml b/indra/newview/skins/default/xui/en/panel_pick_info.xml
index ecf5516390..49e1d16f6a 100644
--- a/indra/newview/skins/default/xui/en/panel_pick_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_pick_info.xml
@@ -12,14 +12,16 @@
width="333">
<button
follows="top|right"
- height="23"
- image_overlay="BackArrow_Off"
+ height="24"
+ image_hover_unselected="BackButton_Over"
+ image_pressed="BackButton_Press"
+ image_unselected="BackButton_Off"
layout="topleft"
name="back_btn"
- left="12"
+ left="7"
tab_stop="false"
top="2"
- width="23" />
+ width="30" />
<text
follows="top|left|right"
font="SansSerifHugeBold"
diff --git a/indra/newview/skins/default/xui/en/panel_place_profile.xml b/indra/newview/skins/default/xui/en/panel_place_profile.xml
index 9725e9952a..57ac79686d 100644
--- a/indra/newview/skins/default/xui/en/panel_place_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_place_profile.xml
@@ -140,15 +140,17 @@
value="Parcel_DamageNo_Dark" />
<button
follows="top|right"
- height="23"
- image_overlay="BackArrow_Off"
+ height="24"
+ image_hover_unselected="BackButton_Over"
+ image_pressed="BackButton_Press"
+ image_unselected="BackButton_Off"
layout="topleft"
- left="11"
+ left="7"
name="back_btn"
tool_tip="Back"
tab_stop="false"
top="4"
- width="23" />
+ width="30" />
<text
follows="top|left|right"
font="SansSerifHugeBold"
@@ -318,6 +320,7 @@
value="unknown"
width="268" />
<accordion
+ fit_parent="true"
follows="all"
height="223"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_profile_view.xml b/indra/newview/skins/default/xui/en/panel_profile_view.xml
index 5a96ba2dd2..cc5ba334d6 100644
--- a/indra/newview/skins/default/xui/en/panel_profile_view.xml
+++ b/indra/newview/skins/default/xui/en/panel_profile_view.xml
@@ -18,14 +18,16 @@
</string>
<button
follows="top|right"
- height="23"
- image_overlay="BackArrow_Off"
+ height="24"
+ image_hover_unselected="BackButton_Over"
+ image_pressed="BackButton_Press"
+ image_unselected="BackButton_Off"
layout="topleft"
name="back"
- left="12"
+ left="9"
tab_stop="false"
top="2"
- width="23" />
+ width="30" />
<text_editor
h_pad="0"
v_pad="0"
diff --git a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
index b840fdd31b..c816fd1479 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
@@ -40,14 +40,16 @@
width="18" />
<button
follows="top|right"
- height="23"
- image_overlay="BackArrow_Off"
+ height="24"
+ image_hover_unselected="BackButton_Over"
+ image_pressed="BackButton_Press"
+ image_unselected="BackButton_Off"
layout="topleft"
- left="14"
+ left="12"
name="back_btn"
tab_stop="false"
top="2"
- width="23" />
+ width="30" />
<text
follows="top|left|right"
font="SansSerifHugeBold"
diff --git a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
index d46783e058..faa1ae4e8b 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
@@ -58,14 +58,16 @@
</panel.string>
<button
follows="top|right"
- height="23"
- image_overlay="BackArrow_Off"
+ height="24"
+ image_hover_unselected="BackButton_Over"
+ image_pressed="BackButton_Press"
+ image_unselected="BackButton_Off"
layout="topleft"
- left="10"
+ left="8"
name="back_btn"
tab_stop="false"
top="0"
- width="23" />
+ width="30" />
<text
follows="top|left|right"
font="SansSerifHuge"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 078426d3d9..9d7079a495 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -318,6 +318,10 @@
<!-- For use when we do not have land type back from the server -->
<string name="land_type_unknown">(unknown)</string>
+ <!-- For land type back from the simulator -->
+ <string name="Estate / Full Region">Estate / Full Region</string>
+ <string name="Mainland / Full Region">Mainland / Full Region</string>
+
<!-- File load/save dialogs -->
<string name="all_files">All Files</string>
<string name="sound_files">Sounds</string>
@@ -1826,6 +1830,7 @@ Clears (deletes) the media and all params from the given face.
<!-- Wearable List-->
<string name="NewWearable">New [WEARABLE_ITEM]</string>
+ <string name="CreateNewWearable">Create [WEARABLE_TYPE]</string>
<!-- LLGroupNotify -->
<!-- used in the construction of a Group Notice blue dialog box, buttons, tooltip etc. Seems to be no longer utilized by code in Viewer 2.0 -->
@@ -3154,10 +3159,10 @@ Abuse Report</string>
<string name="Male - Stick tougue out">Male - Stick tougue out</string>
<string name="Male - Wow">Male - Wow</string>
- <string name="FeMale - Excuse me">FeMale - Excuse me</string>
- <string name="FeMale - Get lost">FeMale - Get lost</string>
- <string name="FeMale - Blow kiss">FeMale - Blow kiss</string>
- <string name="FeMale - Boo">FeMale - Boo</string>
+ <string name="Female - Excuse me">Female - Excuse me</string>
+ <string name="Female - Get lost">Female - Get lost</string>
+ <string name="Female - Blow kiss">Female - Blow kiss</string>
+ <string name="Female - Boo">Female - Boo</string>
<string name="Female - Bored">Female - Bored</string>
<string name="Female - Hey">Female - Hey</string>
<string name="Female - Laugh">Female - Laugh</string>
@@ -3174,6 +3179,7 @@ Abuse Report</string>
<!-- language specific white-space characters, delimiters, spacers, item separation symbols -->
<string name="sentences_separator" value=" "></string>
+ <string name="words_separator">, </string>
<string name="server_is_down">
Despite our best efforts, something unexpected has gone wrong.
diff --git a/indra/newview/skins/default/xui/en/widgets/button.xml b/indra/newview/skins/default/xui/en/widgets/button.xml
index c4f0fe5208..2d0a1728d5 100644
--- a/indra/newview/skins/default/xui/en/widgets/button.xml
+++ b/indra/newview/skins/default/xui/en/widgets/button.xml
@@ -2,6 +2,7 @@
<!-- Additional attributes:
image_pressed
image_pressed_selected
+ image_flash
-->
<button image_unselected="PushButton_Off"
image_selected="PushButton_Selected"
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..c37ead0be2 100644
--- a/indra/newview/skins/default/xui/en/widgets/tab_container.xml
+++ b/indra/newview/skins/default/xui/en/widgets/tab_container.xml
@@ -11,6 +11,12 @@ label_pad_left - padding to the left of tab button labels
tab_height="21"
label_pad_bottom="2"
label_pad_left="4">
+ <!--
+ Possible additional attributes for tabs:
+ tab_bottom_image_flash
+ tab_left_image_flash
+ tab_top_image_flash
+ -->
<first_tab tab_top_image_unselected="TabTop_Left_Off"
tab_top_image_selected="TabTop_Left_Selected"
tab_bottom_image_unselected="Toolbar_Left_Off"
diff --git a/indra/newview/skins/default/xui/pl/floater_about_land.xml b/indra/newview/skins/default/xui/pl/floater_about_land.xml
index e4908deb07..163868f200 100644
--- a/indra/newview/skins/default/xui/pl/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/pl/floater_about_land.xml
@@ -196,13 +196,13 @@ Idź do Świat &gt; O Posiadłości albo wybierz inną posiadłość żeby pokaz
<text name="resellable_lbl">
Odsprzedaj:
</text>
- <text left="115" name="resellable_clause" width="338">
+ <text left="115" name="resellable_clause">
Posiadłość zakupiona w tym Regionie nie może być odsprzedana.
</text>
<text name="changeable_lbl">
Podziel:
</text>
- <text left="115" name="changeable_clause" width="338">
+ <text left="115" name="changeable_clause">
Posiadłość zakupiona w tym Regionie nie może być
łączona/dzielona.
</text>