diff --git a/indra/llui/llaccordionctrl.h b/indra/llui/llaccordionctrl.h index 3ad52740855790a03aa1845d84a5f944e6f5e92a..b5fdf796cd73ff07407d9b9797010044f38d202a 100644 --- a/indra/llui/llaccordionctrl.h +++ b/indra/llui/llaccordionctrl.h @@ -138,6 +138,8 @@ class LLAccordionCtrl: public LLPanel */ const LLAccordionCtrlTab* getExpandedTab() const; + const LLAccordionCtrlTab* getSelectedTab() const { return mSelectedTab; } + private: void initNoTabsWidget(const LLTextBox::Params& tb_params); void updateNoTabsHelpTextVisibility(); diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp index 54bb328a18dbaa586825e086d0eb974385cd3563..20e4b7867c30e005de37c340c870cb45e1986d51 100644 --- a/indra/llui/llaccordionctrltab.cpp +++ b/indra/llui/llaccordionctrltab.cpp @@ -76,6 +76,8 @@ class LLAccordionCtrlTab::LLAccordionCtrlTabHeader : public LLUICtrl std::string getTitle(); void setTitle(const std::string& title, const std::string& hl); + void setTitleFontStyle(std::string style); + void setSelected(bool is_selected) { mIsSelected = is_selected; } virtual void onMouseEnter(S32 x, S32 y, MASK mask); @@ -102,6 +104,9 @@ class LLAccordionCtrlTab::LLAccordionCtrlTabHeader : public LLUICtrl LLPointer<LLUIImage> mImageHeaderPressed; LLPointer<LLUIImage> mImageHeaderFocused; + // style saved when applying it in setTitleFontStyle + LLStyle::Params mStyleParams; + LLUIColor mHeaderBGColor; bool mNeedsHighlight; @@ -170,12 +175,23 @@ void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::setTitle(const std::string& t { LLTextUtil::textboxSetHighlightedVal( mHeaderTextbox, - LLStyle::Params(), + mStyleParams, title, hl); } } +void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::setTitleFontStyle(std::string style) +{ + if (mHeaderTextbox) + { + std::string text = mHeaderTextbox->getText(); + mStyleParams.font(mHeaderTextbox->getDefaultFont()); + mStyleParams.font.style(style); + mHeaderTextbox->setText(text, mStyleParams); + } +} + void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::draw() { S32 width = getRect().getWidth(); @@ -495,6 +511,15 @@ void LLAccordionCtrlTab::setTitle(const std::string& title, const std::string& h } } +void LLAccordionCtrlTab::setTitleFontStyle(std::string style) +{ + LLAccordionCtrlTabHeader* header = findChild<LLAccordionCtrlTabHeader>(DD_HEADER_NAME); + if (header) + { + header->setTitleFontStyle(style); + } +} + boost::signals2::connection LLAccordionCtrlTab::setFocusReceivedCallback(const focus_signal_t::slot_type& cb) { LLAccordionCtrlTabHeader* header = findChild<LLAccordionCtrlTabHeader>(DD_HEADER_NAME); diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h index 7bf7eeef8fe66945c8ed5381ffaa65d52068c34a..e17ecc53198c18083e38a155d4cc7618805856b1 100644 --- a/indra/llui/llaccordionctrltab.h +++ b/indra/llui/llaccordionctrltab.h @@ -37,6 +37,7 @@ #include "llrect.h" #include "lluictrl.h" #include "lluicolor.h" +#include "llstyle.h" class LLUICtrlFactory; class LLUIImage; @@ -120,6 +121,9 @@ class LLAccordionCtrlTab : public LLUICtrl // Set text and highlight substring in LLAccordionCtrlTabHeader void setTitle(const std::string& title, const std::string& hl = LLStringUtil::null); + // Set text font style in LLAccordionCtrlTabHeader + void setTitleFontStyle(std::string style); + boost::signals2::connection setFocusReceivedCallback(const focus_signal_t::slot_type& cb); boost::signals2::connection setFocusLostCallback(const focus_signal_t::slot_type& cb); diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 3c6c7d3e829c453d5e9d492645c47410101e66c3..2d0d5c12cbce34a82461f4dacd848b2c2ac49660 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -152,6 +152,7 @@ LLTextBase::Params::Params() bg_writeable_color("bg_writeable_color"), bg_focus_color("bg_focus_color"), allow_scroll("allow_scroll", true), + plain_text("plain_text",false), track_end("track_end", false), read_only("read_only", false), v_pad("v_pad", 0), @@ -200,6 +201,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p) mSelectionStart( 0 ), mSelectionEnd( 0 ), mIsSelecting( FALSE ), + mPlainText ( p.plain_text ), mWordWrap(p.wrap), mUseEllipses( p.use_ellipses ), mParseHTML(p.allow_html), @@ -1614,7 +1616,7 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para part = (S32)LLTextParser::MIDDLE; } std::string subtext=text.substr(0,start); - appendAndHighlightTextImpl(subtext, part, style_params); + appendAndHighlightText(subtext, part, style_params); } // output an optional icon before the Url @@ -1635,11 +1637,11 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para // output the styled Url (unless we've been asked to suppress hyperlinking) if (match.isLinkDisabled()) { - appendAndHighlightTextImpl(match.getLabel(), part, style_params); + appendAndHighlightText(match.getLabel(), part, style_params); } else { - appendAndHighlightTextImpl(match.getLabel(), part, link_params); + appendAndHighlightText(match.getLabel(), part, link_params); // set the tooltip for the Url label if (! match.getTooltip().empty()) @@ -1667,11 +1669,11 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para if (part != (S32)LLTextParser::WHOLE) part=(S32)LLTextParser::END; if (end < (S32)text.length()) - appendAndHighlightTextImpl(text, part, style_params); + appendAndHighlightText(text, part, style_params); } else { - appendAndHighlightTextImpl(new_text, part, style_params); + appendAndHighlightText(new_text, part, style_params); } } @@ -1682,23 +1684,7 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c 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); + appendTextImpl(new_text,input_params); } void LLTextBase::needsReflow(S32 index) @@ -1718,6 +1704,10 @@ void LLTextBase::appendLineBreakSegment(const LLStyle::Params& style_params) void LLTextBase::appendImageSegment(S32 highlight_part, const LLStyle::Params& style_params) { + if(getPlainText()) + { + return; + } segment_vec_t segments; LLStyleConstSP sp(new LLStyle(style_params)); segments.push_back(new LLImageTextSegment(sp, getLength(),*this)); @@ -1797,13 +1787,10 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig } } -void LLTextBase::appendAndHighlightText(const std::string &new_text, bool prepend_newline, S32 highlight_part, const LLStyle::Params& style_params) +void LLTextBase::appendAndHighlightText(const std::string &new_text, 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); diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 89ce5cdc8e142cc25753e749bdc0e605c4c985b8..92876e20d6fbc97438c41dd65d74babc6a0a6d6f 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -86,6 +86,7 @@ class LLTextBase track_end, read_only, allow_scroll, + plain_text, wrap, use_ellipses, allow_html, @@ -177,6 +178,9 @@ class LLTextBase void setReadOnly(bool read_only) { mReadOnly = read_only; } bool getReadOnly() { return mReadOnly; } + void setPlainText(bool value) { mPlainText = value;} + bool getPlainText() const { return mPlainText; } + // cursor manipulation bool setCursor(S32 row, S32 column); bool setCursorPos(S32 cursor_pos, bool keep_cursor_offset = false); @@ -274,7 +278,7 @@ class LLTextBase S32 insertStringNoUndo(S32 pos, const LLWString &wstr, segment_vec_t* segments = NULL); // returns num of chars actually inserted S32 removeStringNoUndo(S32 pos, S32 length); S32 overwriteCharNoUndo(S32 pos, llwchar wc); - void appendAndHighlightText(const std::string &new_text, bool prepend_newline, S32 highlight_part, const LLStyle::Params& stylep); + void appendAndHighlightText(const std::string &new_text, S32 highlight_part, const LLStyle::Params& stylep); // manage segments @@ -366,6 +370,7 @@ class LLTextBase bool mReadOnly; bool mBGVisible; // render background? bool mClipPartial; // false if we show lines that are partially inside bounding rect + bool mPlainText; // didn't use Image or Icon segments S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes // support widgets diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 557b3b0a77ec5fc08959b1b8dd2e143fc67ddb9b..3923749e641c0728fecb665745338f5782a2e3bb 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -166,6 +166,7 @@ struct LLAgentDumper LLAgentWearables::LLAgentWearables() : mWearablesLoaded(FALSE) +, mCOFChangeInProgress(false) { } @@ -920,13 +921,18 @@ BOOL LLAgentWearables::isWearingItem(const LLUUID& item_id) const // static // ! BACKWARDS COMPATIBILITY ! When we stop supporting viewer1.23, we can assume // that viewers have a Current Outfit Folder and won't need this message, and thus -// we can remove/ignore this whole function. +// we can remove/ignore this whole function. EXCEPT gAgentWearables.notifyLoadingStarted void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgsys, void** user_data) { // We should only receive this message a single time. Ignore subsequent AgentWearablesUpdates // that may result from AgentWearablesRequest having been sent more than once. if (mInitialWearablesUpdateReceived) return; + + // notify subscribers that wearables started loading. See EXT-7777 + // *TODO: find more proper place to not be called from deprecated method. + gAgentWearables.notifyLoadingStarted(); + mInitialWearablesUpdateReceived = true; LLUUID agent_id; @@ -1208,7 +1214,7 @@ void LLAgentWearables::createStandardWearablesAllDone() mWearablesLoaded = TRUE; checkWearablesLoaded(); - mLoadedSignal(); + notifyLoadingFinished(); updateServer(); @@ -1460,7 +1466,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it // Start rendering & update the server mWearablesLoaded = TRUE; checkWearablesLoaded(); - mLoadedSignal(); + notifyLoadingFinished(); queryWearableCache(); updateServer(); @@ -1945,7 +1951,7 @@ void LLAgentWearables::updateWearablesLoaded() mWearablesLoaded = (itemUpdatePendingCount()==0); if (mWearablesLoaded) { - mLoadedSignal(); + notifyLoadingFinished(); } } @@ -2111,7 +2117,13 @@ boost::signals2::connection LLAgentWearables::addLoadedCallback(loaded_callback_ void LLAgentWearables::notifyLoadingStarted() { + mCOFChangeInProgress = true; mLoadingStartedSignal(); } +void LLAgentWearables::notifyLoadingFinished() +{ + mCOFChangeInProgress = false; + mLoadedSignal(); +} // EOF diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h index 3295544e044f360a387abcd61a2d3dbf600d3d99..05913825dd1a9bff62f6ace6bee685766a646895 100644 --- a/indra/newview/llagentwearables.h +++ b/indra/newview/llagentwearables.h @@ -75,6 +75,7 @@ class LLAgentWearables BOOL isWearableCopyable(LLWearableType::EType type, U32 index /*= 0*/) const; BOOL areWearablesLoaded() const; + bool isCOFChangeInProgress() const { return mCOFChangeInProgress; } void updateWearablesLoaded(); void checkWearablesLoaded() const; bool canMoveWearable(const LLUUID& item_id, bool closer_to_body); @@ -233,6 +234,7 @@ class LLAgentWearables boost::signals2::connection addLoadedCallback(loaded_callback_t cb); void notifyLoadingStarted(); + void notifyLoadingFinished(); private: loading_started_signal_t mLoadingStartedSignal; // should be called before wearables are changed @@ -249,6 +251,11 @@ class LLAgentWearables static BOOL mInitialWearablesUpdateReceived; BOOL mWearablesLoaded; std::set<LLUUID> mItemsAwaitingWearableUpdate; + + /** + * True if agent's outfit is being changed now. + */ + BOOL mCOFChangeInProgress; //-------------------------------------------------------------------------------- // Support classes diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 52a5587a1622e21373b363fba9eb9fa462ec6978..4e96372da93ed2339dd1ba6f476da3bf5da391d5 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -923,6 +923,14 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up { if (item_id_to_wear.isNull()) return false; + // *TODO: issue with multi-wearable should be fixed: + // in this case this method will be called N times - loading started for each item + // and than N times will be called - loading completed for each item. + // That means subscribers will be notified that loading is done after first item in a batch is worn. + // (loading indicator disappears for example before all selected items are worn) + // Have not fix this issue for 2.1 because of stability reason. EXT-7777. + gAgentWearables.notifyLoadingStarted(); + LLViewerInventoryItem* item_to_wear = gInventory.getItem(item_id_to_wear); if (!item_to_wear) return false; @@ -1060,7 +1068,7 @@ void LLAppearanceMgr::takeOffOutfit(const LLUUID& cat_id) { LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; - LLFindWorn collector; + LLFindWearablesEx collector(/*is_worn=*/ true, /*include_body_parts=*/ false); gInventory.collectDescendentsIf(cat_id, cats, items, FALSE, collector); @@ -1216,6 +1224,34 @@ bool LLAppearanceMgr::getCanRemoveOutfit(const LLUUID& outfit_cat_id) return true; } +// static +bool LLAppearanceMgr::getCanRemoveFromCOF(const LLUUID& outfit_cat_id) +{ + LLInventoryModel::cat_array_t cats; + LLInventoryModel::item_array_t items; + LLFindWearablesEx is_worn(/*is_worn=*/ true, /*include_body_parts=*/ false); + gInventory.collectDescendentsIf(outfit_cat_id, + cats, + items, + LLInventoryModel::EXCLUDE_TRASH, + is_worn); + return items.size() > 0; +} + +// static +bool LLAppearanceMgr::getCanAddToCOF(const LLUUID& outfit_cat_id) +{ + LLInventoryModel::cat_array_t cats; + LLInventoryModel::item_array_t items; + LLFindWearablesEx not_worn(/*is_worn=*/ false, /*include_body_parts=*/ false); + gInventory.collectDescendentsIf(outfit_cat_id, + cats, + items, + LLInventoryModel::EXCLUDE_TRASH, + not_worn); + return items.size() > 0; +} + void LLAppearanceMgr::purgeBaseOutfitLink(const LLUUID& category) { LLInventoryModel::cat_array_t cats; @@ -1330,9 +1366,12 @@ void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append) // - Body parts: always include COF contents as a fallback in case any // required parts are missing. + // Preserve body parts from COF if appending. LLInventoryModel::item_array_t body_items; getDescendentsOfAssetType(cof, body_items, LLAssetType::AT_BODYPART, false); getDescendentsOfAssetType(category, body_items, LLAssetType::AT_BODYPART, false); + if (append) + reverse(body_items.begin(), body_items.end()); // Reduce body items to max of one per type. removeDuplicateItems(body_items); filterWearableItems(body_items, 1); diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index e42f9f7d6f4bd02900479c5333ecb18fd730509e..8ded32a53d4e957deda365e1c4a9682ba0d75571 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -75,6 +75,12 @@ class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr> // Determine whether a given outfit can be removed. bool getCanRemoveOutfit(const LLUUID& outfit_cat_id); + // Determine whether we're wearing any of the outfit contents (excluding body parts). + static bool getCanRemoveFromCOF(const LLUUID& outfit_cat_id); + + // Determine whether we can add anything (but body parts) from the outfit contents to COF. + static bool getCanAddToCOF(const LLUUID& outfit_cat_id); + // Copy all items in a category. void shallowCopyCategoryContents(const LLUUID& src_id, const LLUUID& dst_id, LLPointer<LLInventoryCallback> cb); diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index 18c69b5130c43c2e238b7916b795be8c664e8509..ab97dbb69539510589fe5b8cd26e9afd24854374 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -557,6 +557,11 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL { bool use_plain_text_chat_history = args["use_plain_text_chat_history"].asBoolean(); + if(mEditor) + { + mEditor->setPlainText(use_plain_text_chat_history); + } + if (!mEditor->scrolledToEnd() && chat.mFromID != gAgent.getID() && !chat.mFromName.empty()) { mUnreadChatSources.insert(chat.mFromName); diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp index 46d2e0a5db6fab967e0cf9b88a6bbaa8763bfe5c..aa8cc01f7d32e314b1d78bce6b005bf5f2af1197 100644 --- a/indra/newview/llcofwearables.cpp +++ b/indra/newview/llcofwearables.cpp @@ -208,7 +208,7 @@ class CofClothingContextMenu : public CofContextMenu } else if ("edit" == param) { - return gAgentWearables.isWearableModifiable(selected_id); + return mUUIDs.size() == 1 && gAgentWearables.isWearableModifiable(selected_id); } return true; } @@ -264,7 +264,7 @@ class CofBodyPartContextMenu : public CofContextMenu if ("edit" == param) { - return gAgentWearables.isWearableModifiable(selected_id); + return mUUIDs.size() == 1 && gAgentWearables.isWearableModifiable(selected_id); } return true; diff --git a/indra/newview/llcolorswatch.cpp b/indra/newview/llcolorswatch.cpp index d079da3b3600af28857a415c2b8288bd97db5741..b83e4fe830d8b255e7d48334ba9cc46ee74b2d9a 100644 --- a/indra/newview/llcolorswatch.cpp +++ b/indra/newview/llcolorswatch.cpp @@ -338,7 +338,11 @@ void LLColorSwatchCtrl::showPicker(BOOL take_focus) if (!pickerp) { pickerp = new LLFloaterColorPicker(this, mCanApplyImmediately); - //gFloaterView->getParentFloater(this)->addDependentFloater(pickerp); + LLFloater* parent = gFloaterView->getParentFloater(this); + if (parent) + { + parent->addDependentFloater(pickerp); + } mPickerHandle = pickerp->getHandle(); } diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index c8d66549b7ed87c63cabcb12ebbd52ddafd8b2a9..afaeddaaeba03b5f885cb416da8d4150f7c62d5b 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -2489,7 +2489,7 @@ void LLFolderBridge::folderOptionsMenu() mItems.push_back(std::string("Wear As Ensemble")); } mItems.push_back(std::string("Remove From Outfit")); - if (!areAnyContentsWorn(model)) + if (!LLAppearanceMgr::getCanRemoveFromCOF(mUUID)) { disabled_items.push_back(std::string("Remove From Outfit")); } @@ -2514,19 +2514,6 @@ BOOL LLFolderBridge::checkFolderForContentsOfType(LLInventoryModel* model, LLInv return ((item_array.count() > 0) ? TRUE : FALSE ); } -BOOL LLFolderBridge::areAnyContentsWorn(LLInventoryModel* model) const -{ - LLInventoryModel::cat_array_t cat_array; - LLInventoryModel::item_array_t item_array; - LLFindWorn is_worn; - model->collectDescendentsIf(mUUID, - cat_array, - item_array, - LLInventoryModel::EXCLUDE_TRASH, - is_worn); - return (item_array.size() > 0); -} - // Flags unused void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 757808eb93cf50d80cf94e91302e9155dfb59e00..64d0f8d25452339586c5557589a42f7dbf7b1eaa 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -295,7 +295,6 @@ class LLFolderBridge : public LLInvFVBridge static void createNewEyes(void* user_data); BOOL checkFolderForContentsOfType(LLInventoryModel* model, LLInventoryCollectFunctor& typeToCheck); - BOOL areAnyContentsWorn(LLInventoryModel* model) const; void modifyOutfit(BOOL append); void determineFolderType(); diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index c784ca3a9c84f1fe6781a839b4d8186856317612..37088064c6d2cb463c8996c189f7583669ccc360 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -578,6 +578,31 @@ bool LLFindWearables::operator()(LLInventoryCategory* cat, return FALSE; } +LLFindWearablesEx::LLFindWearablesEx(bool is_worn, bool include_body_parts) +: mIsWorn(is_worn) +, mIncludeBodyParts(include_body_parts) +{} + +bool LLFindWearablesEx::operator()(LLInventoryCategory* cat, LLInventoryItem* item) +{ + LLViewerInventoryItem *vitem = dynamic_cast<LLViewerInventoryItem*>(item); + if (!vitem) return false; + + // Skip non-wearables. + if (!vitem->isWearableType() && vitem->getType() != LLAssetType::AT_OBJECT) + { + return false; + } + + // Skip body parts if requested. + if (!mIncludeBodyParts && vitem->getType() == LLAssetType::AT_BODYPART) + { + return false; + } + + return (bool) get_is_item_worn(item->getUUID()) == mIsWorn; +} + bool LLFindWearablesOfType::operator()(LLInventoryCategory* cat, LLInventoryItem* item) { if (!item) return false; @@ -598,11 +623,6 @@ 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) diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index aa4ac98241f632e1312bee8f38e05a4cffe8adca..6619a50d28e83ad3c35d515bf064f755b2a49073 100644 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -338,6 +338,21 @@ class LLFindWearables : public LLInventoryCollectFunctor LLInventoryItem* item); }; +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class LLFindWearablesEx +// +// Collects wearables based on given criteria. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +class LLFindWearablesEx : public LLInventoryCollectFunctor +{ +public: + LLFindWearablesEx(bool is_worn, bool include_body_parts = true); + virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item); +private: + bool mIncludeBodyParts; + bool mIsWorn; +}; + //Inventory collect functor collecting wearables of a specific wearable type class LLFindWearablesOfType : public LLInventoryCollectFunctor { @@ -364,15 +379,6 @@ class LLFindActualWearablesOfType : public LLFindWearablesOfType } }; -// 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 { diff --git a/indra/newview/llinventoryitemslist.cpp b/indra/newview/llinventoryitemslist.cpp index 384b24210cf80328d191aef248d19c65e94d0856..14de5442d69b9c94c8bc77e8cd98712f84f517a0 100644 --- a/indra/newview/llinventoryitemslist.cpp +++ b/indra/newview/llinventoryitemslist.cpp @@ -80,10 +80,11 @@ void LLPanelInventoryListItemBase::draw() } // virtual -void LLPanelInventoryListItemBase::updateItem(const std::string& name) +void LLPanelInventoryListItemBase::updateItem(const std::string& name, + const LLStyle::Params& input_params) { setIconImage(mIconImage); - setTitle(name, mHighlightedText); + setTitle(name, mHighlightedText, input_params); } void LLPanelInventoryListItemBase::addWidgetToLeftSide(const std::string& name, bool show_widget/* = true*/) @@ -286,25 +287,28 @@ void LLPanelInventoryListItemBase::setIconImage(const LLUIImagePtr& image) } } -void LLPanelInventoryListItemBase::setTitle(const std::string& title, const std::string& highlit_text) +void LLPanelInventoryListItemBase::setTitle(const std::string& title, + const std::string& highlit_text, + const LLStyle::Params& input_params) { - setToolTip(title); + mTitleCtrl->setToolTip(title); LLTextUtil::textboxSetHighlightedVal( mTitleCtrl, - LLStyle::Params(), + input_params, title, highlit_text); } BOOL LLPanelInventoryListItemBase::handleToolTip( S32 x, S32 y, MASK mask) { - LLTextBox* item_name = getChild<LLTextBox>("item_name"); - if (item_name->getRect().getWidth() < item_name->getTextPixelWidth()) + LLRect text_box_rect = mTitleCtrl->getRect(); + if (text_box_rect.pointInRect(x, y) && + mTitleCtrl->getTextPixelWidth() <= text_box_rect.getWidth()) { - return LLPanel::handleToolTip(x,y,mask); + return FALSE; } - return FALSE; + return LLPanel::handleToolTip(x, y, mask); } void LLPanelInventoryListItemBase::reshapeLeftWidgets() diff --git a/indra/newview/llinventoryitemslist.h b/indra/newview/llinventoryitemslist.h index 489a82829c8cc20ae049fc3f7218832e65b6c9d5..5dc0bfe3de6c10a6ed23255f1c93ea8b2b9fc5a9 100644 --- a/indra/newview/llinventoryitemslist.h +++ b/indra/newview/llinventoryitemslist.h @@ -152,7 +152,8 @@ class LLPanelInventoryListItemBase : public LLPanel /** * Called after inventory item was updated, update panel widgets to reflect inventory changes. */ - virtual void updateItem(const std::string& name); + virtual void updateItem(const std::string& name, + const LLStyle::Params& input_params = LLStyle::Params()); /** setter for mIconCtrl */ void setIconCtrl(LLIconCtrl* icon) { mIconCtrl = icon; } @@ -177,7 +178,9 @@ class LLPanelInventoryListItemBase : public LLPanel void setIconImage(const LLUIImagePtr& image); /** Set item title - inventory item name usually */ - virtual void setTitle(const std::string& title, const std::string& highlit_text); + virtual void setTitle(const std::string& title, + const std::string& highlit_text, + const LLStyle::Params& input_params = LLStyle::Params()); /** * Show tool tip if item name text size > panel size diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index de074d6aaf43ccad2becf2675cf77d27ce8123d5..c5043e1c3d7f174e148bcfcaca33fb81f868106b 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -103,6 +103,14 @@ class OutfitContextMenu : public LLListContextMenu { return get_is_category_renameable(&gInventory, outfit_cat_id); } + else if ("wear_add" == param) + { + return LLAppearanceMgr::getCanAddToCOF(outfit_cat_id); + } + else if ("take_off" == param) + { + return LLAppearanceMgr::getCanRemoveFromCOF(outfit_cat_id); + } return true; } @@ -120,14 +128,6 @@ class OutfitContextMenu : public LLListContextMenu { return !is_worn; } - else if ("wear_add" == param) - { - return !is_worn; - } - else if ("take_off" == param) - { - return is_worn; - } else if ("delete" == param) { return LLAppearanceMgr::instance().getCanRemoveOutfit(outfit_cat_id); @@ -161,6 +161,7 @@ LLOutfitsList::LLOutfitsList() , mAccordion(NULL) , mListCommands(NULL) , mIsInitialized(false) + , mItemSelected(false) { mCategoriesObserver = new LLInventoryCategoriesObserver(); @@ -208,8 +209,13 @@ void LLOutfitsList::onOpen(const LLSD& /*info*/) mCategoriesObserver->addCategory(outfits, boost::bind(&LLOutfitsList::refreshList, this, outfits)); - // Start observing changes in Current Outfit to update items worn state. - LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&LLOutfitsList::onCOFChanged, this)); + const LLUUID cof = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); + + // Start observing changes in Current Outfit category. + mCategoriesObserver->addCategory(cof, boost::bind(&LLOutfitsList::onCOFChanged, this)); + + LLOutfitObserver::instance().addBOFChangedCallback(boost::bind(&LLOutfitsList::highlightBaseOutfit, this)); + LLOutfitObserver::instance().addBOFReplacedCallback(boost::bind(&LLOutfitsList::highlightBaseOutfit, this)); // Fetch "My Outfits" contents and refresh the list to display // initially fetched items. If not all items are fetched now @@ -217,6 +223,7 @@ void LLOutfitsList::onOpen(const LLSD& /*info*/) // arrive. category->fetch(); refreshList(outfits); + highlightBaseOutfit(); mIsInitialized = true; } @@ -325,19 +332,13 @@ void LLOutfitsList::refreshList(const LLUUID& category_id) // 1. Remove outfit category from observer to stop monitoring its changes. mCategoriesObserver->removeCategory(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) - { - setSelectedOutfitUUID(LLUUID()); - } + // 2. Remove the outfit from selection. + deselectOutfit(outfit_id); - // 4. Remove category UUID to accordion tab mapping. + // 3. Remove category UUID to accordion tab mapping. mOutfitsMap.erase(outfits_iter); - // 5. Remove outfit tab from accordion. + // 4. Remove outfit tab from accordion. mAccordion->removeCollapsibleCtrl(tab); } } @@ -355,6 +356,25 @@ void LLOutfitsList::refreshList(const LLUUID& category_id) mAccordion->sort(); } +void LLOutfitsList::highlightBaseOutfit() +{ + // id of base outfit + LLUUID base_id = LLAppearanceMgr::getInstance()->getBaseOutfitUUID(); + if (base_id != mHighlightedOutfitUUID) + { + if (mOutfitsMap[mHighlightedOutfitUUID]) + { + mOutfitsMap[mHighlightedOutfitUUID]->setTitleFontStyle("NORMAL"); + } + + mHighlightedOutfitUUID = base_id; + } + if (mOutfitsMap[base_id]) + { + mOutfitsMap[base_id]->setTitleFontStyle("BOLD"); + } +} + void LLOutfitsList::onSelectionChange(LLUICtrl* ctrl) { LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(ctrl); @@ -399,6 +419,11 @@ boost::signals2::connection LLOutfitsList::addSelectionChangeCallback(selection_ return mSelectionChangeSignal.connect(cb); } +bool LLOutfitsList::hasItemSelected() +{ + return mItemSelected; +} + ////////////////////////////////////////////////////////////////////////// // Private methods ////////////////////////////////////////////////////////////////////////// @@ -484,6 +509,8 @@ void LLOutfitsList::changeOutfitSelection(LLWearableItemsList* list, const LLUUI mSelectedListsMap.clear(); } + mItemSelected = list && (list->getSelectedItem() != NULL); + mSelectedListsMap.insert(wearables_lists_map_value_t(category_id, list)); setSelectedOutfitUUID(category_id); } @@ -493,6 +520,27 @@ void LLOutfitsList::setSelectedOutfitUUID(const LLUUID& category_id) mSelectionChangeSignal(mSelectedOutfitUUID = category_id); } +void LLOutfitsList::deselectOutfit(const LLUUID& category_id) +{ + // Remove selected lists map entry. + mSelectedListsMap.erase(category_id); + + // Reset selection if the outfit is selected. + if (category_id == mSelectedOutfitUUID) + { + setSelectedOutfitUUID(LLUUID::null); + } +} + +void LLOutfitsList::restoreOutfitSelection(LLAccordionCtrlTab* tab, const LLUUID& category_id) +{ + // Try restoring outfit selection after filtering. + if (mAccordion->getSelectedTab() == tab) + { + setSelectedOutfitUUID(category_id); + } +} + void LLOutfitsList::onFilteredWearableItemsListRefresh(LLUICtrl* ctrl) { if (!ctrl || mFilterSubString.empty()) @@ -509,26 +557,7 @@ void LLOutfitsList::onFilteredWearableItemsListRefresh(LLUICtrl* ctrl) LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(tab->getAccordionView()); if (list != ctrl) continue; - std::string title = tab->getTitle(); - LLStringUtil::toUpper(title); - - std::string cur_filter = mFilterSubString; - LLStringUtil::toUpper(cur_filter); - - if (std::string::npos == title.find(cur_filter)) - { - // 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 - { - tab->setTitle(tab->getTitle(), cur_filter); - } + applyFilterToTab(iter->first, tab, mFilterSubString); } } @@ -567,26 +596,7 @@ void LLOutfitsList::applyFilter(const std::string& new_filter_substring) if (!new_filter_substring.empty()) { - std::string title = tab->getTitle(); - LLStringUtil::toUpper(title); - - std::string cur_filter = new_filter_substring; - LLStringUtil::toUpper(cur_filter); - - if (std::string::npos == title.find(cur_filter)) - { - // 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 - { - tab->setTitle(tab->getTitle(), cur_filter); - } + applyFilterToTab(iter->first, tab, new_filter_substring); if (tab->getVisible()) { @@ -607,10 +617,50 @@ void LLOutfitsList::applyFilter(const std::string& new_filter_substring) //restore accordion state after all those accodrion tab manipulations tab->notifyChildren(LLSD().with("action","restore_state")); + + // Try restoring the tab selection. + restoreOutfitSelection(tab, iter->first); } } } +void LLOutfitsList::applyFilterToTab( + const LLUUID& category_id, + LLAccordionCtrlTab* tab, + const std::string& filter_substring) +{ + if (!tab) return; + LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(tab->getAccordionView()); + if (!list) return; + + std::string title = tab->getTitle(); + LLStringUtil::toUpper(title); + + std::string cur_filter = filter_substring; + LLStringUtil::toUpper(cur_filter); + + tab->setTitle(tab->getTitle(), cur_filter); + + if (std::string::npos == title.find(cur_filter)) + { + // 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()); + + // Remove the tab from selection. + deselectOutfit(category_id); + } + else + { + // Try restoring the tab selection. + restoreOutfitSelection(tab, category_id); + } +} + void LLOutfitsList::onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id) { LLAccordionCtrlTab* tab = dynamic_cast<LLAccordionCtrlTab*>(ctrl); diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h index 5605044f41a59f7f0417584b0b03067edc75804f..df65f7187b49144b99412f7b06a719a103c090d3 100644 --- a/indra/newview/lloutfitslist.h +++ b/indra/newview/lloutfitslist.h @@ -83,6 +83,9 @@ class LLOutfitsList : public LLPanel void refreshList(const LLUUID& category_id); + // highlits currently worn outfit tab text and unhighlights previously worn + void highlightBaseOutfit(); + void performAction(std::string action); void setFilterSubString(const std::string& string); @@ -91,6 +94,11 @@ class LLOutfitsList : public LLPanel boost::signals2::connection addSelectionChangeCallback(selection_change_callback_t cb); + /** + * Returns true if there is a selection inside currently selected outfit + */ + bool hasItemSelected(); + private: /** * Reads xml with accordion tab and Flat list from xml file. @@ -119,6 +127,18 @@ class LLOutfitsList : public LLPanel */ void setSelectedOutfitUUID(const LLUUID& category_id); + /** + * Removes the outfit from selection. + */ + void deselectOutfit(const LLUUID& category_id); + + /** + * Try restoring selection for a temporary hidden tab. + * + * A tab may be hidden if it doesn't match current filter. + */ + void restoreOutfitSelection(LLAccordionCtrlTab* tab, const LLUUID& category_id); + /** * Called upon list refresh event to update tab visibility depending on * the results of applying filter to the title and list items of the tab. @@ -130,6 +150,13 @@ class LLOutfitsList : public LLPanel */ void applyFilter(const std::string& new_filter_substring); + /** + * Applies filter to the given tab + * + * @see applyFilter() + */ + void applyFilterToTab(const LLUUID& category_id, LLAccordionCtrlTab* tab, const std::string& filter_substring); + void onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id); void onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y); void onCOFChanged(); @@ -148,6 +175,8 @@ class LLOutfitsList : public LLPanel wearables_lists_map_t mSelectedListsMap; LLUUID mSelectedOutfitUUID; + // id of currently highlited outfit + LLUUID mHighlightedOutfitUUID; selection_change_signal_t mSelectionChangeSignal; std::string mFilterSubString; @@ -159,6 +188,10 @@ class LLOutfitsList : public LLPanel LLListContextMenu* mOutfitMenu; bool mIsInitialized; + /** + * True if there is a selection inside currently selected outfit + */ + bool mItemSelected; }; #endif //LL_LLOUTFITSLIST_H diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp index 7e1bff09617d0710fff881c8a910727d75249277..714d9cd4c5f6c0fbb1e25e10473ede4f98b4aa1a 100644 --- a/indra/newview/llpaneloutfitsinventory.cpp +++ b/indra/newview/llpaneloutfitsinventory.cpp @@ -191,6 +191,10 @@ class LLOutfitListGearMenu { return LLAppearanceMgr::instance().getCanRemoveOutfit(selected_outfit_id); } + else if ("take_off" == param) + { + return LLAppearanceMgr::getCanRemoveFromCOF(selected_outfit_id); + } return true; } @@ -209,10 +213,6 @@ class LLOutfitListGearMenu { return !is_worn; } - else if ("take_off" == param) - { - return is_worn; - } return true; } @@ -224,7 +224,6 @@ class LLOutfitListGearMenu LLPanelOutfitsInventory::LLPanelOutfitsInventory() : mMyOutfitsPanel(NULL), mCurrentOutfitPanel(NULL), - mParent(NULL), mGearMenu(NULL), mInitialized(false) { @@ -314,11 +313,6 @@ void LLPanelOutfitsInventory::updateVerbs() } } -void LLPanelOutfitsInventory::setParent(LLSidepanelAppearance* parent) -{ - mParent = parent; -} - // virtual void LLPanelOutfitsInventory::onSearchEdit(const std::string& string) { @@ -548,7 +542,7 @@ void LLPanelOutfitsInventory::initListCommandsHandlers() void LLPanelOutfitsInventory::updateListCommands() { bool trash_enabled = isActionEnabled("delete"); - bool wear_enabled = isActionEnabled("wear"); + bool wear_enabled = !gAgentWearables.isCOFChangeInProgress() && isActionEnabled("wear"); bool wear_visible = !isCOFPanelActive(); bool make_outfit_enabled = isActionEnabled("save_outfit"); @@ -667,7 +661,8 @@ BOOL LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata) else // "My Outfits" tab active { const LLUUID& selected_outfit = mMyOutfitsPanel->getSelectedOutfitUUID(); - can_delete = LLAppearanceMgr::instance().getCanRemoveOutfit(selected_outfit); + // first condition prevents trash btn from enabling when items are selected inside outfit (EXT-7847) + can_delete = !mMyOutfitsPanel->hasItemSelected() && LLAppearanceMgr::instance().getCanRemoveOutfit(selected_outfit); } return can_delete; @@ -827,12 +822,6 @@ BOOL LLPanelOutfitsInventory::isCOFPanelActive() const void LLPanelOutfitsInventory::setWearablesLoading(bool val) { mListCommands->childSetEnabled("wear_btn", !val); - - llassert(mParent); - if (mParent) - { - mParent->setWearablesLoading(val); - } } void LLPanelOutfitsInventory::onWearablesLoaded() diff --git a/indra/newview/llpaneloutfitsinventory.h b/indra/newview/llpaneloutfitsinventory.h index 863dc9dd7c2bb8010063a63f356bdd5d2e4a4a57..eabfda7f8c2e56817a646c871e521b25e8eb946d 100644 --- a/indra/newview/llpaneloutfitsinventory.h +++ b/indra/newview/llpaneloutfitsinventory.h @@ -72,7 +72,6 @@ class LLPanelOutfitsInventory : public LLPanel // If a compatible listener type is selected, then return a pointer to that. // Otherwise, return NULL. LLFolderViewEventListener* getCorrectListenerForAction(); - void setParent(LLSidepanelAppearance *parent); LLFolderView* getRootFolder(); static LLSidepanelAppearance* getAppearanceSP(); @@ -84,7 +83,6 @@ class LLPanelOutfitsInventory : public LLPanel bool getIsCorrectType(const LLFolderViewEventListener *listenerp) const; private: - LLSidepanelAppearance* mParent; LLSaveFolderState* mSavedFolderState; LLTabContainer* mAppearanceTabs; std::string mFilterSubString; diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index e2d4f5ad45a57b49014d14cd795979a442998ae7..0d1be91125483d0cdba45fc39db6e5f8ac997995 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -86,6 +86,9 @@ LLSidepanelAppearance::LLSidepanelAppearance() : outfit_observer.addBOFReplacedCallback(boost::bind(&LLSidepanelAppearance::refreshCurrentOutfitName, this, "")); outfit_observer.addBOFChangedCallback(boost::bind(&LLSidepanelAppearance::refreshCurrentOutfitName, this, "")); outfit_observer.addCOFChangedCallback(boost::bind(&LLSidepanelAppearance::refreshCurrentOutfitName, this, "")); + + gAgentWearables.addLoadingStartedCallback(boost::bind(&LLSidepanelAppearance::setWearablesLoading, this, true)); + gAgentWearables.addLoadedCallback(boost::bind(&LLSidepanelAppearance::setWearablesLoading, this, false)); } LLSidepanelAppearance::~LLSidepanelAppearance() @@ -114,7 +117,6 @@ BOOL LLSidepanelAppearance::postBuild() } mPanelOutfitsInventory = dynamic_cast<LLPanelOutfitsInventory *>(getChild<LLPanel>("panel_outfits_inventory")); - mPanelOutfitsInventory->setParent(this); mOutfitEdit = dynamic_cast<LLPanelOutfitEdit*>(getChild<LLPanel>("panel_outfit_edit")); if (mOutfitEdit) @@ -387,7 +389,9 @@ void LLSidepanelAppearance::refreshCurrentOutfitName(const std::string& name) mCurrentLookName->setText(outfit_name); return; } - mCurrentLookName->setText(getString("No Outfit")); + + std::string look_name = gAgentWearables.isCOFChangeInProgress() ? "" : getString("No Outfit"); + mCurrentLookName->setText(look_name); mOpenOutfitBtn->setEnabled(FALSE); } else diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp index db1f4dc4cb32b223991ad2b06345ad41b82934ce..7ba256c87056b988b9eb0475dc96640325f17725 100644 --- a/indra/newview/lltoastalertpanel.cpp +++ b/indra/newview/lltoastalertpanel.cpp @@ -247,35 +247,6 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal msg_box->setRect( rect ); LLToastPanel::addChild(msg_box); - // Buttons - S32 button_left = (LLToastPanel::getRect().getWidth() - btn_total_width) / 2; - - for( S32 i = 0; i < num_options; i++ ) - { - LLRect button_rect; - - LLButton* btn = LLUICtrlFactory::getInstance()->createFromFile<LLButton>("alert_button.xml", this, LLPanel::child_registry_t::instance()); - if(btn) - { - btn->setName(options[i].first); - btn->setRect(button_rect.setOriginAndSize( button_left, VPAD, button_width, BTN_HEIGHT )); - btn->setLabel(options[i].second); - btn->setFont(font); - - btn->setClickedCallback(boost::bind(&LLToastAlertPanel::onButtonPressed, this, _2, i)); - - mButtonData[i].mButton = btn; - - LLToastPanel::addChild(btn); - - if( i == mDefaultOption ) - { - btn->setFocus(TRUE); - } - } - button_left += button_width + BTN_HPAD; - } - // (Optional) Edit Box if (!edit_text_name.empty()) { @@ -307,9 +278,63 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal mLineEditor->setDrawAsterixes(is_password); setEditTextArgs(notification->getSubstitutions()); + + mLineEditor->setFollowsLeft(); + mLineEditor->setFollowsRight(); + + // find form text input field + LLSD form_text; + for (LLSD::array_const_iterator it = form_sd.beginArray(); it != form_sd.endArray(); ++it) + { + std::string type = (*it)["type"].asString(); + if (type == "text") + { + form_text = (*it); + } + } + + // if form text input field has width attribute + if (form_text.has("width")) + { + // adjust floater width to fit line editor + S32 editor_width = form_text["width"]; + LLRect editor_rect = mLineEditor->getRect(); + U32 width_delta = editor_width - editor_rect.getWidth(); + LLRect toast_rect = getRect(); + reshape(toast_rect.getWidth() + width_delta, toast_rect.getHeight()); + } } } + // Buttons + S32 button_left = (LLToastPanel::getRect().getWidth() - btn_total_width) / 2; + + for( S32 i = 0; i < num_options; i++ ) + { + LLRect button_rect; + + LLButton* btn = LLUICtrlFactory::getInstance()->createFromFile<LLButton>("alert_button.xml", this, LLPanel::child_registry_t::instance()); + if(btn) + { + btn->setName(options[i].first); + btn->setRect(button_rect.setOriginAndSize( button_left, VPAD, button_width, BTN_HEIGHT )); + btn->setLabel(options[i].second); + btn->setFont(font); + + btn->setClickedCallback(boost::bind(&LLToastAlertPanel::onButtonPressed, this, _2, i)); + + mButtonData[i].mButton = btn; + + LLToastPanel::addChild(btn); + + if( i == mDefaultOption ) + { + btn->setFocus(TRUE); + } + } + button_left += button_width + BTN_HPAD; + } + std::string ignore_label; if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE) diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index ea0c5f1d0f47100d25dd17ece70f705f7f20be44..9c308359fa92f6b9cc096c80c5b8b8355af5ac8f 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -112,16 +112,19 @@ LLPanelWearableOutfitItem::LLPanelWearableOutfitItem(LLViewerInventoryItem* item } // virtual -void LLPanelWearableOutfitItem::updateItem(const std::string& name) +void LLPanelWearableOutfitItem::updateItem(const std::string& name, + const LLStyle::Params& input_params) { std::string search_label = name; + LLStyle::Params style_params = input_params; if (mItem && get_is_item_worn(mItem->getUUID())) { search_label += LLTrans::getString("worn"); + style_params.font.style("BOLD"); } - LLPanelInventoryListItemBase::updateItem(search_label); + LLPanelInventoryListItemBase::updateItem(search_label, style_params); } ////////////////////////////////////////////////////////////////////////// @@ -261,7 +264,9 @@ LLPanelAttachmentListItem* LLPanelAttachmentListItem::create(LLViewerInventoryIt return list_item; } -void LLPanelAttachmentListItem::setTitle(const std::string& title, const std::string& highlit_text) +void LLPanelAttachmentListItem::setTitle(const std::string& title, + const std::string& highlit_text, + const LLStyle::Params& input_params) { std::string title_joint = title; @@ -271,7 +276,7 @@ void LLPanelAttachmentListItem::setTitle(const std::string& title, const std::st title_joint = title + " (" + joint + ")"; } - LLPanelDeletableWearableListItem::setTitle(title_joint, highlit_text); + LLPanelDeletableWearableListItem::setTitle(title_joint, highlit_text, input_params); } ////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h index 69134dd6462b49511867854899648182aa073a23..5dc06284c387b2582c68c6c24de3513d5c30a7ce 100644 --- a/indra/newview/llwearableitemslist.h +++ b/indra/newview/llwearableitemslist.h @@ -86,8 +86,8 @@ class LLPanelWearableOutfitItem : public LLPanelInventoryListItemBase /** * Updates item name and (worn) suffix. */ - /*virtual*/ void updateItem(const std::string& name); - + /*virtual*/ void updateItem(const std::string& name, + const LLStyle::Params& input_params = LLStyle::Params()); protected: LLPanelWearableOutfitItem(LLViewerInventoryItem* item); @@ -124,7 +124,9 @@ class LLPanelAttachmentListItem : public LLPanelDeletableWearableListItem virtual ~LLPanelAttachmentListItem() {}; /** Set item title. Joint name is added to the title in parenthesis */ - /*virtual*/ void setTitle(const std::string& title, const std::string& highlit_text); + /*virtual*/ void setTitle(const std::string& title, + const std::string& highlit_text, + const LLStyle::Params& input_params = LLStyle::Params()); protected: LLPanelAttachmentListItem(LLViewerInventoryItem* item) : LLPanelDeletableWearableListItem(item) {}; diff --git a/indra/newview/llworldmapmessage.cpp b/indra/newview/llworldmapmessage.cpp index 06040a574c579a6387023c72d111cde6fbba9eed..09c5b9b196466165ce48c8c4b32490d91fdcea62 100644 --- a/indra/newview/llworldmapmessage.cpp +++ b/indra/newview/llworldmapmessage.cpp @@ -193,6 +193,9 @@ void LLWorldMapMessage::processMapBlockReply(LLMessageSystem* msg, void**) U32 x_world = (U32)(x_regions) * REGION_WIDTH_UNITS; U32 y_world = (U32)(y_regions) * REGION_WIDTH_UNITS; + // name shouldn't be empty, see EXT-4568 + llassert(!name.empty()); + // Insert that region in the world map, if failure, flag it as a "null_sim" if (!(LLWorldMap::getInstance()->insertRegion(x_world, y_world, name, image_id, (U32)accesscode, region_flags))) { diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index c02bf5741efa4bebe827d45c6acd72c9e2147867..cf632c085f6342ab73c2319b7fe26d7ef31ce421 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -114,7 +114,7 @@ with the same filename but different name <texture name="DisclosureArrow_Opened_Off" file_name="widgets/DisclosureArrow_Opened_Off.png" preload="true" /> <texture name="DownArrow" file_name="bottomtray/DownArrow.png" preload="false" /> - <texture name="DownArrow_Off" file_name="icons/DownArrow_off.png" preload="false" /> + <texture name="DownArrow_Off" file_name="icons/DownArrow_Off.png" preload="false" /> <texture name="Dragbar" file_name="windows/Dragbar.png" preload="false" scale.left="35" scale.top="5" scale.right="29" scale.bottom="5" /> <texture name="DropDown_Disabled" file_name="widgets/DropDown_Disabled.png" preload="true" scale.left="4" scale.top="19" scale.right="99" scale.bottom="4" /> 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 e084216a69d2c80db722f74a85a4adebc57c5b32..9c3151fe07f3166bda3c4184a525dc3c7066ee13 100644 --- a/indra/newview/skins/default/xui/en/menu_outfit_tab.xml +++ b/indra/newview/skins/default/xui/en/menu_outfit_tab.xml @@ -18,6 +18,9 @@ name="wear_add"> <on_click function="Outfit.WearAdd" /> + <on_enable + function="Outfit.OnEnable" + parameter="wear_add" /> <on_visible function="Outfit.OnVisible" parameter="wear_add" /> @@ -28,6 +31,9 @@ name="take_off"> <on_click function="Outfit.TakeOff" /> + <on_enable + function="Outfit.OnEnable" + parameter="take_off" /> <on_visible function="Outfit.OnVisible" parameter="take_off" /> @@ -44,7 +50,7 @@ </menu_item_call> <menu_item_separator /> <menu_item_call - label="Rename" + label="Rename Outfit" layout="topleft" name="rename"> <on_click diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 20a2a7d954a5aea4fffb51641942de47802b90bd..673c09582630bfb236e22a7a334c5295dffe8116 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -2098,7 +2098,7 @@ Would you be my friend? type="alertmodal"> New outfit name: <form name="form"> - <input name="new_name" type="text"> + <input name="new_name" type="text" width="300"> [NAME] </input> <button diff --git a/indra/newview/skins/default/xui/en/panel_group_general.xml b/indra/newview/skins/default/xui/en/panel_group_general.xml index e79ae346279aebd8728cee3e977d6f544cb5821d..2af1a84400fb82da7d45253e09fe0f34dbc1c01e 100644 --- a/indra/newview/skins/default/xui/en/panel_group_general.xml +++ b/indra/newview/skins/default/xui/en/panel_group_general.xml @@ -243,7 +243,7 @@ Hover your mouse over the options for more help. top_pad="4" width="190"> <combo_item name="select_mature" value="Select"> - - Select Mature - + - Select maturity rating - </combo_item> <combo_box.item label="Moderate Content"