From 1d1377079b08ada11bc33cc88ee25761b1954d5c Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 14 Jul 2010 11:48:33 -0700 Subject: EXT-8300 FIX Creator's icon overlaps description text on object's mini-inspector reviewed by Leyla --- indra/llui/lltextbase.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index ed03645944..d3b2a368a5 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -2282,6 +2282,12 @@ void LLTextBase::updateRects() ? llmax(mVisibleTextRect.getWidth(), mTextBoundingRect.mRight) : mVisibleTextRect.getWidth(); + if (!mScroller) + { + // push doc rect to top of text widget + doc_rect.translate(0, mVisibleTextRect.getHeight() - doc_rect.mTop); + } + mDocumentView->setShape(doc_rect); //update mVisibleTextRect *after* mDocumentView has been resized @@ -2786,9 +2792,9 @@ F32 LLLineBreakTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 se } LLImageTextSegment::LLImageTextSegment(LLStyleConstSP style,S32 pos,class LLTextBase& editor) - :LLTextSegment(pos,pos+1) - ,mStyle( style ) - ,mEditor(editor) +: LLTextSegment(pos,pos+1), + mStyle( style ), + mEditor(editor) { } -- cgit v1.3 From 5a56c79fd45b5a422b1f9139995fb3d78ba7815f Mon Sep 17 00:00:00 2001 From: Andrew Dyukov Date: Thu, 15 Jul 2010 15:06:35 +0300 Subject: EXT-7511 FIXED Fixed disappearance of selected item's border in flatlistviews. - This issue was a regression caused by EXT-8052. Bug was caused by setting visibility of border to FALSE without respect to boolean argument passed to setNoItemsCommentVisible(). setNoItemsCommentVisible() is called on every rearrange, so border disappeared quite often. Fixed it by setting border's visibility depending on passed argument. Reviewed by Mike Antipov at https://codereview.productengine.com/secondlife/r/764/ --HG-- branch : product-engine --- indra/llui/llflatlistview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp index 3c79da64f9..12004e2a75 100644 --- a/indra/llui/llflatlistview.cpp +++ b/indra/llui/llflatlistview.cpp @@ -1079,7 +1079,7 @@ void LLFlatListView::setNoItemsCommentVisible(bool visible) const mNoItemsCommentTextbox->setRect(comment_rect); */ } - mSelectedItemsBorder->setVisible(FALSE); + mSelectedItemsBorder->setVisible(!visible); mNoItemsCommentTextbox->setVisible(visible); } } -- cgit v1.3 From 200ad6dca75067c62d0e10a08d1e30b995cdd7d0 Mon Sep 17 00:00:00 2001 From: Alexei Arabadji Date: Thu, 15 Jul 2010 18:57:01 +0300 Subject: EXT-8303 FIXED [crashhunters] Crash in inventory_offer_mute_callback Details: Instead of copying shared pointer, raw pointer was used, that cause crash, since notification responder object was accessed after it was destroyed. Replaced usage copying of raw pointer instead of copying shared pointer of notification responder object, that should live after notification destroyed. --HG-- branch : product-engine --- indra/llui/llnotifications.cpp | 1 + indra/llui/llnotifications.h | 2 ++ indra/newview/llviewermessage.cpp | 19 ++++++++++++++++--- 3 files changed, 19 insertions(+), 3 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 9e272a0949..7fa3c2cf65 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -375,6 +375,7 @@ LLNotification::LLNotification(const LLSD& sd) : LLSD LLNotification::asLLSD() { LLSD output; + output["id"] = mId; output["name"] = mTemplatep->mName; output["form"] = getForm()->asLLSD(); output["substitutions"] = mSubstitutions; diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index 8bfada0e71..1cdd744a68 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -353,6 +353,8 @@ public: } }; + LLNotificationResponderPtr getResponderPtr() { return mResponder; } + private: LLUUID mId; diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 53fb01aec3..fe6988c526 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -1215,8 +1215,9 @@ bool highlight_offered_object(const LLUUID& obj_id) void inventory_offer_mute_callback(const LLUUID& blocked_id, const std::string& first_name, const std::string& last_name, - BOOL is_group, LLOfferInfo* offer = NULL) + BOOL is_group, boost::shared_ptr offer_ptr) { + LLOfferInfo* offer = dynamic_cast(offer_ptr.get()); std::string from_name; LLMute::EType type; if (is_group) @@ -1406,7 +1407,13 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& // * we can't build two messages at once. if (2 == button) // Block { - gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,_4,this)); + LLNotificationPtr notification_ptr = LLNotifications::instance().find(notification["id"].asUUID()); + + llassert(notification_ptr != NULL); + if (notification_ptr != NULL) + { + gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,_4, notification_ptr->getResponderPtr())); + } } std::string from_string; // Used in the pop-up. @@ -1540,7 +1547,13 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const // * we can't build two messages at once. if (2 == button) { - gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,_4,this)); + LLNotificationPtr notification_ptr = LLNotifications::instance().find(notification["id"].asUUID()); + + llassert(notification_ptr != NULL); + if (notification_ptr != NULL) + { + gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,_4, notification_ptr->getResponderPtr())); + } } LLMessageSystem* msg = gMessageSystem; -- cgit v1.3 From d3d39b98aa0b0161be4e573c440ce642617d6d15 Mon Sep 17 00:00:00 2001 From: Mike Antipov Date: Tue, 20 Jul 2010 15:17:46 +0300 Subject: EXT-8458 FIXED ensure that static pointer to instance of LLPanelStandStopFlying is always valid to prevent crash. Consequences of root cause: Static pointer to LLPanelStandStopFlying in LLPanelStandStopFlying::getInstance() becomes invalid when the instance of the LLPanelStandStopFlying is a child of floater while it is destroying. Next usage of that pointed cause a crash. Root Cause: 1. LLFloater::closeFloater sets floater invisible and marks floater as "dead" but does not destroy it. 2. But that instance was still in LLFloaterReg map. It is removed in LLFloater's destructor. 3. So it was possible on low fps to get "dead" floater with LLFloaterReg, LLFloaterMove in this case. 4. Then LLMortician deleted floater instance shown on previous step. Call of setVisible(false) from the LLFloater's destructor does not call overridden LLFloaterMove's method (which is expected behavior.) So, child panel LLPanelStandStopFlying was not re-parented to Main View and was destroyed with LLFloaterMove. That leaded to the "Top Reason" described above. FIX: 1. Ensure that LLPanelStandStopFlying is not a child of LLFloaterMove on its destroying. 2. Synchronized removing of a floater instance from the LLFloaterReg when it is marked as "dead". Note: both changes fixes this bug independently, but I included both of them into result patch to avoid similar but in the future. Reviewed by Vadim Savchuk at https://codereview.productengine.com/secondlife/r/781/ --HG-- branch : product-engine --- indra/llui/llfloater.cpp | 8 ++++++++ indra/llui/llfloater.h | 2 +- indra/newview/llmoveview.cpp | 10 ++++++++++ indra/newview/llmoveview.h | 2 +- 4 files changed, 20 insertions(+), 2 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 39a6855273..22d6f6ca52 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -451,6 +451,14 @@ void LLFloater::enableResizeCtrls(bool enable) } } +void LLFloater::destroy() +{ + // LLFloaterReg should be synchronized with "dead" floater to avoid returning dead instance before + // it was deleted via LLMortician::updateClass(). See EXT-8458. + LLFloaterReg::removeInstance(mInstanceName, mKey); + die(); +} + // virtual LLFloater::~LLFloater() { diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 3ea035777c..42f422f91c 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -308,7 +308,7 @@ protected: BOOL getAutoFocus() const { return mAutoFocus; } LLDragHandle* getDragHandle() const { return mDragHandle; } - void destroy() { die(); } // Don't call this directly. You probably want to call closeFloater() + void destroy(); // Don't call this directly. You probably want to call closeFloater() virtual void onClickCloseBtn(); diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp index 6ae4a5e5e4..fc41137686 100644 --- a/indra/newview/llmoveview.cpp +++ b/indra/newview/llmoveview.cpp @@ -83,6 +83,16 @@ LLFloaterMove::LLFloaterMove(const LLSD& key) { } +LLFloaterMove::~LLFloaterMove() +{ + // Ensure LLPanelStandStopFlying panel is not among floater's children. See EXT-8458. + setVisible(FALSE); + + // Otherwise it can be destroyed and static pointer in LLPanelStandStopFlying::getInstance() will become invalid. + // Such situation was possible when LLFloaterReg returns "dead" instance of floater. + // Should not happen after LLFloater::destroy was modified to remove "dead" instances from LLFloaterReg. +} + // virtual BOOL LLFloaterMove::postBuild() { diff --git a/indra/newview/llmoveview.h b/indra/newview/llmoveview.h index d463861188..43b0342744 100644 --- a/indra/newview/llmoveview.h +++ b/indra/newview/llmoveview.h @@ -51,7 +51,7 @@ class LLFloaterMove private: LLFloaterMove(const LLSD& key); - ~LLFloaterMove() {} + ~LLFloaterMove(); public: /*virtual*/ BOOL postBuild(); -- cgit v1.3 From 20ce01811e3a5565a27de150e4658e996bac3108 Mon Sep 17 00:00:00 2001 From: Richard Nelson Date: Tue, 20 Jul 2010 18:39:36 -0700 Subject: EXT-7654 FIX About Land Floater> Icons missing --- indra/llui/llcheckboxctrl.cpp | 2 +- indra/newview/llfloaterland.cpp | 3 ++- indra/newview/skins/default/xui/en/floater_about_land.xml | 6 ++++-- 3 files changed, 7 insertions(+), 4 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp index 3d32157406..6f81f5434c 100644 --- a/indra/llui/llcheckboxctrl.cpp +++ b/indra/llui/llcheckboxctrl.cpp @@ -191,7 +191,7 @@ void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent) static LLUICachedControl llcheckboxctrl_btn_size ("UICheckboxctrlBtnSize", 0); const S32 FUDGE = 10; - S32 text_width = mFont->getWidth( mLabel->getText() ) + FUDGE; + S32 text_width = mLabel->getTextBoundingRect().getWidth() + FUDGE; S32 text_height = llround(mFont->getLineHeight()); LLRect label_rect; label_rect.setOriginAndSize( diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 913bb676b0..f0ed659f5a 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -2088,7 +2088,8 @@ void LLPanelLandOptions::refresh() LLStyle::Params style; style.image(LLUI::getUIImage(gFloaterView->getParentFloater(this)->getString("maturity_icon_moderate"))); LLCheckBoxWithTBAcess* fullaccess_mature_ctrl = (LLCheckBoxWithTBAcess*)mMatureCtrl; - fullaccess_mature_ctrl->getTextBox()->setText(std::string("icon"),style); + fullaccess_mature_ctrl->getTextBox()->setText(LLStringExplicit("")); + fullaccess_mature_ctrl->getTextBox()->appendImageSegment(style); fullaccess_mature_ctrl->getTextBox()->appendText(getString("mature_check_mature"), false); fullaccess_mature_ctrl->setToolTip(getString("mature_check_mature_tooltip")); fullaccess_mature_ctrl->reshape(fullaccess_mature_ctrl->getRect().getWidth(), fullaccess_mature_ctrl->getRect().getHeight(), FALSE); 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 68e36ff0b3..8d32097c3b 100644 --- a/indra/newview/skins/default/xui/en/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en/floater_about_land.xml @@ -1467,13 +1467,15 @@ Only large parcels can be listed in search. + width="200" /> Date: Wed, 21 Jul 2010 19:00:57 +0300 Subject: EXT-8164 FIXED (Accordions should be reset to default state after Edit Outfit panel reopening) Now accordion on panels 'Edit Outfit', 'Editing Shape', 'Editing Hair', 'Editing Eyes', 'Editing Skin', 'Group Profile' and 'Place Profile' are reset when the panels are closed and then opened again. Reviewed by Vadim Savchuk at https://codereview.productengine.com/secondlife/r/782/ --HG-- branch : product-engine --- indra/llui/llaccordionctrl.cpp | 25 ++++++++++++++++++++++ indra/llui/llaccordionctrl.h | 1 + indra/newview/llcofwearables.cpp | 34 +++++++++++++++++++++++------ indra/newview/llcofwearables.h | 4 ++++ indra/newview/llpaneleditwearable.cpp | 38 +++++++++++++++++++++++++++++++++ indra/newview/llpaneleditwearable.h | 5 +++++ indra/newview/llpanelgroup.cpp | 12 +++++++++++ indra/newview/llpanelgroup.h | 3 ++- indra/newview/llpaneloutfitedit.cpp | 12 +++++++++++ indra/newview/llpaneloutfitedit.h | 2 ++ indra/newview/llpanelplaceprofile.cpp | 9 +++++++- indra/newview/llpanelplaceprofile.h | 2 ++ indra/newview/llsidepanelappearance.cpp | 21 ++++++++++++++++-- 13 files changed, 157 insertions(+), 11 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llaccordionctrl.cpp b/indra/llui/llaccordionctrl.cpp index 673631f99a..2bc8ea054a 100644 --- a/indra/llui/llaccordionctrl.cpp +++ b/indra/llui/llaccordionctrl.cpp @@ -811,6 +811,31 @@ void LLAccordionCtrl::reset () mScrollbar->setDocPos(0); } +void LLAccordionCtrl::expandDefaultTab() +{ + if (mAccordionTabs.size() > 0) + { + LLAccordionCtrlTab* tab = mAccordionTabs.front(); + + if (!tab->getDisplayChildren()) + { + tab->setDisplayChildren(true); + } + + for (size_t i = 1; i < mAccordionTabs.size(); ++i) + { + tab = mAccordionTabs[i]; + + if (tab->getDisplayChildren()) + { + tab->setDisplayChildren(false); + } + } + + arrange(); + } +} + void LLAccordionCtrl::sort() { if (!mTabComparator) diff --git a/indra/llui/llaccordionctrl.h b/indra/llui/llaccordionctrl.h index b5fdf796cd..8241ee1518 100644 --- a/indra/llui/llaccordionctrl.h +++ b/indra/llui/llaccordionctrl.h @@ -122,6 +122,7 @@ public: S32 notifyParent(const LLSD& info); void reset (); + void expandDefaultTab(); void setComparator(const LLTabComparator* comp) { mTabComparator = comp; } void sort(); diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp index f75ea23351..f356a04fa4 100644 --- a/indra/newview/llcofwearables.cpp +++ b/indra/newview/llcofwearables.cpp @@ -284,7 +284,8 @@ LLCOFWearables::LLCOFWearables() : LLPanel(), mAttachmentsTab(NULL), mBodyPartsTab(NULL), mLastSelectedTab(NULL), - mCOFVersion(-1) + mCOFVersion(-1), + mAccordionCtrl(NULL) { mClothingMenu = new CofClothingContextMenu(this); mAttachmentMenu = new CofAttachmentContextMenu(this); @@ -336,6 +337,8 @@ BOOL LLCOFWearables::postBuild() mTab2AssetType[mAttachmentsTab] = LLAssetType::AT_OBJECT; mTab2AssetType[mBodyPartsTab] = LLAssetType::AT_BODYPART; + mAccordionCtrl = getChild("cof_wearables_accordion"); + return LLPanel::postBuild(); } @@ -652,18 +655,35 @@ LLAssetType::EType LLCOFWearables::getExpandedAccordionAssetType() typedef std::map type_map_t; static type_map_t type_map; - static LLAccordionCtrl* accordion_ctrl = getChild("cof_wearables_accordion"); - const LLAccordionCtrlTab* expanded_tab = accordion_ctrl->getExpandedTab(); - return get_if_there(mTab2AssetType, expanded_tab, LLAssetType::AT_NONE); + if (mAccordionCtrl != NULL) + { + const LLAccordionCtrlTab* expanded_tab = mAccordionCtrl->getExpandedTab(); + + return get_if_there(mTab2AssetType, expanded_tab, LLAssetType::AT_NONE); } + return LLAssetType::AT_NONE; +} + LLAssetType::EType LLCOFWearables::getSelectedAccordionAssetType() +{ + if (mAccordionCtrl != NULL) { - static LLAccordionCtrl* accordion_ctrl = getChild("cof_wearables_accordion"); - const LLAccordionCtrlTab* selected_tab = accordion_ctrl->getSelectedTab(); + const LLAccordionCtrlTab* selected_tab = mAccordionCtrl->getSelectedTab(); - return get_if_there(mTab2AssetType, selected_tab, LLAssetType::AT_NONE); + return get_if_there(mTab2AssetType, selected_tab, LLAssetType::AT_NONE); + } + + return LLAssetType::AT_NONE; +} + +void LLCOFWearables::expandDefaultAccordionTab() +{ + if (mAccordionCtrl != NULL) + { + mAccordionCtrl->expandDefaultTab(); + } } void LLCOFWearables::onListRightClick(LLUICtrl* ctrl, S32 x, S32 y, LLListContextMenu* menu) diff --git a/indra/newview/llcofwearables.h b/indra/newview/llcofwearables.h index d005b75eaa..cd7cc060e5 100644 --- a/indra/newview/llcofwearables.h +++ b/indra/newview/llcofwearables.h @@ -40,6 +40,7 @@ #include "llappearancemgr.h" #include "llinventorymodel.h" +class LLAccordionCtrl; class LLAccordionCtrlTab; class LLListContextMenu; class LLPanelClothingListItem; @@ -87,6 +88,7 @@ public: LLAssetType::EType getExpandedAccordionAssetType(); LLAssetType::EType getSelectedAccordionAssetType(); + void expandDefaultAccordionTab(); LLCOFCallbacks& getCOFCallbacks() { return mCOFCallbacks; } @@ -125,6 +127,8 @@ protected: LLListContextMenu* mAttachmentMenu; LLListContextMenu* mBodyPartMenu; + LLAccordionCtrl* mAccordionCtrl; + /* COF category version since last refresh */ S32 mCOFVersion; }; diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index ec685405ed..62e6cdc79d 100644 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -47,6 +47,7 @@ #include "llvoavatarself.h" #include "lltexteditor.h" #include "lltextbox.h" +#include "llaccordionctrl.h" #include "llaccordionctrltab.h" #include "llagentwearables.h" #include "llscrollingpanelparam.h" @@ -666,6 +667,35 @@ void LLPanelEditWearable::updateAvatarHeightLabel() mTxtAvatarHeight->appendText(this->mReplacementMetricUrl, false, param); } +void LLPanelEditWearable::onWearablePanelVisibilityChange(const LLSD &in_visible_chain, LLAccordionCtrl* accordion_ctrl) +{ + if (in_visible_chain.asBoolean() && accordion_ctrl != NULL) + { + accordion_ctrl->expandDefaultTab(); + } +} + +void LLPanelEditWearable::setWearablePanelVisibilityChangeCallback(LLPanel* bodypart_panel) +{ + if (bodypart_panel != NULL) + { + LLAccordionCtrl* accordion_ctrl = bodypart_panel->getChild("wearable_accordion"); + + if (accordion_ctrl != NULL) + { + bodypart_panel->setVisibleCallback( + boost::bind(&LLPanelEditWearable::onWearablePanelVisibilityChange, this, _2, accordion_ctrl)); + } + else + { + llwarns << "accordion_ctrl is NULL" << llendl; + } + } + else + { + llwarns << "bodypart_panel is NULL" << llendl; + } +} // virtual BOOL LLPanelEditWearable::postBuild() @@ -695,6 +725,14 @@ BOOL LLPanelEditWearable::postBuild() mPanelEyes = getChild("edit_eyes_panel"); mPanelHair = getChild("edit_hair_panel"); + // Setting the visibility callback is applied only to the bodyparts panel + // because currently they are the only ones whose 'wearable_accordion' has + // multiple accordion tabs (see EXT-8164 for details). + setWearablePanelVisibilityChangeCallback(mPanelShape); + setWearablePanelVisibilityChangeCallback(mPanelSkin); + setWearablePanelVisibilityChangeCallback(mPanelEyes); + setWearablePanelVisibilityChangeCallback(mPanelHair); + //clothes mPanelShirt = getChild("edit_shirt_panel"); mPanelPants = getChild("edit_pants_panel"); diff --git a/indra/newview/llpaneleditwearable.h b/indra/newview/llpaneleditwearable.h index dbda90fe9f..c0823dd3fa 100644 --- a/indra/newview/llpaneleditwearable.h +++ b/indra/newview/llpaneleditwearable.h @@ -39,6 +39,7 @@ #include "llvoavatardefines.h" #include "llwearabletype.h" +class LLAccordionCtrl; class LLCheckBoxCtrl; class LLWearable; class LLTextBox; @@ -113,6 +114,10 @@ private: // updates avatar height label void updateAvatarHeightLabel(); + void onWearablePanelVisibilityChange(const LLSD &in_visible_chain, LLAccordionCtrl* accordion_ctrl); + + void setWearablePanelVisibilityChangeCallback(LLPanel* bodypart_panel); + // the pointer to the wearable we're editing. NULL means we're not editing a wearable. LLWearable *mWearablePtr; LLViewerInventoryItem* mWearableItem; diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp index d997b83cbb..38e776b195 100644 --- a/indra/newview/llpanelgroup.cpp +++ b/indra/newview/llpanelgroup.cpp @@ -182,6 +182,11 @@ BOOL LLPanelGroup::postBuild() LLPanelGroupTab* panel_notices = findChild("group_notices_tab_panel"); LLPanelGroupTab* panel_land = findChild("group_land_tab_panel"); + if (LLAccordionCtrl* accordion_ctrl = getChild("groups_accordion")) + { + setVisibleCallback(boost::bind(&LLPanelGroup::onVisibilityChange, this, _2, accordion_ctrl)); + } + if(panel_general) mTabs.push_back(panel_general); if(panel_roles) mTabs.push_back(panel_roles); if(panel_notices) mTabs.push_back(panel_notices); @@ -305,6 +310,13 @@ void LLPanelGroup::onBtnCancel() onBackBtnClick(); } +void LLPanelGroup::onVisibilityChange(const LLSD &in_visible_chain, LLAccordionCtrl* accordion_ctrl) +{ + if (in_visible_chain.asBoolean() && accordion_ctrl != NULL) + { + accordion_ctrl->expandDefaultTab(); + } +} void LLPanelGroup::changed(LLGroupChange gc) { diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h index 13a03b0713..2b21e9895a 100644 --- a/indra/newview/llpanelgroup.h +++ b/indra/newview/llpanelgroup.h @@ -42,6 +42,7 @@ class LLOfferInfo; const S32 UPDATE_MEMBERS_PER_FRAME = 500; // Forward declares +class LLAccordionCtrl; class LLPanelGroupTab; class LLTabContainer; class LLAgent; @@ -102,6 +103,7 @@ protected: void onBackBtnClick(); void onBtnJoin(); void onBtnCancel(); + void onVisibilityChange(const LLSD &in_visible_chain, LLAccordionCtrl* accordion_ctrl); static void onBtnApply(void*); static void onBtnRefresh(void*); @@ -126,7 +128,6 @@ protected: LLButton* mButtonJoin; LLUICtrl* mJoinText; - }; class LLPanelGroupTab : public LLPanel diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index e12344ce9d..c09aff44da 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -1027,6 +1027,18 @@ bool LLPanelOutfitEdit::switchPanels(LLPanel* switch_from_panel, LLPanel* switch return false; } +void LLPanelOutfitEdit::resetAccordionState() +{ + if (mCOFWearables != NULL) + { + mCOFWearables->expandDefaultAccordionTab(); + } + else + { + llwarns << "mCOFWearables is NULL" << llendl; + } +} + void LLPanelOutfitEdit::onGearButtonClick(LLUICtrl* clicked_button) { if(!mGearMenu) diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h index ad128b1055..13ceda98a6 100644 --- a/indra/newview/llpaneloutfitedit.h +++ b/indra/newview/llpaneloutfitedit.h @@ -183,6 +183,8 @@ public: */ bool switchPanels(LLPanel* switch_from_panel, LLPanel* switch_to_panel); + void resetAccordionState(); + virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void* cargo_data, diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp index 1f979b0ef1..08835dc2b8 100644 --- a/indra/newview/llpanelplaceprofile.cpp +++ b/indra/newview/llpanelplaceprofile.cpp @@ -79,7 +79,8 @@ LLPanelPlaceProfile::LLPanelPlaceProfile() : LLPanelPlaceInfo(), mForSalePanel(NULL), mYouAreHerePanel(NULL), - mSelectedParcelID(-1) + mSelectedParcelID(-1), + mAccordionCtrl(NULL) {} // virtual @@ -139,6 +140,7 @@ BOOL LLPanelPlaceProfile::postBuild() mSubdivideText = getChild("subdivide"); mResaleText = getChild("resale"); mSaleToText = getChild("sale_to"); + mAccordionCtrl = getChild("advanced_info_accordion"); icon_pg = getString("icon_PG"); icon_m = getString("icon_M"); @@ -278,6 +280,11 @@ void LLPanelPlaceProfile::handleVisibilityChange(BOOL new_visibility) parcel_mgr->deselectUnused(); } } + + if (mAccordionCtrl != NULL) + { + mAccordionCtrl->expandDefaultTab(); + } } void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel, diff --git a/indra/newview/llpanelplaceprofile.h b/indra/newview/llpanelplaceprofile.h index e77b441567..49c13ff5e3 100644 --- a/indra/newview/llpanelplaceprofile.h +++ b/indra/newview/llpanelplaceprofile.h @@ -35,6 +35,7 @@ #include "llpanelplaceinfo.h" +class LLAccordionCtrl; class LLIconCtrl; class LLTextEditor; @@ -118,6 +119,7 @@ private: LLTextEditor* mSubdivideText; LLTextEditor* mResaleText; LLTextBox* mSaleToText; + LLAccordionCtrl* mAccordionCtrl; }; #endif // LL_LLPANELPLACEPROFILE_H diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index 7a7ffb9983..98cd0b88eb 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -190,13 +190,16 @@ void LLSidepanelAppearance::onVisibilityChange(const LLSD &new_visibility) { if (new_visibility.asBoolean()) { - if ((mOutfitEdit && mOutfitEdit->getVisible()) || (mEditWearable && mEditWearable->getVisible())) + bool is_outfit_edit_visible = mOutfitEdit && mOutfitEdit->getVisible(); + bool is_wearable_edit_visible = mEditWearable && mEditWearable->getVisible(); + + if (is_outfit_edit_visible || is_wearable_edit_visible) { if (!gAgentCamera.cameraCustomizeAvatar() && gSavedSettings.getBOOL("AppearanceCameraMovement")) { gAgentCamera.changeCameraToCustomizeAvatar(); } - if (mEditWearable && mEditWearable->getVisible()) + if (is_wearable_edit_visible) { LLWearable *wearable_ptr = mEditWearable->getWearable(); if (gAgentWearables.getWearableIndex(wearable_ptr) == LLAgentWearables::MAX_CLOTHING_PER_TYPE) @@ -205,6 +208,11 @@ void LLSidepanelAppearance::onVisibilityChange(const LLSD &new_visibility) showOutfitEditPanel(); } } + + if (is_outfit_edit_visible) + { + mOutfitEdit->resetAccordionState(); + } } } else @@ -283,6 +291,15 @@ void LLSidepanelAppearance::showOutfitsInventoryPanel() void LLSidepanelAppearance::showOutfitEditPanel() { + // Accordion's state must be reset in all cases except the one when user + // is returning back to the mOutfitEdit panel from the mEditWearable panel. + // The simplest way to control this is to check the visibility state of the mEditWearable + // BEFORE it is changed by the call to the toggleWearableEditPanel(FALSE, NULL, TRUE). + if (mEditWearable != NULL && !mEditWearable->getVisible() && mOutfitEdit != NULL) + { + mOutfitEdit->resetAccordionState(); + } + togglMyOutfitsPanel(FALSE); toggleWearableEditPanel(FALSE, NULL, TRUE); // don't switch out of edit appearance mode toggleOutfitEditPanel(TRUE); -- cgit v1.3 From 98bd370952bfa54f629991b77c3e68b3064e5c9c Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 22 Jul 2010 12:09:23 -0700 Subject: fix for checkbox truncation --- indra/llui/llcheckboxctrl.cpp | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp index 6f81f5434c..0c524cd470 100644 --- a/indra/llui/llcheckboxctrl.cpp +++ b/indra/llui/llcheckboxctrl.cpp @@ -81,17 +81,6 @@ LLCheckBoxCtrl::LLCheckBoxCtrl(const LLCheckBoxCtrl::Params& p) // must be big enough to hold all children setUseBoundingRect(TRUE); - // Label (add a little space to make sure text actually renders) - const S32 FUDGE = 10; - S32 text_width = mFont->getWidth( p.label ) + FUDGE; - S32 text_height = llround(mFont->getLineHeight()); - LLRect label_rect; - label_rect.setOriginAndSize( - llcheckboxctrl_hpad + llcheckboxctrl_btn_size + llcheckboxctrl_spacing, - llcheckboxctrl_vpad + 1, // padding to get better alignment - text_width + llcheckboxctrl_hpad, - text_height ); - // *HACK Get rid of this with SL-55508... // this allows blank check boxes and radio boxes for now std::string local_label = p.label; @@ -101,7 +90,6 @@ LLCheckBoxCtrl::LLCheckBoxCtrl(const LLCheckBoxCtrl::Params& p) } LLTextBox::Params tbparams = p.label_text; - tbparams.rect(label_rect); tbparams.initial_value(local_label); if (p.font.isProvided()) { @@ -111,6 +99,17 @@ LLCheckBoxCtrl::LLCheckBoxCtrl(const LLCheckBoxCtrl::Params& p) mLabel = LLUICtrlFactory::create (tbparams); addChild(mLabel); + S32 text_width = mLabel->getTextBoundingRect().getWidth(); + S32 text_height = llround(mFont->getLineHeight()); + LLRect label_rect; + label_rect.setOriginAndSize( + llcheckboxctrl_hpad + llcheckboxctrl_btn_size + llcheckboxctrl_spacing, + llcheckboxctrl_vpad + 1, // padding to get better alignment + text_width + llcheckboxctrl_hpad, + text_height ); + mLabel->setShape(label_rect); + + // Button // Note: button cover the label by extending all the way to the right. LLRect btn_rect; @@ -190,8 +189,7 @@ void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent) static LLUICachedControl llcheckboxctrl_vpad ("UICheckboxctrlVPad", 0); static LLUICachedControl llcheckboxctrl_btn_size ("UICheckboxctrlBtnSize", 0); - const S32 FUDGE = 10; - S32 text_width = mLabel->getTextBoundingRect().getWidth() + FUDGE; + S32 text_width = mLabel->getTextBoundingRect().getWidth(); S32 text_height = llround(mFont->getLineHeight()); LLRect label_rect; label_rect.setOriginAndSize( @@ -199,7 +197,7 @@ void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent) llcheckboxctrl_vpad, text_width, text_height ); - mLabel->setRect(label_rect); + mLabel->setShape(label_rect); LLRect btn_rect; btn_rect.setOriginAndSize( @@ -207,7 +205,7 @@ void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent) llcheckboxctrl_vpad, llcheckboxctrl_btn_size + llcheckboxctrl_spacing + text_width, llmax( text_height, llcheckboxctrl_btn_size() ) ); - mButton->setRect( btn_rect ); + mButton->setShape( btn_rect ); LLUICtrl::reshape(width, height, called_from_parent); } -- cgit v1.3 From 3c4f82b2984c0cf70b2bc61190495cf9cf1a6aad Mon Sep 17 00:00:00 2001 From: Mike Antipov Date: Fri, 23 Jul 2010 10:26:28 +0300 Subject: EXT-8318 ADDITIONAL FIXED ensure that thousands separator is in utf8 format (on Windows) before converting it to LLWString. Problem on Windows: ================== LLPanelMainInventory::updateItemcountText() formats number using viewer locale. non-break space is detected as unknown symbols while converting utf8str_to_wstring when formatted text is set to LLTextBox. FIX: === Added converting of string to multi-byte string and then to utf8 string while formatting on Windows. created opposite to "ll_convert_wide_to_string" function "ll_convert_string_to_wide" and helper function to call both of them. It is used now to convert result of formatted string while formatting integer number in locale. Fix affects Windows only. Reviewed by Richard Nelson at https://codereview.productengine.com/secondlife/r/775/ --HG-- branch : product-engine --- indra/llcommon/llformat.cpp | 32 +++++++++++++++++++++---- indra/llcommon/llformat.h | 4 ++++ indra/llcommon/llstring.cpp | 31 +++++++++++++++++++++--- indra/llcommon/llstring.h | 15 +++++++++++- indra/llui/llresmgr.cpp | 4 ++-- indra/win_crash_logger/llcrashloggerwindows.cpp | 6 ++--- 6 files changed, 79 insertions(+), 13 deletions(-) (limited to 'indra/llui') diff --git a/indra/llcommon/llformat.cpp b/indra/llcommon/llformat.cpp index cf509bee14..689f649d0a 100644 --- a/indra/llcommon/llformat.cpp +++ b/indra/llcommon/llformat.cpp @@ -37,16 +37,40 @@ #include -std::string llformat(const char *fmt, ...) +// common used function with va_list argument +// wrapper for vsnprintf to be called from llformatXXX functions. +static void va_format(std::string& out, const char *fmt, va_list va) { char tstr[1024]; /* Flawfinder: ignore */ - va_list va; - va_start(va, fmt); #if LL_WINDOWS _vsnprintf(tstr, 1024, fmt, va); #else vsnprintf(tstr, 1024, fmt, va); /* Flawfinder: ignore */ #endif + out.assign(tstr); +} + +std::string llformat(const char *fmt, ...) +{ + std::string res; + va_list va; + va_start(va, fmt); + va_format(res, fmt, va); va_end(va); - return std::string(tstr); + return res; +} + +std::string llformat_to_utf8(const char *fmt, ...) +{ + std::string res; + va_list va; + va_start(va, fmt); + va_format(res, fmt, va); + va_end(va); + +#if LL_WINDOWS + // made converting to utf8. See EXT-8318. + res = ll_convert_string_to_utf8_string(res); +#endif + return res; } diff --git a/indra/llcommon/llformat.h b/indra/llcommon/llformat.h index dc64edb26d..17d8b4a8ad 100644 --- a/indra/llcommon/llformat.h +++ b/indra/llcommon/llformat.h @@ -42,4 +42,8 @@ std::string LL_COMMON_API llformat(const char *fmt, ...); +// the same version as above but ensures that returned string is in utf8 on windows +// to enable correct converting utf8_to_wstring. +std::string LL_COMMON_API llformat_to_utf8(const char *fmt, ...); + #endif // LL_LLFORMAT_H diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index 1561bda201..804c00fd60 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -633,14 +633,14 @@ namespace snprintf_hack } } -std::string ll_convert_wide_to_string(const wchar_t* in) +std::string ll_convert_wide_to_string(const wchar_t* in, unsigned int code_page) { std::string out; if(in) { int len_in = wcslen(in); int len_out = WideCharToMultiByte( - CP_ACP, + code_page, 0, in, len_in, @@ -655,7 +655,7 @@ std::string ll_convert_wide_to_string(const wchar_t* in) if(pout) { WideCharToMultiByte( - CP_ACP, + code_page, 0, in, len_in, @@ -669,6 +669,31 @@ std::string ll_convert_wide_to_string(const wchar_t* in) } return out; } + +wchar_t* ll_convert_string_to_wide(const std::string& in, unsigned int code_page) +{ + int output_str_len = MultiByteToWideChar(code_page, 0, in.c_str(), in.length(), NULL, 0); + + // reserve place to NULL terminator + wchar_t* w_out = new wchar_t[output_str_len + 1]; + + memset(w_out, 0, output_str_len + 1); + MultiByteToWideChar (code_page, 0, in.c_str(), in.length(), w_out, output_str_len); + + //looks like MultiByteToWideChar didn't add null terminator to converted string, see EXT-4858. + w_out[output_str_len] = 0; + + return w_out; +} + +std::string ll_convert_string_to_utf8_string(const std::string& in) +{ + wchar_t* w_mesg = ll_convert_string_to_wide(in, CP_ACP); + std::string out_utf8 = ll_convert_wide_to_string(w_mesg, CP_UTF8); + delete[] w_mesg; + + return out_utf8; +} #endif // LL_WINDOWS long LLStringOps::sPacificTimeOffset = 0; diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index 8071c8aa2d..41fac0f8cc 100644 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h @@ -564,7 +564,20 @@ using snprintf_hack::snprintf; * * This replaces the unsafe W2A macro from ATL. */ -LL_COMMON_API std::string ll_convert_wide_to_string(const wchar_t* in); +LL_COMMON_API std::string ll_convert_wide_to_string(const wchar_t* in, unsigned int code_page); + +/** + * Converts a string to wide string. + * + * It will allocate memory for result string with "new []". Don't forget to release it with "delete []". + */ +LL_COMMON_API wchar_t* ll_convert_string_to_wide(const std::string& in, unsigned int code_page); + +/** + * Converts incoming string into urf8 string + * + */ +LL_COMMON_API std::string ll_convert_string_to_utf8_string(const std::string& in); //@} #endif // LL_WINDOWS diff --git a/indra/llui/llresmgr.cpp b/indra/llui/llresmgr.cpp index ed870d46d5..9158bc70f5 100644 --- a/indra/llui/llresmgr.cpp +++ b/indra/llui/llresmgr.cpp @@ -298,11 +298,11 @@ void LLResMgr::getIntegerString( std::string& output, S32 input ) const { if (fraction == remaining_count) { - fraction_string = llformat("%d%c", fraction, getThousandsSeparator()); + fraction_string = llformat_to_utf8("%d%c", fraction, getThousandsSeparator()); } else { - fraction_string = llformat("%3.3d%c", fraction, getThousandsSeparator()); + fraction_string = llformat_to_utf8("%3.3d%c", fraction, getThousandsSeparator()); } output = fraction_string + output; } diff --git a/indra/win_crash_logger/llcrashloggerwindows.cpp b/indra/win_crash_logger/llcrashloggerwindows.cpp index 2884231299..01c750487e 100644 --- a/indra/win_crash_logger/llcrashloggerwindows.cpp +++ b/indra/win_crash_logger/llcrashloggerwindows.cpp @@ -145,7 +145,7 @@ void LLCrashLoggerWindows::ProcessCaption(HWND hWnd) TCHAR header[MAX_STRING]; std::string final; GetWindowText(hWnd, templateText, sizeof(templateText)); - final = llformat(ll_convert_wide_to_string(templateText).c_str(), gProductName.c_str()); + final = llformat(ll_convert_wide_to_string(templateText, CP_ACP).c_str(), gProductName.c_str()); ConvertLPCSTRToLPWSTR(final.c_str(), header); SetWindowText(hWnd, header); } @@ -158,7 +158,7 @@ void LLCrashLoggerWindows::ProcessDlgItemText(HWND hWnd, int nIDDlgItem) TCHAR header[MAX_STRING]; std::string final; GetDlgItemText(hWnd, nIDDlgItem, templateText, sizeof(templateText)); - final = llformat(ll_convert_wide_to_string(templateText).c_str(), gProductName.c_str()); + final = llformat(ll_convert_wide_to_string(templateText, CP_ACP).c_str(), gProductName.c_str()); ConvertLPCSTRToLPWSTR(final.c_str(), header); SetDlgItemText(hWnd, nIDDlgItem, header); } @@ -201,7 +201,7 @@ bool handle_button_click(WORD button_id) wbuffer, // pointer to buffer for text 20000 // maximum size of string ); - std::string user_text(ll_convert_wide_to_string(wbuffer)); + std::string user_text(ll_convert_wide_to_string(wbuffer, CP_ACP)); // Activate and show the window. ShowWindow(gHwndProgress, SW_SHOW); // Try doing this second to make the progress window go frontmost. -- cgit v1.3 From a8632670db7366d7b1be362fa2300c6896cc0f61 Mon Sep 17 00:00:00 2001 From: Alexei Arabadji Date: Fri, 23 Jul 2010 17:06:27 +0300 Subject: EXT-6739 FIXED Provided updating of object inspector gear menu 'Touch' and 'Sit' entries. Details: 1 Provided using Object.EnableSit and Object.EnableTouch callbacks for both object menu and inspector gear menu. Now default menu item label stores in hash map and since callback receives triggered control no need to hardcode updating menu item labels from callback. 2 Removed redundant attribute 'parameter' from menu xml's since now handler callbacks receives triggered menu item as function parameter. 3 Replaced LLObjectEnableTouch class with enable_object_touch function, since there no need on triggering callback on menu commit event. 4 Added symmetric method LLMenuItemGL::getValue(). 5 Removed unused "Object.EnableGearSit" callback. reviewed by Vadim Savchuk at https://codereview.productengine.com/secondlife/r/774/ --HG-- branch : product-engine --- indra/llui/llmenugl.cpp | 6 ++ indra/llui/llmenugl.h | 1 + indra/newview/llviewermenu.cpp | 84 ++++++++++++++-------- .../skins/default/xui/en/menu_attachment_self.xml | 3 +- .../default/xui/en/menu_inspect_object_gear.xml | 2 +- 5 files changed, 63 insertions(+), 33 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index b4a1bcb7c5..8610d79142 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -217,6 +217,12 @@ void LLMenuItemGL::setValue(const LLSD& value) setLabel(value.asString()); } +//virtual +LLSD LLMenuItemGL::getValue() const +{ + return getLabel(); +} + //virtual BOOL LLMenuItemGL::handleAcceleratorKey(KEY key, MASK mask) { diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 7668f301ea..a484405eaa 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -95,6 +95,7 @@ public: // LLUICtrl overrides /*virtual*/ void setValue(const LLSD& value); + /*virtual*/ LLSD getValue() const; virtual BOOL handleAcceleratorKey(KEY key, MASK mask); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 7cca118392..df8e127b1f 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -108,9 +108,12 @@ #include "llappearancemgr.h" #include "lltrans.h" #include "lleconomy.h" +#include "boost/unordered_map.hpp" using namespace LLVOAvatarDefines; +static boost::unordered_map sDefaultItemLabels; + BOOL enable_land_build(void*); BOOL enable_object_build(void*); @@ -2403,31 +2406,53 @@ void handle_object_touch() msg->sendMessage(object->getRegion()->getHost()); } -// One object must have touch sensor -class LLObjectEnableTouch : public view_listener_t +static void init_default_item_label(const std::string& item_name) { - bool handleEvent(const LLSD& userdata) + boost::unordered_map::iterator it = sDefaultItemLabels.find(item_name); + if (it == sDefaultItemLabels.end()) { - LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); - - bool new_value = obj && obj->flagHandleTouch(); - - // Update label based on the node touch name if available. - std::string touch_text; - LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); - if (node && node->mValid && !node->mTouchName.empty()) - { - touch_text = node->mTouchName; - } - else + LLStringExplicit default_label = gMenuHolder->childGetValue(item_name).asString(); + if (!default_label.empty()) { - touch_text = userdata.asString(); + sDefaultItemLabels.insert(std::pair(item_name, default_label)); } - gMenuHolder->childSetText("Object Touch", touch_text); - gMenuHolder->childSetText("Attachment Object Touch", touch_text); + } +} - return new_value; +static LLStringExplicit get_default_item_label(const std::string& item_name) +{ + LLStringExplicit res(""); + boost::unordered_map::iterator it = sDefaultItemLabels.find(item_name); + if (it != sDefaultItemLabels.end()) + { + res = it->second; + } + + return res; +} + + +bool enable_object_touch(LLUICtrl* ctrl) +{ + LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + + bool new_value = obj && obj->flagHandleTouch(); + + std::string item_name = ctrl->getName(); + init_default_item_label(item_name); + + // Update label based on the node touch name if available. + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); + if (node && node->mValid && !node->mTouchName.empty()) + { + gMenuHolder->childSetText(item_name, node->mTouchName); + } + else + { + gMenuHolder->childSetText(item_name, get_default_item_label(item_name)); } + + return new_value; }; //void label_touch(std::string& label, void*) @@ -5519,27 +5544,27 @@ bool enable_object_stand_up() return sitting_on_selection(); } -bool enable_object_sit() +bool enable_object_sit(LLUICtrl* ctrl) { // 'Object Sit' menu item is enabled when agent is not sitting on selection bool sitting_on_sel = sitting_on_selection(); if (!sitting_on_sel) { - LLMenuItemGL* sit_menu_item = gMenuHolder->getChild("Object Sit"); - // Init default 'Object Sit' menu item label - static const LLStringExplicit sit_text(sit_menu_item->getLabel()); + std::string item_name = ctrl->getName(); + + // init default labels + init_default_item_label(item_name); + // Update label - std::string label; LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); if (node && node->mValid && !node->mSitName.empty()) { - label.assign(node->mSitName); + gMenuHolder->childSetText(item_name, node->mSitName); } else { - label = sit_text; + gMenuHolder->childSetText(item_name, get_default_item_label(item_name)); } - sit_menu_item->setLabel(label); } return !sitting_on_sel && is_object_sittable(); } @@ -8048,7 +8073,6 @@ void initialize_menus() view_listener_t::addMenu(new LLObjectBuild(), "Object.Build"); commit.add("Object.Touch", boost::bind(&handle_object_touch)); commit.add("Object.SitOrStand", boost::bind(&handle_object_sit_or_stand)); - enable.add("Object.EnableGearSit", boost::bind(&is_object_sittable)); commit.add("Object.Delete", boost::bind(&handle_object_delete)); view_listener_t::addMenu(new LLObjectAttachToAvatar(), "Object.AttachToAvatar"); view_listener_t::addMenu(new LLObjectReturn(), "Object.Return"); @@ -8064,12 +8088,12 @@ void initialize_menus() commit.add("Object.Open", boost::bind(&handle_object_open)); commit.add("Object.Take", boost::bind(&handle_take)); enable.add("Object.EnableOpen", boost::bind(&enable_object_open)); - view_listener_t::addMenu(new LLObjectEnableTouch(), "Object.EnableTouch"); + enable.add("Object.EnableTouch", boost::bind(&enable_object_touch, _1)); enable.add("Object.EnableDelete", boost::bind(&enable_object_delete)); enable.add("Object.EnableWear", boost::bind(&object_selected_and_point_valid)); enable.add("Object.EnableStandUp", boost::bind(&enable_object_stand_up)); - enable.add("Object.EnableSit", boost::bind(&enable_object_sit)); + enable.add("Object.EnableSit", boost::bind(&enable_object_sit, _1)); view_listener_t::addMenu(new LLObjectEnableReturn(), "Object.EnableReturn"); view_listener_t::addMenu(new LLObjectEnableReportAbuse(), "Object.EnableReportAbuse"); diff --git a/indra/newview/skins/default/xui/en/menu_attachment_self.xml b/indra/newview/skins/default/xui/en/menu_attachment_self.xml index 7239b13466..e2348375d5 100644 --- a/indra/newview/skins/default/xui/en/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/en/menu_attachment_self.xml @@ -11,8 +11,7 @@ function="Object.Touch" /> + name="EnableTouch"/>