diff options
Diffstat (limited to 'indra/newview')
24 files changed, 395 insertions, 114 deletions
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index b0211dd85b..d4aebe6cb1 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -11428,5 +11428,16 @@ <key>Value</key> <integer>180</integer> </map> + <key>HeightUnits</key> + <map> + <key>Comment</key> + <string>Determines which metric units are used: 1(TRUE) for meter and 0(FALSE) for foot.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> </map> </llsd> diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index acf43dda1e..342f9a5d80 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -2006,6 +2006,8 @@ bool LLAgentWearables::moveWearable(const LLViewerInventoryItem* item, bool clos // static void LLAgentWearables::createWearable(LLWearableType::EType type, bool wear, const LLUUID& parent_id) { + if (type == LLWearableType::WT_INVALID || type == LLWearableType::WT_NONE) return; + LLWearable* wearable = LLWearableList::instance().createNewWearable(type); LLAssetType::EType asset_type = wearable->getAssetType(); LLInventoryType::EType inv_type = LLInventoryType::IT_WEARABLE; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 95084666bb..82bd59d25c 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -331,10 +331,6 @@ const char *VFS_INDEX_FILE_BASE = "index.db2.x."; static std::string gWindowTitle; -std::string gLoginPage; -std::vector<std::string> gLoginURIs; -static std::string gHelperURI; - LLAppViewer::LLUpdaterInfo *LLAppViewer::sUpdaterInfo = NULL ; void idle_afk_check() diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index 01d6c3a8d5..2dafe295fe 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -656,6 +656,8 @@ void LLAvatarActions::shareWithAvatars() LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(give_inventory, _1, _2), TRUE, FALSE); picker->setOkBtnEnableCb(boost::bind(is_give_inventory_acceptable)); + picker->openFriendsTab(); + LLNotificationsUtil::add("ShareNotification"); } // static diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp index 916d53da3c..611396b0e5 100644 --- a/indra/newview/llcofwearables.cpp +++ b/indra/newview/llcofwearables.cpp @@ -58,13 +58,19 @@ static const LLWearableItemNameComparator WEARABLE_NAME_COMPARATOR; class CofContextMenu : public LLListContextMenu { protected: - static void updateCreateWearableLabel(LLMenuGL* menu, const LLUUID& item_id) + CofContextMenu(LLCOFWearables* cof_wearables) + : mCOFWearables(cof_wearables) + { + llassert(mCOFWearables); + } + + void updateCreateWearableLabel(LLMenuGL* menu, const LLUUID& item_id) { LLMenuItemGL* menu_item = menu->getChild<LLMenuItemGL>("create_new"); + LLWearableType::EType w_type = getWearableType(item_id); // Hide the "Create new <WEARABLE_TYPE>" if it's irrelevant. - LLViewerInventoryItem* item = gInventory.getLinkedItem(item_id); - if (!item || !item->isWearableType()) + if (w_type == LLWearableType::WT_NONE) { menu_item->setVisible(FALSE); return; @@ -72,25 +78,67 @@ protected: // Set proper label for the "Create new <WEARABLE_TYPE>" menu item. LLStringUtil::format_map_t args; - LLWearableType::EType w_type = item->getWearableType(); args["[WEARABLE_TYPE]"] = LLWearableType::getTypeDefaultNewName(w_type); std::string new_label = LLTrans::getString("CreateNewWearable", args); menu_item->setLabel(new_label); } - static void createNew(const LLUUID& item_id) + void createNew(const LLUUID& item_id) { - LLViewerInventoryItem* item = gInventory.getLinkedItem(item_id); - if (!item || !item->isWearableType()) return; + LLAgentWearables::createWearable(getWearableType(item_id), true); + } + + // Get wearable type of the given item. + // + // There is a special case: so-called "dummy items" + // (i.e. the ones that are there just to indicate that you're not wearing + // any wearables of the corresponding type. They are currently grayed out + // and suffixed with "not worn"). + // Those items don't have an UUID, but they do have an associated wearable type. + // If the user has invoked context menu for such item, + // we ignore the passed item_id and retrieve wearable type from the item. + LLWearableType::EType getWearableType(const LLUUID& item_id) + { + if (!isDummyItem(item_id)) + { + LLViewerInventoryItem* item = gInventory.getLinkedItem(item_id); + if (item && item->isWearableType()) + { + return item->getWearableType(); + } + } + else if (mCOFWearables) // dummy item selected + { + LLPanelDummyClothingListItem* item; + + item = dynamic_cast<LLPanelDummyClothingListItem*>(mCOFWearables->getSelectedItem()); + if (item) + { + return item->getWearableType(); + } + } + + return LLWearableType::WT_NONE; + } - LLAgentWearables::createWearable(item->getWearableType(), true); + static bool isDummyItem(const LLUUID& item_id) + { + return item_id.isNull(); } + + LLCOFWearables* mCOFWearables; }; ////////////////////////////////////////////////////////////////////////// -class CofAttachmentContextMenu : public LLListContextMenu +class CofAttachmentContextMenu : public CofContextMenu { +public: + CofAttachmentContextMenu(LLCOFWearables* cof_wearables) + : CofContextMenu(cof_wearables) + { + } + protected: /*virtual*/ LLContextMenu* createMenu() @@ -108,8 +156,13 @@ protected: class CofClothingContextMenu : public CofContextMenu { -protected: +public: + CofClothingContextMenu(LLCOFWearables* cof_wearables) + : CofContextMenu(cof_wearables) + { + } +protected: /*virtual*/ LLContextMenu* createMenu() { LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; @@ -121,7 +174,7 @@ protected: registrar.add("Clothing.MoveUp", boost::bind(moveWearable, selected_id, false)); registrar.add("Clothing.MoveDown", boost::bind(moveWearable, selected_id, true)); registrar.add("Clothing.Edit", boost::bind(LLAgentWearables::editWearable, selected_id)); - registrar.add("Clothing.Create", boost::bind(createNew, selected_id)); + registrar.add("Clothing.Create", boost::bind(&CofClothingContextMenu::createNew, this, selected_id)); enable_registrar.add("Clothing.OnEnable", boost::bind(&CofClothingContextMenu::onEnable, this, _2)); @@ -171,8 +224,13 @@ protected: class CofBodyPartContextMenu : public CofContextMenu { -protected: +public: + CofBodyPartContextMenu(LLCOFWearables* cof_wearables) + : CofContextMenu(cof_wearables) + { + } +protected: /*virtual*/ LLContextMenu* createMenu() { LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; @@ -184,7 +242,7 @@ protected: LLPanelOutfitEdit* panel_oe = dynamic_cast<LLPanelOutfitEdit*>(LLSideTray::getInstance()->getPanel("panel_outfit_edit")); registrar.add("BodyPart.Replace", boost::bind(&LLPanelOutfitEdit::onReplaceBodyPartMenuItemClicked, panel_oe, selected_id)); registrar.add("BodyPart.Edit", boost::bind(LLAgentWearables::editWearable, selected_id)); - registrar.add("BodyPart.Create", boost::bind(createNew, selected_id)); + registrar.add("BodyPart.Create", boost::bind(&CofBodyPartContextMenu::createNew, this, selected_id)); enable_registrar.add("BodyPart.OnEnable", boost::bind(&CofBodyPartContextMenu::onEnable, this, _2)); @@ -219,9 +277,9 @@ LLCOFWearables::LLCOFWearables() : LLPanel(), mBodyParts(NULL), mLastSelectedList(NULL) { - mClothingMenu = new CofClothingContextMenu(); - mAttachmentMenu = new CofAttachmentContextMenu(); - mBodyPartMenu = new CofBodyPartContextMenu(); + mClothingMenu = new CofClothingContextMenu(this); + mAttachmentMenu = new CofAttachmentContextMenu(this); + mBodyPartMenu = new CofBodyPartContextMenu(this); }; LLCOFWearables::~LLCOFWearables() diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index 96364f9418..8f6816b845 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -446,6 +446,19 @@ BOOL LLFloaterAvatarPicker::handleDragAndDrop(S32 x, S32 y, MASK mask, return TRUE; } + +void LLFloaterAvatarPicker::openFriendsTab() +{ + LLTabContainer* tab_container = getChild<LLTabContainer>("ResidentChooserTabs"); + if (tab_container == NULL) + { + llassert(tab_container != NULL); + return; + } + + tab_container->selectTabByName("FriendsPanel"); +} + // static void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void**) { diff --git a/indra/newview/llfloateravatarpicker.h b/indra/newview/llfloateravatarpicker.h index e69b814f9f..0af72e85a0 100644 --- a/indra/newview/llfloateravatarpicker.h +++ b/indra/newview/llfloateravatarpicker.h @@ -66,6 +66,8 @@ public: void *cargo_data, EAcceptance *accept, std::string& tooltip_msg); + void openFriendsTab(); + private: void editKeystroke(class LLLineEditor* caller, void* user_data); diff --git a/indra/newview/llfloatermap.cpp b/indra/newview/llfloatermap.cpp index c259659083..e74bfae026 100644 --- a/indra/newview/llfloatermap.cpp +++ b/indra/newview/llfloatermap.cpp @@ -54,7 +54,10 @@ // Constants // const F32 MAP_MINOR_DIR_THRESHOLD = 0.08f; - +const S32 MAP_PADDING_LEFT = 0; +const S32 MAP_PADDING_TOP = 2; +const S32 MAP_PADDING_RIGHT = 2; +const S32 MAP_PADDING_BOTTOM = 0; // // Member functions // @@ -106,7 +109,8 @@ BOOL LLFloaterMap::postBuild() mPopupMenu->setItemEnabled ("Stop Tracking", false); } - stretchMiniMap(getRect().getWidth(),getRect().getHeight()); + stretchMiniMap(getRect().getWidth() - MAP_PADDING_LEFT - MAP_PADDING_RIGHT + ,getRect().getHeight() - MAP_PADDING_TOP - MAP_PADDING_BOTTOM); updateMinorDirections(); @@ -238,7 +242,7 @@ void LLFloaterMap::stretchMiniMap(S32 width,S32 height) if(mMap) { LLRect map_rect; - map_rect.setLeftTopAndSize( 0, getRect().getHeight(), width, height); + map_rect.setLeftTopAndSize( MAP_PADDING_LEFT, getRect().getHeight() - MAP_PADDING_TOP, width, height); mMap->reshape( width, height, 1); mMap->setRect(map_rect); } @@ -248,7 +252,8 @@ void LLFloaterMap::reshape(S32 width, S32 height, BOOL called_from_parent) { LLFloater::reshape(width, height, called_from_parent); - stretchMiniMap(width, height); + stretchMiniMap(width - MAP_PADDING_LEFT - MAP_PADDING_RIGHT + ,height - MAP_PADDING_TOP - MAP_PADDING_BOTTOM); updateMinorDirections(); } diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 293585cd9c..7ce96a6ac1 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -2209,13 +2209,7 @@ void LLFolderBridge::determineFolderType() BOOL LLFolderBridge::isItemRenameable() const { - LLViewerInventoryCategory* cat = (LLViewerInventoryCategory*)getCategory(); - if(cat && !LLFolderType::lookupIsProtectedType(cat->getPreferredType()) - && (cat->getOwnerID() == gAgent.getID())) - { - return TRUE; - } - return FALSE; + return get_is_category_renameable(getInventoryModel(), mUUID); } void LLFolderBridge::restoreItem() diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index ca6cede7e9..c86d463a08 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -309,6 +309,11 @@ BOOL get_is_category_removable(const LLInventoryModel* model, const LLUUID& id) BOOL get_is_category_renameable(const LLInventoryModel* model, const LLUUID& id) { + if (!model) + { + return FALSE; + } + LLViewerInventoryCategory* cat = model->getCategory(id); if (cat && !LLFolderType::lookupIsProtectedType(cat->getPreferredType()) && diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp index f1c13de8bb..1beaaf3cb4 100644 --- a/indra/newview/llnearbychat.cpp +++ b/indra/newview/llnearbychat.cpp @@ -49,7 +49,6 @@ #include "llchannelmanager.h" #include "llagent.h" // gAgent -#include "llfloaterscriptdebug.h" #include "llchathistory.h" #include "llstylemap.h" @@ -163,25 +162,6 @@ std::string appendTime() void LLNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args) { - if (chat.mChatType == CHAT_TYPE_DEBUG_MSG) - { - if(gSavedSettings.getBOOL("ShowScriptErrors") == FALSE) - return; - if (gSavedSettings.getS32("ShowScriptErrorsLocation")== 1)// show error in window //("ScriptErrorsAsChat")) - { - - LLColor4 txt_color; - - LLViewerChat::getChatColor(chat,txt_color); - - LLFloaterScriptDebug::addScriptLine(chat.mText, - chat.mFromName, - txt_color, - chat.mFromID); - return; - } - } - LLChat& tmp_chat = const_cast<LLChat&>(chat); if(tmp_chat.mTimeStr.empty()) diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp index 9824517ed1..4b5e765c4f 100644 --- a/indra/newview/llnearbychathandler.cpp +++ b/indra/newview/llnearbychathandler.cpp @@ -36,6 +36,7 @@ #include "llbottomtray.h" #include "llchatitemscontainerctrl.h" +#include "llfloaterscriptdebug.h" #include "llnearbychat.h" #include "llrecentpeople.h" @@ -287,7 +288,7 @@ void LLNearbyChatScreenChannel::showToastsBottom() toast_rect.setLeftTopAndSize(getRect().mLeft , bottom + toast_rect.getHeight(), toast_rect.getWidth() ,toast_rect.getHeight()); toast->setRect(toast_rect); - bottom += toast_rect.getHeight() + margin; + bottom += toast_rect.getHeight() - toast->getTopPad() + margin; } // use reverse order to provide correct z-order and avoid toast blinking @@ -358,6 +359,29 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg, const LLSD &args) //if(tmp_chat.mFromName.empty() && tmp_chat.mFromID!= LLUUID::null) // tmp_chat.mFromName = tmp_chat.mFromID.asString(); } + + // don't show toast and add message to chat history on receive debug message + // with disabled setting showing script errors or enabled setting to show script + // errors in separate window. + if (chat_msg.mChatType == CHAT_TYPE_DEBUG_MSG) + { + if(gSavedSettings.getBOOL("ShowScriptErrors") == FALSE) + return; + if (gSavedSettings.getS32("ShowScriptErrorsLocation")== 1)// show error in window //("ScriptErrorsAsChat")) + { + + LLColor4 txt_color; + + LLViewerChat::getChatColor(chat_msg,txt_color); + + LLFloaterScriptDebug::addScriptLine(chat_msg.mText, + chat_msg.mFromName, + txt_color, + chat_msg.mFromID); + return; + } + } + nearby_chat->addMessage(chat_msg, true, args); if( nearby_chat->getVisible() || ( chat_msg.mSourceType == CHAT_SOURCE_AGENT diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index a1a9300ec2..1aedfec86f 100644 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -61,6 +61,9 @@ #include "llagentcamera.h" #include "llmorphview.h" +#include "llcommandhandler.h" +#include "lltextutil.h" + // register panel with appropriate XML static LLRegisterPanelClassWrapper<LLPanelEditWearable> t_edit_wearable("panel_edit_wearable"); @@ -608,6 +611,36 @@ LLPanelEditWearable::~LLPanelEditWearable() } +bool LLPanelEditWearable::changeHeightUnits(const LLSD& new_value) +{ + updateMetricLayout( new_value.asBoolean() ); + updateTypeSpecificControls(LLWearableType::WT_SHAPE); + return true; +} + +void LLPanelEditWearable::updateMetricLayout(BOOL new_value) +{ + LLUIString current_metric, replacment_metric; + current_metric = new_value ? mMeters : mFeet; + replacment_metric = new_value ? mFeet : mMeters; + mHeigthValue.setArg( "[METRIC1]", current_metric.getString() ); + mReplacementMetricUrl.setArg( "[URL_METRIC2]", std::string("[secondlife:///app/metricsystem ") + replacment_metric.getString() + std::string("]")); +} + +void LLPanelEditWearable::updateAvatarHeightLabel() +{ + mTxtAvatarHeight->setText(LLStringUtil::null); + LLStyle::Params param; + param.color = mAvatarHeigthLabelColor; + mTxtAvatarHeight->appendText(mHeigth, false, param); + param.color = mAvatarHeigthValueLabelColor; + mTxtAvatarHeight->appendText(mHeigthValue, false, param); + param.color = mAvatarHeigthLabelColor; // using mAvatarHeigthLabelColor for '/' separator + mTxtAvatarHeight->appendText(" / ", false, param); + mTxtAvatarHeight->appendText(this->mReplacementMetricUrl, false, param); +} + + // virtual BOOL LLPanelEditWearable::postBuild() { @@ -700,6 +733,20 @@ BOOL LLPanelEditWearable::postBuild() for_each_picker_ctrl_entry <LLTextureCtrl> (getPanel(type), type, boost::bind(init_texture_ctrl, this, _1, _2)); } + // init all strings + mMeters = mPanelShape->getString("meters"); + mFeet = mPanelShape->getString("feet"); + mHeigth = mPanelShape->getString("height") + " "; + mHeigthValue = "[HEIGHT] [METRIC1]"; + mReplacementMetricUrl = "[URL_METRIC2]"; + + std::string color = mPanelShape->getString("heigth_label_color"); + mAvatarHeigthLabelColor = LLUIColorTable::instance().getColor(color, LLColor4::green); + color = mPanelShape->getString("heigth_value_label_color"); + mAvatarHeigthValueLabelColor = LLUIColorTable::instance().getColor(color, LLColor4::green); + gSavedSettings.getControl("HeightUnits")->getSignal()->connect(boost::bind(&LLPanelEditWearable::changeHeightUnits, this, _2)); + updateMetricLayout(gSavedSettings.getBOOL("HeightUnits")); + return TRUE; } @@ -1107,12 +1154,22 @@ void LLPanelEditWearable::toggleTypeSpecificControls(LLWearableType::EType type) void LLPanelEditWearable::updateTypeSpecificControls(LLWearableType::EType type) { + const F32 ONE_METER = 1.0; + const F32 ONE_FOOT = 0.3048 * ONE_METER; // in meters // Update controls specific to shape editing panel. if (type == LLWearableType::WT_SHAPE) { // Update avatar height - std::string avatar_height_str = llformat("%.2f", gAgentAvatarp->mBodySize.mV[VZ]); - mTxtAvatarHeight->setTextArg("[HEIGHT]", avatar_height_str); + F32 new_size = gAgentAvatarp->mBodySize.mV[VZ]; + if (gSavedSettings.getBOOL("HeightUnits") == FALSE) + { + // convert meters to feet + new_size = new_size / ONE_FOOT; + } + + std::string avatar_height_str = llformat("%.2f", new_size); + mHeigthValue.setArg("[HEIGHT]", avatar_height_str); + updateAvatarHeightLabel(); } if (LLWearableType::WT_ALPHA == type) @@ -1381,4 +1438,21 @@ void LLPanelEditWearable::initPreviousAlphaTextureEntry(LLVOAvatarDefines::EText } } +// handle secondlife:///app/metricsystem +class LLMetricSystemHandler : public LLCommandHandler +{ +public: + LLMetricSystemHandler() : LLCommandHandler("metricsystem", UNTRUSTED_THROTTLE) { } + + bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web) + { + // change height units TRUE for meters and FALSE for feet + BOOL new_value = (gSavedSettings.getBOOL("HeightUnits") == FALSE) ? TRUE : FALSE; + gSavedSettings.setBOOL("HeightUnits", new_value); + return true; + } +}; + +LLMetricSystemHandler gMetricSystemHandler; + // EOF diff --git a/indra/newview/llpaneleditwearable.h b/indra/newview/llpaneleditwearable.h index 54f729fa7a..c63671fcc9 100644 --- a/indra/newview/llpaneleditwearable.h +++ b/indra/newview/llpaneleditwearable.h @@ -104,6 +104,15 @@ private: void initPreviousAlphaTextures(); void initPreviousAlphaTextureEntry(LLVOAvatarDefines::ETextureIndex te); + // callback for HeightUnits parameter. + bool changeHeightUnits(const LLSD& new_value); + + // updates current metric and replacemet metric label text + void updateMetricLayout(BOOL new_value); + + // updates avatar height label + void updateAvatarHeightLabel(); + // the pointer to the wearable we're editing. NULL means we're not editing a wearable. LLWearable *mWearablePtr; LLViewerInventoryItem* mWearableItem; @@ -117,6 +126,18 @@ private: LLTextBox *mTxtAvatarHeight; + // localized and parametrized strings that used to build avatar_height_label + std::string mMeters; + std::string mFeet; + std::string mHeigth; + LLUIString mHeigthValue; + LLUIString mReplacementMetricUrl; + + // color for mHeigth string + LLUIColor mAvatarHeigthLabelColor; + // color for mHeigthValue string + LLUIColor mAvatarHeigthValueLabelColor; + // This text editor reference will change each time we edit a new wearable - // it will be grabbed from the currently visible panel LLTextEditor *mTextEditor; diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index 7fb46fc84f..ce1131f45c 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -334,7 +334,7 @@ void LLLandmarksPanel::updateVerbs() bool landmark_selected = isLandmarkSelected(); mTeleportBtn->setEnabled(landmark_selected && isActionEnabled("teleport")); mShowProfile->setEnabled(landmark_selected && isActionEnabled("more_info")); - mShowOnMapBtn->setEnabled(true); + mShowOnMapBtn->setEnabled(landmark_selected && isActionEnabled("show_on_map")); // TODO: mantipov: Uncomment when mShareBtn is supported // Share button should be enabled when neither a folder nor a landmark is selected diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index e07d5c064b..3d0684afca 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -189,7 +189,8 @@ LLPanelOutfitEdit::LLPanelOutfitEdit() mInitialized(false), mAddWearablesPanel(NULL), mWearableListMaskCollector(NULL), - mWearableListTypeCollector(NULL) + mWearableListTypeCollector(NULL), + mFilterComboBox(NULL) { mSavedFolderState = new LLSaveFolderState(); mSavedFolderState->setApply(FALSE); @@ -235,12 +236,13 @@ BOOL LLPanelOutfitEdit::postBuild() mListViewBtn = getChild<LLButton>("list_view_btn"); childSetCommitCallback("filter_button", boost::bind(&LLPanelOutfitEdit::showWearablesFilter, this), NULL); - childSetCommitCallback("folder_view_btn", boost::bind(&LLPanelOutfitEdit::showFilteredFolderWearablesPanel, this), NULL); - childSetCommitCallback("list_view_btn", boost::bind(&LLPanelOutfitEdit::showFilteredWearablesPanel, this), NULL); + childSetCommitCallback("folder_view_btn", boost::bind(&LLPanelOutfitEdit::showWearablesFolderView, this), NULL); + childSetCommitCallback("list_view_btn", boost::bind(&LLPanelOutfitEdit::showWearablesListView, this), NULL); childSetCommitCallback("wearables_gear_menu_btn", boost::bind(&LLPanelOutfitEdit::onGearButtonClick, this, _1), NULL); + childSetCommitCallback("gear_menu_btn", boost::bind(&LLPanelOutfitEdit::onGearButtonClick, this, _1), NULL); mCOFWearables = getChild<LLCOFWearables>("cof_wearables_list"); - mCOFWearables->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onOutfitItemSelectionChange, this)); + mCOFWearables->setCommitCallback(boost::bind(&LLPanelOutfitEdit::filterWearablesBySelectedItem, this)); mCOFWearables->getCOFCallbacks().mAddWearable = boost::bind(&LLPanelOutfitEdit::onAddWearableClicked, this); mCOFWearables->getCOFCallbacks().mEditWearable = boost::bind(&LLPanelOutfitEdit::onEditWearableClicked, this); @@ -258,19 +260,20 @@ BOOL LLPanelOutfitEdit::postBuild() mCOFDragAndDropObserver = new LLCOFDragAndDropObserver(mInventoryItemsPanel->getModel()); - LLComboBox* type_filter = getChild<LLComboBox>("filter_wearables_combobox"); - type_filter->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onTypeFilterChanged, this, _1)); - type_filter->removeall(); + mFilterComboBox = getChild<LLComboBox>("filter_wearables_combobox"); + mFilterComboBox->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onTypeFilterChanged, this, _1)); + mFilterComboBox->removeall(); for (U32 i = 0; i < mLookItemTypes.size(); ++i) { - type_filter->add(mLookItemTypes[i].displayName); + mFilterComboBox->add(mLookItemTypes[i].displayName); } - type_filter->setCurrentByIndex(LIT_ALL); + mFilterComboBox->setCurrentByIndex(LIT_ALL); mSearchFilter = getChild<LLFilterEditor>("look_item_filter"); mSearchFilter->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onSearchEdit, this, _2)); - childSetAction("show_add_wearables_btn", boost::bind(&LLPanelOutfitEdit::toggleAddWearablesPanel, this)); + childSetAction("show_add_wearables_btn", boost::bind(&LLPanelOutfitEdit::onAddMoreButtonClicked, this)); + childSetAction("add_to_outfit_btn", boost::bind(&LLPanelOutfitEdit::onAddToOutfitClicked, this)); mEditWearableBtn = getChild<LLButton>("edit_wearable_btn"); @@ -353,7 +356,7 @@ void LLPanelOutfitEdit::showWearablesFilter() } } -void LLPanelOutfitEdit::showFilteredWearablesPanel() +void LLPanelOutfitEdit::showWearablesListView() { if(switchPanels(mInventoryItemsPanel, mWearableItemsPanel)) { @@ -364,7 +367,7 @@ void LLPanelOutfitEdit::showFilteredWearablesPanel() mListViewBtn->setToggleState(TRUE); } -void LLPanelOutfitEdit::showFilteredFolderWearablesPanel() +void LLPanelOutfitEdit::showWearablesFolderView() { if(switchPanels(mWearableItemsPanel, mInventoryItemsPanel)) { @@ -377,17 +380,12 @@ void LLPanelOutfitEdit::showFilteredFolderWearablesPanel() void LLPanelOutfitEdit::onTypeFilterChanged(LLUICtrl* ctrl) { - LLComboBox* type_filter = dynamic_cast<LLComboBox*>(ctrl); - llassert(type_filter); - if (type_filter) - { - U32 curr_filter_type = type_filter->getCurrentIndex(); - mInventoryItemsPanel->setFilterTypes(mLookItemTypes[curr_filter_type].inventoryMask); + U32 curr_filter_type = mFilterComboBox->getCurrentIndex(); + mInventoryItemsPanel->setFilterTypes(mLookItemTypes[curr_filter_type].inventoryMask); + + mWearableListMaskCollector->setFilterMask(mLookItemTypes[curr_filter_type].inventoryMask); + mWearableListManager->setFilterCollector(mWearableListMaskCollector); - mWearableListMaskCollector->setFilterMask(mLookItemTypes[curr_filter_type].inventoryMask); - mWearableListManager->setFilterCollector(mWearableListMaskCollector); - } - mSavedFolderState->setApply(TRUE); mInventoryItemsPanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState); @@ -471,7 +469,7 @@ void LLPanelOutfitEdit::onAddWearableClicked(void) if(item) { - showFilteredWearableItemsList(item->getWearableType()); + showFilteredWearablesListView(item->getWearableType()); } } @@ -481,7 +479,7 @@ void LLPanelOutfitEdit::onReplaceBodyPartMenuItemClicked(LLUUID selected_item_id if (item && item->getType() == LLAssetType::AT_BODYPART) { - showFilteredWearableItemsList(item->getWearableType()); + showFilteredWearablesListView(item->getWearableType()); } } @@ -538,24 +536,81 @@ void LLPanelOutfitEdit::onInventorySelectionChange(const std::deque<LLFolderView current_item->addChild(mAddToLookBtn); */ } -void LLPanelOutfitEdit::onOutfitItemSelectionChange(void) -{ - LLUUID item_id = mCOFWearables->getSelectedUUID(); - //*TODO show Edit Wearable Button +void LLPanelOutfitEdit::applyFilter(e_look_item_type type) +{ + mFilterComboBox->setCurrentByIndex(type); + mFilterComboBox->onCommit(); +} + +void LLPanelOutfitEdit::filterWearablesBySelectedItem(void) +{ + if (!mAddWearablesPanel->getVisible()) return; + + uuid_vec_t ids; + mCOFWearables->getSelectedUUIDs(ids); - LLViewerInventoryItem* item_to_remove = gInventory.getItem(item_id); - if (!item_to_remove) return; + bool nothing_selected = ids.empty(); + bool one_selected = ids.size() == 1; + bool more_than_one_selected = ids.size() > 1; + bool is_dummy_item = (ids.size() && dynamic_cast<LLPanelDummyClothingListItem*>(mCOFWearables->getSelectedItem())); - switch (item_to_remove->getType()) + //resetting selection if no item is selected or than one item is selected + if (nothing_selected || more_than_one_selected) { - case LLAssetType::AT_CLOTHING: - case LLAssetType::AT_OBJECT: - default: - break; + if (nothing_selected) + { + showWearablesFolderView(); + } + + if (more_than_one_selected) + { + showWearablesListView(); + } + + applyFilter(LIT_ALL); + return; } + + + //filter wearables by a type represented by a dummy item + if (one_selected && is_dummy_item) + { + onAddWearableClicked(); + return; + } + + LLViewerInventoryItem* item = gInventory.getItem(ids[0]); + if (!item && ids[0].notNull()) + { + //Inventory misses an item with non-zero id + showWearablesListView(); + applyFilter(LIT_ALL); + return; + } + + if (one_selected && !is_dummy_item) + { + if (item->isWearableType()) + { + //single clothing or bodypart item is selected + showFilteredWearablesListView(item->getWearableType()); + mFilterComboBox->setLabel(getString("Filter.Custom")); + return; + } + else + { + //attachment is selected + showWearablesListView(); + applyFilter(LIT_ATTACHMENT); + return; + } + } + } + + void LLPanelOutfitEdit::update() { mCOFWearables->refresh(); @@ -676,12 +731,21 @@ void LLPanelOutfitEdit::onGearButtonClick(LLUICtrl* clicked_button) LLMenuGL::showPopup(clicked_button, mGearMenu, 0, menu_y); } -void LLPanelOutfitEdit::showFilteredWearableItemsList(LLWearableType::EType type) +void LLPanelOutfitEdit::onAddMoreButtonClicked() +{ + toggleAddWearablesPanel(); + filterWearablesBySelectedItem(); +} + +void LLPanelOutfitEdit::showFilteredWearablesListView(LLWearableType::EType type) { + mFilterComboBox->setLabel(getString("Filter.Custom")); mWearableListTypeCollector->setType(type); mWearableListManager->setFilterCollector(mWearableListTypeCollector); showAddWearablesPanel(true); - showFilteredWearablesPanel(); + showWearablesListView(); } + + // EOF diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h index 24ecf75c18..d19ede04f1 100644 --- a/indra/newview/llpaneloutfitedit.h +++ b/indra/newview/llpaneloutfitedit.h @@ -47,6 +47,7 @@ class LLButton; class LLCOFWearables; +class LLComboBox; class LLTextBox; class LLInventoryCategory; class LLOutfitObserver; @@ -94,15 +95,27 @@ public: void toggleAddWearablesPanel(); void showAddWearablesPanel(bool show__add_wearables); + + //following methods operate with "add wearables" panel void showWearablesFilter(); - void showFilteredWearablesPanel(); - void showFilteredFolderWearablesPanel(); + void showWearablesListView(); + void showWearablesFolderView(); void onTypeFilterChanged(LLUICtrl* ctrl); void onSearchEdit(const std::string& string); void onInventorySelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action); void onAddToOutfitClicked(void); - void onOutfitItemSelectionChange(void); + + void applyFilter(e_look_item_type type); + + /** + * Filter items in views of Add Wearables Panel and show appropriate view depending on currently selected COF item(s) + * No COF items selected - shows the folder view, reset filter + * 1 COF item selected - shows the list view and filters wearables there by a wearable type of the selected item + * More than 1 COF item selected - shows the list view and filters it by a type of the selected item (attachment or clothing) + */ + void filterWearablesBySelectedItem(void); + void onRemoveFromOutfitClicked(void); void onEditWearableClicked(void); void onAddWearableClicked(void); @@ -132,7 +145,8 @@ public: private: void onGearButtonClick(LLUICtrl* clicked_button); - void showFilteredWearableItemsList(LLWearableType::EType type); + void onAddMoreButtonClicked(); + void showFilteredWearablesListView(LLWearableType::EType type); LLTextBox* mCurrentOutfitName; @@ -145,6 +159,7 @@ private: LLButton* mFolderViewBtn; LLButton* mListViewBtn; LLPanel* mAddWearablesPanel; + LLComboBox* mFilterComboBox; LLFindNonLinksByMask* mWearableListMaskCollector; LLFindWearablesOfType* mWearableListTypeCollector; @@ -162,6 +177,8 @@ private: bool mInitialized; std::auto_ptr<LLSaveOutfitComboBtn> mSaveComboBtn; + + }; #endif // LL_LLPANELOUTFITEDIT_H diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index e8b6c6bfe5..494cba8c6f 100644 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -564,6 +564,7 @@ void LLTeleportHistoryPanel::updateVerbs() { mTeleportBtn->setEnabled(false); mShowProfile->setEnabled(false); + mShowOnMapBtn->setEnabled(false); return; } @@ -571,7 +572,7 @@ void LLTeleportHistoryPanel::updateVerbs() mTeleportBtn->setEnabled(NULL != itemp); mShowProfile->setEnabled(NULL != itemp); - mShowOnMapBtn->setEnabled(true); + mShowOnMapBtn->setEnabled(NULL != itemp); } void LLTeleportHistoryPanel::getNextTab(const LLDate& item_date, S32& tab_idx, LLDate& tab_date) diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp index 6c6eda2e68..db1f4dc4cb 100644 --- a/indra/newview/lltoastalertpanel.cpp +++ b/indra/newview/lltoastalertpanel.cpp @@ -172,6 +172,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal params.tab_stop(false); params.wrap(true); params.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP); + params.allow_scroll(true); LLTextBox * msg_box = LLUICtrlFactory::create<LLTextBox> (params); // Compute max allowable height for the dialog text, so we can allocate @@ -180,9 +181,16 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal gFloaterView->getRect().getHeight() - LINE_HEIGHT // title bar - 3*VPAD - BTN_HEIGHT; + // reshape to calculate real text width and height msg_box->reshape( MAX_ALLOWED_MSG_WIDTH, max_allowed_msg_height ); msg_box->setValue(msg); - msg_box->reshapeToFitText(); + + S32 pixel_width = msg_box->getTextPixelWidth(); + S32 pixel_height = msg_box->getTextPixelHeight(); + + // We should use some space to prevent set textbox's scroller visible when it is unnecessary. + msg_box->reshape( llmin(MAX_ALLOWED_MSG_WIDTH,pixel_width + 2 * msg_box->getHPad() + HPAD), + llmin(max_allowed_msg_height,pixel_height + 2 * msg_box->getVPad()) ) ; const LLRect& text_rect = msg_box->getRect(); S32 dialog_width = llmax( btn_total_width, text_rect.getWidth() ) + 2 * HPAD; diff --git a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml index b5eda8e999..c4e31ed180 100644 --- a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml +++ b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml @@ -170,7 +170,7 @@ <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 439f67e7b1..76a41a3b13 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -6207,7 +6207,7 @@ The button will be shown when there is enough space for it. icon="notifytip.tga" name="ShareNotification" type="notifytip"> -Drag items from inventory onto a person in the resident picker +Select residents to share with. </notification> <notification icon="notifytip.tga" diff --git a/indra/newview/skins/default/xui/en/panel_edit_shape.xml b/indra/newview/skins/default/xui/en/panel_edit_shape.xml index cf15fb0455..d295f5fe4a 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_shape.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_shape.xml @@ -8,19 +8,22 @@ name="edit_shape_panel" top_pad="10" width="333" > - <text - follows="top|left|right" - font="SansSerifSmallBold" - halign="right" - height="12" - layout="topleft" - left="0" - name="avatar_height" - text_color="EmphasisColor" - top="0" - width="310"> - [HEIGHT] Meters tall - </text> + <string name="meters">Meters</string> + <string name="feet">Feet</string> + <string name="height">Height:</string> + <string name="heigth_label_color" translate="false">White_50</string> + <string name="heigth_value_label_color" translate="false">White</string> + <text + follows="top|left|right" + font="SansSerifSmallBold" + halign="right" + height="12" + layout="topleft" + left="0" + name="avatar_height" + top="0" + width="310"> + </text> <panel border="false" bg_alpha_color="DkGray2" diff --git a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml index c9802a269c..741f60669a 100644 --- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml +++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml @@ -51,6 +51,7 @@ <string name="Filter.All" value="All"/> <string name="Filter.Clothes/Body" value="Clothes/Body"/> <string name="Filter.Objects" value="Objects"/> + <string name="Filter.Custom" value="Custom filter"/> <button diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 0d14a6b3c8..361af0e8fb 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -3181,7 +3181,7 @@ Abuse Report</string> <!-- language specific white-space characters, delimiters, spacers, item separation symbols --> <string name="sentences_separator" value=" "></string> - <string name="words_separator">, </string> + <string name="words_separator" value=", "/> <string name="server_is_down"> Despite our best efforts, something unexpected has gone wrong. |