diff options
106 files changed, 2123 insertions, 926 deletions
diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp index 40a9752268..27c0c0b640 100644 --- a/indra/llcharacter/llcharacter.cpp +++ b/indra/llcharacter/llcharacter.cpp @@ -389,27 +389,6 @@ void LLCharacter::clearVisualParamWeights() } //----------------------------------------------------------------------------- -// BOOL visualParamWeightsAreDefault() -//----------------------------------------------------------------------------- -BOOL LLCharacter::visualParamWeightsAreDefault() -{ - for (LLVisualParam *param = getFirstVisualParam(); - param; - param = getNextVisualParam()) - { - if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) - { - if (param->getWeight() != param->getDefaultWeight()) - return false; - } - } - - return true; -} - - - -//----------------------------------------------------------------------------- // getVisualParam() //----------------------------------------------------------------------------- LLVisualParam* LLCharacter::getVisualParam(const char *param_name) diff --git a/indra/llcharacter/llcharacter.h b/indra/llcharacter/llcharacter.h index 27e2a51c62..cac73c01b9 100644 --- a/indra/llcharacter/llcharacter.h +++ b/indra/llcharacter/llcharacter.h @@ -212,12 +212,9 @@ public: F32 getVisualParamWeight(const char* param_name); F32 getVisualParamWeight(S32 index); - // set all morph weights to 0 + // set all morph weights to defaults void clearVisualParamWeights(); - // see if all the weights are default - BOOL visualParamWeightsAreDefault(); - // visual parameter accessors LLVisualParam* getFirstVisualParam() { @@ -231,6 +228,21 @@ public: return (mCurIterator++)->second; } + S32 getVisualParamCountInGroup(const EVisualParamGroup group) const + { + S32 rtn = 0; + for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin(); + iter != mVisualParamIndexMap.end(); + /**/ ) + { + if ((iter++)->second->getGroup() == group) + { + ++rtn; + } + } + return rtn; + } + LLVisualParam* getVisualParam(S32 id) const { visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.find(id); diff --git a/indra/llcharacter/llvisualparam.cpp b/indra/llcharacter/llvisualparam.cpp index 297322fe58..703fe2f9cc 100644 --- a/indra/llcharacter/llvisualparam.cpp +++ b/indra/llcharacter/llvisualparam.cpp @@ -284,7 +284,7 @@ void LLVisualParam::setAnimationTarget(F32 target_value, BOOL upload_bake) void LLVisualParam::setNextParam( LLVisualParam *next ) { llassert(!mNext); - + llassert(getWeight() == getDefaultWeight()); // need to establish mNext before we start changing values on this, else initial value won't get mirrored (we can fix that, but better to forbid this pattern) mNext = next; } diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index a8f72183fd..34f3049f2e 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -636,8 +636,8 @@ void LLButton::draw() if (mFlashing) { - // if we have icon for flashing, use it as image for button - if(flash && mImageFlash->getName() != "FlashIconAbsent") + // if button should flash and we have icon for flashing, use it as image for button + if(flash && mImageFlash) { // setting flash to false to avoid its further influence on glow flash = false; diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h index b251c3d65d..9bd566d3c9 100644 --- a/indra/llui/llbutton.h +++ b/indra/llui/llbutton.h @@ -314,8 +314,7 @@ private: /* There are two ways an image can flash- by making changes in color according to flash_color attribute or by changing icon from current to the one specified in image_flash. Second way is used only if - the name of flash icon is different from "FlashIconAbsent" which is there by default. First way is used - otherwise. */ + flash icon name is set in attributes(by default it isn't). First way is used otherwise. */ LLPointer<LLUIImage> mImageFlash; LLUIColor mHighlightColor; diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 9ba44e787b..b00104c427 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -466,6 +466,7 @@ set(viewer_SOURCE_FILES llviewchildren.cpp llviewerassetstorage.cpp llviewerassettype.cpp + llviewerattachmenu.cpp llvieweraudio.cpp llviewercamera.cpp llviewerchat.cpp @@ -984,6 +985,7 @@ set(viewer_HEADER_FILES llviewchildren.h llviewerassetstorage.h llviewerassettype.h + llviewerattachmenu.h llvieweraudio.h llviewercamera.h llviewerchat.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index c0be54a105..6204c8047a 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -632,7 +632,18 @@ <key>BlockAvatarAppearanceMessages</key> <map> <key>Comment</key> - <string>Ignore's appearance messages (for simulating Ruth)</string> + <string>Ignores appearance messages (for simulating Ruth)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>BlockSomeAvatarAppearanceVisualParams</key> + <map> + <key>Comment</key> + <string>Drop around 50% of VisualParam occurances in appearance messages (for simulating Ruth)</string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -8294,17 +8305,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>ShowSidebarButton</key> - <map> - <key>Comment</key> - <string>Shows/hides Sidebar button in the bottom tray.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> <key>ShowSnapshotButton</key> <map> <key>Comment</key> @@ -8847,17 +8847,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>SidebarWithButtonsVisibility</key> - <map> - <key>Comment</key> - <string>Sets visibility of sidebar with its tabs' buttons</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> <key>SkinCurrent</key> <map> <key>Comment</key> @@ -11384,5 +11373,16 @@ <string>mini_map</string> </array> </map> + <key>LandmarksSortedByDate</key> + <map> + <key>Comment</key> + <string>Reflects landmarks panel sorting order.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> </map> </llsd> diff --git a/indra/newview/character/avatar_lad.xml b/indra/newview/character/avatar_lad.xml index 5efd997ab7..9564236ad2 100644 --- a/indra/newview/character/avatar_lad.xml +++ b/indra/newview/character/avatar_lad.xml @@ -4782,7 +4782,7 @@ group="1" name="Saddlebags" wearable="shape" - edit_grouo="driven" + edit_group="driven" value_min="-.5" value_max="3"> <param_morph> diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index e5796f8e63..d2a01aba16 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -1974,6 +1974,32 @@ bool LLAgentWearables::moveWearable(const LLViewerInventoryItem* item, bool clos } // static +void LLAgentWearables::createWearable(LLWearableType::EType type, bool wear, const LLUUID& parent_id) +{ + LLWearable* wearable = LLWearableList::instance().createNewWearable(type); + LLAssetType::EType asset_type = wearable->getAssetType(); + LLInventoryType::EType inv_type = LLInventoryType::IT_WEARABLE; + LLPointer<LLInventoryCallback> cb = wear ? new WearOnAvatarCallback : NULL; + LLUUID folder_id; + + if (parent_id.notNull()) + { + folder_id = parent_id; + } + else + { + LLFolderType::EType folder_type = LLFolderType::assetTypeToFolderType(asset_type); + folder_id = gInventory.findCategoryUUIDForType(folder_type); + } + + create_inventory_item(gAgent.getID(), gAgent.getSessionID(), + folder_id, wearable->getTransactionID(), wearable->getName(), + wearable->getDescription(), asset_type, inv_type, wearable->getType(), + wearable->getPermissions().getMaskNextOwner(), + cb); +} + +// static void LLAgentWearables::editWearable(const LLUUID& item_id) { LLViewerInventoryItem* item; diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h index 5d5c5ae371..6d379746ba 100644 --- a/indra/newview/llagentwearables.h +++ b/indra/newview/llagentwearables.h @@ -144,6 +144,7 @@ protected: //-------------------------------------------------------------------- public: + static void createWearable(LLWearableType::EType type, bool wear = false, const LLUUID& parent_id = LLUUID::null); static void editWearable(const LLUUID& item_id); bool moveWearable(const LLViewerInventoryItem* item, bool closer_to_body); diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index f27e632180..75ffb9f329 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -704,6 +704,40 @@ void LLAppearanceMgr::replaceCurrentOutfit(const LLUUID& new_outfit) wearInventoryCategory(cat, false, false); } +// Open outfit renaming dialog. +void LLAppearanceMgr::renameOutfit(const LLUUID& outfit_id) +{ + LLViewerInventoryCategory* cat = gInventory.getCategory(outfit_id); + if (!cat) + { + return; + } + + LLSD args; + args["NAME"] = cat->getName(); + + LLSD payload; + payload["cat_id"] = outfit_id; + + LLNotificationsUtil::add("RenameOutfit", args, payload, boost::bind(onOutfitRename, _1, _2)); +} + +// User typed new outfit name. +// static +void LLAppearanceMgr::onOutfitRename(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option != 0) return; // canceled + + std::string outfit_name = response["new_name"].asString(); + LLStringUtil::trim(outfit_name); + if (!outfit_name.empty()) + { + LLUUID cat_id = notification["payload"]["cat_id"].asUUID(); + rename_category(&gInventory, cat_id, outfit_name); + } +} + void LLAppearanceMgr::addCategoryToCurrentOutfit(const LLUUID& cat_id) { LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id); @@ -714,7 +748,7 @@ void LLAppearanceMgr::takeOffOutfit(const LLUUID& cat_id) { LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; - LLFindWearables collector; + LLFindWorn collector; gInventory.collectDescendentsIf(cat_id, cats, items, FALSE, collector); @@ -842,6 +876,41 @@ BOOL LLAppearanceMgr::getCanMakeFolderIntoOutfit(const LLUUID& folder_id) return ((required_wearables & folder_wearables) == required_wearables); } +bool LLAppearanceMgr::getCanRemoveOutfit(const LLUUID& outfit_cat_id) +{ + // Disallow removing the base outfit. + if (outfit_cat_id == getBaseOutfitUUID()) + { + return false; + } + + // Check if the outfit folder itself is removable. + if (!get_is_category_removable(&gInventory, outfit_cat_id)) + { + return false; + } + + // Check if the folder contains worn items. + LLInventoryModel::cat_array_t cats; + LLInventoryModel::item_array_t items; + LLFindWorn filter_worn; + gInventory.collectDescendentsIf(outfit_cat_id, cats, items, false, filter_worn); + if (!items.empty()) + { + return false; + } + + // Check for the folder's non-removable descendants. + LLFindNonRemovableObjects filter_non_removable; + LLInventoryModel::item_array_t::const_iterator it; + gInventory.collectDescendentsIf(outfit_cat_id, cats, items, false, filter_non_removable); + if (!cats.empty() || !items.empty()) + { + return false; + } + + return true; +} void LLAppearanceMgr::purgeBaseOutfitLink(const LLUUID& category) { diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index dbde055c3a..f1beef5857 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -59,6 +59,7 @@ public: void wearOutfitByName(const std::string& name); void changeOutfit(bool proceed, const LLUUID& category, bool append); void replaceCurrentOutfit(const LLUUID& new_outfit); + void renameOutfit(const LLUUID& outfit_id); void takeOffOutfit(const LLUUID& cat_id); void addCategoryToCurrentOutfit(const LLUUID& cat_id); @@ -69,6 +70,9 @@ public: // Return whether this folder contains minimal contents suitable for making a full outfit. BOOL getCanMakeFolderIntoOutfit(const LLUUID& folder_id); + // Determine whether a given outfit can be removed. + bool getCanRemoveOutfit(const LLUUID& outfit_cat_id); + // Copy all items in a category. void shallowCopyCategoryContents(const LLUUID& src_id, const LLUUID& dst_id, LLPointer<LLInventoryCallback> cb); @@ -180,6 +184,8 @@ private: void purgeCategory(const LLUUID& category, bool keep_outfit_links); void purgeBaseOutfitLink(const LLUUID& category); + static void onOutfitRename(const LLSD& notification, const LLSD& response); + std::set<LLUUID> mRegisteredAttachments; bool mAttachmentInvLinkEnabled; bool mOutfitIsDirty; diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index 875ed72a12..01d6c3a8d5 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -475,32 +475,83 @@ namespace action_give_inventory return acceptable; } - /** - * Performs "give inventory" operations for provided avatars. - * - * Sends one requests to give all selected inventory items for each passed avatar. - * Avatars are represent by two vectors: names and UUIDs which must be sychronized with each other. - * - * @param avatar_names - avatar names request to be sent. - * @param avatar_uuids - avatar names request to be sent. - */ - static void give_inventory(const std::vector<std::string>& avatar_names, const uuid_vec_t& avatar_uuids) + static void build_residents_string(const std::vector<std::string>& avatar_names, std::string& residents_string) { - llassert(avatar_names.size() == avatar_uuids.size()); + llassert(avatar_names.size() > 0); + + const std::string& separator = LLTrans::getString("words_separator"); + for (std::vector<std::string>::const_iterator it = avatar_names.begin(); ; ) + { + residents_string.append(*it); + if (++it == avatar_names.end()) + { + break; + } + residents_string.append(separator); + } + } + + static void build_items_string(const uuid_set_t& inventory_selected_uuids , std::string& items_string) + { + llassert(inventory_selected_uuids.size() > 0); + + const std::string& separator = LLTrans::getString("words_separator"); + for (uuid_set_t::const_iterator it = inventory_selected_uuids.begin(); ; ) + { + LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it); + if (NULL != inv_cat) + { + items_string = inv_cat->getName(); + break; + } + LLViewerInventoryItem* inv_item = gInventory.getItem(*it); + if (NULL != inv_item) + { + items_string.append(inv_item->getName()); + } + if(++it == inventory_selected_uuids.end()) + { + break; + } + items_string.append(separator); + } + } + + struct LLShareInfo : public LLSingleton<LLShareInfo> + { + std::vector<std::string> mAvatarNames; + uuid_vec_t mAvatarUuids; + }; + + static void give_inventory_cb(const LLSD& notification, const LLSD& response) + { + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + // if Cancel pressed + if (option == 1) + { + return; + } LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); - if (NULL == active_panel) return; + if (NULL == active_panel) + { + return; + } const uuid_set_t inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList(); - if (inventory_selected_uuids.empty()) return; + if (inventory_selected_uuids.empty()) + { + return; + } - S32 count = llmin(avatar_names.size(), avatar_uuids.size()); + S32 count = LLShareInfo::instance().mAvatarNames.size(); + bool shared = false; // iterate through avatars for(S32 i = 0; i < count; ++i) { - const std::string& avatar_name = avatar_names[i]; - const LLUUID& avatar_uuid = avatar_uuids[i]; + const std::string& avatar_name = LLShareInfo::instance().mAvatarNames[i]; + const LLUUID& avatar_uuid = LLShareInfo::instance().mAvatarUuids[i]; // Start up IM before give the item const LLUUID session_id = gIMMgr->addSession(avatar_name, IM_NOTHING_SPECIAL, avatar_uuid); @@ -508,6 +559,9 @@ namespace action_give_inventory uuid_set_t::const_iterator it = inventory_selected_uuids.begin(); const uuid_set_t::const_iterator it_end = inventory_selected_uuids.end(); + const std::string& separator = LLTrans::getString("words_separator"); + std::string noncopy_item_names; + LLSD noncopy_items = LLSD::emptyArray(); // iterate through selected inventory objects for (; it != it_end; ++it) { @@ -515,12 +569,82 @@ namespace action_give_inventory if (inv_cat) { LLGiveInventory::doGiveInventoryCategory(avatar_uuid, inv_cat, session_id); + shared = true; break; } LLViewerInventoryItem* inv_item = gInventory.getItem(*it); - LLGiveInventory::doGiveInventoryItem(avatar_uuid, inv_item, session_id); + if (!inv_item->getPermissions().allowCopyBy(gAgentID)) + { + if (!noncopy_item_names.empty()) + { + noncopy_item_names.append(separator); + } + noncopy_item_names.append(inv_item->getName()); + noncopy_items.append(*it); + } + else + { + LLGiveInventory::doGiveInventoryItem(avatar_uuid, inv_item, session_id); + shared = true; + } + } + if (noncopy_items.beginArray() != noncopy_items.endArray()) + { + LLSD substitutions; + substitutions["ITEMS"] = noncopy_item_names; + LLSD payload; + payload["agent_id"] = avatar_uuid; + payload["items"] = noncopy_items; + LLNotificationsUtil::add("CannotCopyWarning", substitutions, payload, + &LLGiveInventory::handleCopyProtectedItem); + break; } } + if (shared) + { + LLFloaterReg::hideInstance("avatar_picker"); + LLNotificationsUtil::add("ItemsShared"); + } + } + + /** + * Performs "give inventory" operations for provided avatars. + * + * Sends one requests to give all selected inventory items for each passed avatar. + * Avatars are represent by two vectors: names and UUIDs which must be sychronized with each other. + * + * @param avatar_names - avatar names request to be sent. + * @param avatar_uuids - avatar names request to be sent. + */ + static void give_inventory(const std::vector<std::string>& avatar_names, const uuid_vec_t& avatar_uuids) + { + llassert(avatar_names.size() == avatar_uuids.size()); + + + LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); + if (NULL == active_panel) + { + return; + } + + const uuid_set_t inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList(); + if (inventory_selected_uuids.empty()) + { + return; + } + + std::string residents; + build_residents_string(avatar_names, residents); + + std::string items; + build_items_string(inventory_selected_uuids, items); + + LLSD substitutions; + substitutions["RESIDENTS"] = residents; + substitutions["ITEMS"] = items; + LLShareInfo::instance().mAvatarNames = avatar_names; + LLShareInfo::instance().mAvatarUuids = avatar_uuids; + LLNotificationsUtil::add("ShareItemsConfirmation", substitutions, LLSD(), &give_inventory_cb); } } @@ -532,7 +656,6 @@ void LLAvatarActions::shareWithAvatars() LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(give_inventory, _1, _2), TRUE, FALSE); picker->setOkBtnEnableCb(boost::bind(is_give_inventory_acceptable)); - LLNotificationsUtil::add("ShareNotification"); } // static diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp index ff1e8a9657..7a3eddf7a6 100644 --- a/indra/newview/llbottomtray.cpp +++ b/indra/newview/llbottomtray.cpp @@ -1170,7 +1170,6 @@ void LLBottomTray::initResizeStateContainers() mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_MOVEMENT, getChild<LLPanel>("movement_panel"))); mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_CAMERA, getChild<LLPanel>("cam_panel"))); mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_SNAPSHOT, getChild<LLPanel>("snapshot_panel"))); - mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_SIDEBAR, getChild<LLPanel>("sidebar_btn_panel"))); mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_BUILD, getChild<LLPanel>("build_btn_panel"))); mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_SEARCH, getChild<LLPanel>("search_btn_panel"))); mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_WORLD_MAP, getChild<LLPanel>("world_map_btn_panel"))); @@ -1181,7 +1180,6 @@ void LLBottomTray::initResizeStateContainers() mButtonsProcessOrder.push_back(RS_BUTTON_MOVEMENT); mButtonsProcessOrder.push_back(RS_BUTTON_CAMERA); mButtonsProcessOrder.push_back(RS_BUTTON_SNAPSHOT); - mButtonsProcessOrder.push_back(RS_BUTTON_SIDEBAR); mButtonsProcessOrder.push_back(RS_BUTTON_BUILD); mButtonsProcessOrder.push_back(RS_BUTTON_SEARCH); mButtonsProcessOrder.push_back(RS_BUTTON_WORLD_MAP); @@ -1217,7 +1215,6 @@ void LLBottomTray::initButtonsVisibility() setVisibleAndFitWidths(RS_BUTTON_MOVEMENT, gSavedSettings.getBOOL("ShowMoveButton")); setVisibleAndFitWidths(RS_BUTTON_CAMERA, gSavedSettings.getBOOL("ShowCameraButton")); setVisibleAndFitWidths(RS_BUTTON_SNAPSHOT, gSavedSettings.getBOOL("ShowSnapshotButton")); - setVisibleAndFitWidths(RS_BUTTON_SIDEBAR, gSavedSettings.getBOOL("ShowSidebarButton")); setVisibleAndFitWidths(RS_BUTTON_BUILD, gSavedSettings.getBOOL("ShowBuildButton")); setVisibleAndFitWidths(RS_BUTTON_SEARCH, gSavedSettings.getBOOL("ShowSearchButton")); setVisibleAndFitWidths(RS_BUTTON_WORLD_MAP, gSavedSettings.getBOOL("ShowWorldMapButton")); @@ -1230,7 +1227,6 @@ void LLBottomTray::setButtonsControlsAndListeners() gSavedSettings.getControl("ShowMoveButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_MOVEMENT, _2)); gSavedSettings.getControl("ShowCameraButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_CAMERA, _2)); gSavedSettings.getControl("ShowSnapshotButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_SNAPSHOT, _2)); - gSavedSettings.getControl("ShowSidebarButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_SIDEBAR, _2)); gSavedSettings.getControl("ShowBuildButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_BUILD, _2)); gSavedSettings.getControl("ShowSearchButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_SEARCH, _2)); gSavedSettings.getControl("ShowWorldMapButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_WORLD_MAP, _2)); diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h index c0887df39a..05fed53936 100644 --- a/indra/newview/llbottomtray.h +++ b/indra/newview/llbottomtray.h @@ -124,7 +124,6 @@ private: , RS_BUTTON_SEARCH = 0x0400 , RS_BUTTON_WORLD_MAP = 0x0800 , RS_BUTTON_MINI_MAP = 0x1000 - , RS_BUTTON_SIDEBAR = 0x2000 /* Once new button that can be hidden on resize is added don't forget to update related places: @@ -139,7 +138,6 @@ private: */ , RS_BUTTONS_CAN_BE_HIDDEN = RS_BUTTON_SNAPSHOT | RS_BUTTON_CAMERA | RS_BUTTON_MOVEMENT | RS_BUTTON_GESTURES | RS_BUTTON_BUILD | RS_BUTTON_SEARCH | RS_BUTTON_WORLD_MAP | RS_BUTTON_MINI_MAP - | RS_BUTTON_SIDEBAR }EResizeState; /** diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp index ee366f4e3c..79ce2f8f6b 100644 --- a/indra/newview/llcofwearables.cpp +++ b/indra/newview/llcofwearables.cpp @@ -45,8 +45,7 @@ #include "llwearableitemslist.h" #include "llpaneloutfitedit.h" #include "llsidetray.h" - -static LLRegisterPanelClassWrapper<LLCOFAccordionListAdaptor> t_cof_accodion_list_adaptor("accordion_list_adaptor"); +#include "lltrans.h" static LLRegisterPanelClassWrapper<LLCOFWearables> t_cof_wearables("cof_wearables"); @@ -54,6 +53,39 @@ const LLSD REARRANGE = LLSD().with("rearrange", LLSD()); static const LLWearableItemNameComparator WEARABLE_NAME_COMPARATOR; +////////////////////////////////////////////////////////////////////////// + +class CofContextMenu : public LLListContextMenu +{ +protected: + static void updateCreateWearableLabel(LLMenuGL* menu, const LLUUID& item_id) + { + LLMenuItemGL* menu_item = menu->getChild<LLMenuItemGL>("create_new"); + + // Hide the "Create new <WEARABLE_TYPE>" if it's irrelevant. + LLViewerInventoryItem* item = gInventory.getLinkedItem(item_id); + if (!item || !item->isWearableType()) + { + menu_item->setVisible(FALSE); + return; + } + + // Set proper label for the "Create new <WEARABLE_TYPE>" menu item. + LLStringUtil::format_map_t args; + LLWearableType::EType w_type = item->getWearableType(); + args["[WEARABLE_TYPE]"] = LLWearableType::getTypeDefaultNewName(w_type); + std::string new_label = LLTrans::getString("CreateNewWearable", args); + menu_item->setLabel(new_label); + } + + static void createNew(const LLUUID& item_id) + { + LLViewerInventoryItem* item = gInventory.getLinkedItem(item_id); + if (!item || !item->isWearableType()) return; + + LLAgentWearables::createWearable(item->getWearableType(), true); + } +}; ////////////////////////////////////////////////////////////////////////// @@ -74,7 +106,7 @@ protected: ////////////////////////////////////////////////////////////////////////// -class CofClothingContextMenu : public LLListContextMenu +class CofClothingContextMenu : public CofContextMenu { protected: @@ -89,10 +121,17 @@ protected: registrar.add("Clothing.MoveUp", boost::bind(moveWearable, selected_id, false)); registrar.add("Clothing.MoveDown", boost::bind(moveWearable, selected_id, true)); registrar.add("Clothing.Edit", boost::bind(LLAgentWearables::editWearable, selected_id)); + registrar.add("Clothing.Create", boost::bind(createNew, selected_id)); enable_registrar.add("Clothing.OnEnable", boost::bind(&CofClothingContextMenu::onEnable, this, _2)); - return createFromFile("menu_cof_clothing.xml"); + LLContextMenu* menu = createFromFile("menu_cof_clothing.xml"); + llassert(menu); + if (menu) + { + updateCreateWearableLabel(menu, selected_id); + } + return menu; } bool onEnable(const LLSD& data) @@ -108,6 +147,10 @@ protected: { return gAgentWearables.canMoveWearable(selected_id, true); } + else if ("take_off" == param) + { + return get_is_item_worn(selected_id); + } else if ("edit" == param) { return gAgentWearables.isWearableModifiable(selected_id); @@ -122,12 +165,11 @@ protected: LLViewerInventoryItem* item = gInventory.getItem(item_id); return LLAppearanceMgr::instance().moveWearable(item, closer_to_body); } - }; ////////////////////////////////////////////////////////////////////////// -class CofBodyPartContextMenu : public LLListContextMenu +class CofBodyPartContextMenu : public CofContextMenu { protected: @@ -142,10 +184,17 @@ protected: LLPanelOutfitEdit* panel_oe = dynamic_cast<LLPanelOutfitEdit*>(LLSideTray::getInstance()->getPanel("panel_outfit_edit")); registrar.add("BodyPart.Replace", boost::bind(&LLPanelOutfitEdit::onReplaceBodyPartMenuItemClicked, panel_oe, selected_id)); registrar.add("BodyPart.Edit", boost::bind(LLAgentWearables::editWearable, selected_id)); + registrar.add("BodyPart.Create", boost::bind(createNew, selected_id)); enable_registrar.add("BodyPart.OnEnable", boost::bind(&CofBodyPartContextMenu::onEnable, this, _2)); - return createFromFile("menu_cof_body_part.xml"); + LLContextMenu* menu = createFromFile("menu_cof_body_part.xml"); + llassert(menu); + if (menu) + { + updateCreateWearableLabel(menu, selected_id); + } + return menu; } bool onEnable(const LLSD& data) diff --git a/indra/newview/llcofwearables.h b/indra/newview/llcofwearables.h index 8f8bda2be8..f99f2662e6 100644 --- a/indra/newview/llcofwearables.h +++ b/indra/newview/llcofwearables.h @@ -45,53 +45,6 @@ class LLPanelClothingListItem; class LLPanelBodyPartsListItem; class LLPanelDeletableWearableListItem; -/** - * Adaptor between LLAccordionCtrlTab and LLFlatListView to facilitate communication between them - * (notify, notifyParent) regarding size changes of a list and selection changes across accordion tabs. - * Besides that it acts as a container for the LLFlatListView and a button bar on top of it. - */ -class LLCOFAccordionListAdaptor : public LLPanel -{ -public: - LLCOFAccordionListAdaptor() : LLPanel() {}; - ~LLCOFAccordionListAdaptor() {}; - - S32 notifyParent(const LLSD& info) - { - LLView* parent = getParent(); - if (!parent) return -1; - - if (!(info.has("action") && "size_changes" == info["action"].asString())) - { - return parent->notifyParent(info); - } - - LLRect rc; - childGetRect("button_bar", rc); - - LLSD params; - params["action"] = "size_changes"; - params["width"] = info["width"]; - params["height"] = info["height"].asInteger() + rc.getHeight(); - - return parent->notifyParent(params); - } - - - S32 notify(const LLSD& info) - { - for (child_list_const_iter_t iter = beginChild(); iter != endChild(); iter++) - { - if (dynamic_cast<LLFlatListView*>(*iter)) - { - return (*iter)->notify(info); - } - } - return LLPanel::notify(info); - }; -}; - - class LLCOFWearables : public LLPanel { public: diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index b40c19c2c6..96364f9418 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -437,7 +437,7 @@ BOOL LLFloaterAvatarPicker::handleDragAndDrop(S32 x, S32 y, MASK mask, session_id = gIMMgr->addSession(avatar_name, IM_NOTHING_SPECIAL, dest_agent_id); } return LLToolDragAndDrop::handleGiveDragAndDrop(dest_agent_id, session_id, drop, - cargo_type, cargo_data, accept); + cargo_type, cargo_data, accept, getName()); } } } diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index abdb55ec17..7c5586ec96 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -572,7 +572,7 @@ void LLPanelLandGeneral::refresh() if (regionp) { insert_maturity_into_textbox(mContentRating, gFloaterView->getParentFloater(this), MATURITY); - mLandType->setText(regionp->getSimProductName()); + mLandType->setText(LLTrans::getString(regionp->getSimProductName())); } // estate owner/manager cannot edit other parts of the parcel diff --git a/indra/newview/llfloatermap.cpp b/indra/newview/llfloatermap.cpp index 725fc17136..c259659083 100644 --- a/indra/newview/llfloatermap.cpp +++ b/indra/newview/llfloatermap.cpp @@ -106,6 +106,8 @@ BOOL LLFloaterMap::postBuild() mPopupMenu->setItemEnabled ("Stop Tracking", false); } + stretchMiniMap(getRect().getWidth(),getRect().getHeight()); + updateMinorDirections(); // Get the drag handle all the way in back @@ -229,10 +231,8 @@ void LLFloaterMap::onFocusLost() LLPanel::onFocusLost(); } -void LLFloaterMap::reshape(S32 width, S32 height, BOOL called_from_parent) +void LLFloaterMap::stretchMiniMap(S32 width,S32 height) { - LLFloater::reshape(width, height, called_from_parent); - //fix for ext-7112 //by default ctrl can't overlap caption area if(mMap) @@ -242,6 +242,13 @@ void LLFloaterMap::reshape(S32 width, S32 height, BOOL called_from_parent) mMap->reshape( width, height, 1); mMap->setRect(map_rect); } +} + +void LLFloaterMap::reshape(S32 width, S32 height, BOOL called_from_parent) +{ + LLFloater::reshape(width, height, called_from_parent); + + stretchMiniMap(width, height); updateMinorDirections(); } diff --git a/indra/newview/llfloatermap.h b/indra/newview/llfloatermap.h index 9ff2f03180..3c063adfb8 100644 --- a/indra/newview/llfloatermap.h +++ b/indra/newview/llfloatermap.h @@ -61,6 +61,8 @@ private: void handleStopTracking (const LLSD& userdata); void setDirectionPos( LLTextBox* text_box, F32 rotation ); void updateMinorDirections(); + + void stretchMiniMap(S32 width,S32 height); LLMenuGL* mPopupMenu; diff --git a/indra/newview/llgiveinventory.cpp b/indra/newview/llgiveinventory.cpp index d83d895dd0..aebf1b4c26 100644 --- a/indra/newview/llgiveinventory.cpp +++ b/indra/newview/llgiveinventory.cpp @@ -192,15 +192,16 @@ bool LLGiveInventory::isInventoryGroupGiveAcceptable(const LLInventoryItem* item } // static -void LLGiveInventory::doGiveInventoryItem(const LLUUID& to_agent, +bool LLGiveInventory::doGiveInventoryItem(const LLUUID& to_agent, const LLInventoryItem* item, const LLUUID& im_session_id/* = LLUUID::null*/) { + bool res = true; llinfos << "LLGiveInventory::giveInventory()" << llendl; if (!isInventoryGiveAcceptable(item)) { - return; + return false; } if (item->getPermissions().allowCopyBy(gAgentID)) { @@ -210,12 +211,19 @@ void LLGiveInventory::doGiveInventoryItem(const LLUUID& to_agent, else { // ask if the agent is sure. + LLSD substitutions; + substitutions["ITEMS"] = item->getName(); LLSD payload; payload["agent_id"] = to_agent; - payload["item_id"] = item->getUUID(); - LLNotificationsUtil::add("CannotCopyWarning", LLSD(), payload, + LLSD items = LLSD::emptyArray(); + items.append(item->getUUID()); + payload["items"] = items; + LLNotificationsUtil::add("CannotCopyWarning", substitutions, payload, &LLGiveInventory::handleCopyProtectedItem); + res = false; } + + return res; } void LLGiveInventory::doGiveInventoryCategory(const LLUUID& to_agent, @@ -318,23 +326,27 @@ void LLGiveInventory::logInventoryOffer(const LLUUID& to_agent, const LLUUID &im bool LLGiveInventory::handleCopyProtectedItem(const LLSD& notification, const LLSD& response) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + LLSD itmes = notification["payload"]["items"]; LLInventoryItem* item = NULL; switch(option) { case 0: // "Yes" - item = gInventory.getItem(notification["payload"]["item_id"].asUUID()); - if (item) + for (LLSD::array_iterator it = itmes.beginArray(); it != itmes.endArray(); it++) { - LLGiveInventory::commitGiveInventoryItem(notification["payload"]["agent_id"].asUUID(), - item); - // delete it for now - it will be deleted on the server - // quickly enough. - gInventory.deleteObject(notification["payload"]["item_id"].asUUID()); - gInventory.notifyObservers(); - } - else - { - LLNotificationsUtil::add("CannotGiveItem"); + item = gInventory.getItem((*it).asUUID()); + if (item) + { + LLGiveInventory::commitGiveInventoryItem(notification["payload"]["agent_id"].asUUID(), + item); + // delete it for now - it will be deleted on the server + // quickly enough. + gInventory.deleteObject(item->getUUID()); + gInventory.notifyObservers(); + } + else + { + LLNotificationsUtil::add("CannotGiveItem"); + } } break; diff --git a/indra/newview/llgiveinventory.h b/indra/newview/llgiveinventory.h index e589a0cc69..86f0f2fe86 100644 --- a/indra/newview/llgiveinventory.h +++ b/indra/newview/llgiveinventory.h @@ -61,7 +61,7 @@ public: /** * Gives passed inventory item to specified avatar in specified session. */ - static void doGiveInventoryItem(const LLUUID& to_agent, + static bool doGiveInventoryItem(const LLUUID& to_agent, const LLInventoryItem* item, const LLUUID& im_session_id = LLUUID::null); @@ -72,6 +72,9 @@ public: const LLInventoryCategory* item, const LLUUID &session_id = LLUUID::null); + // give inventory item functionality + static bool handleCopyProtectedItem(const LLSD& notification, const LLSD& response); + private: // this class is not intended to be instantiated. LLGiveInventory(); @@ -82,8 +85,6 @@ private: static void logInventoryOffer(const LLUUID& to_agent, const LLUUID &im_session_id = LLUUID::null); - // give inventory item functionality - static bool handleCopyProtectedItem(const LLSD& notification, const LLSD& response); static void commitGiveInventoryItem(const LLUUID& to_agent, const LLInventoryItem* item, const LLUUID &im_session_id = LLUUID::null); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 577652fc79..b7495f7dbe 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -164,38 +164,7 @@ time_t LLInvFVBridge::getCreationDate() const // Can be destroyed (or moved to trash) BOOL LLInvFVBridge::isItemRemovable() const { - const LLInventoryModel* model = getInventoryModel(); - if(!model) - { - return FALSE; - } - - // Can't delete an item that's in the library. - if(!model->isObjectDescendentOf(mUUID, gInventory.getRootFolderID())) - { - return FALSE; - } - - // Disable delete from COF folder; have users explicitly choose "detach/take off", - // unless the item is not worn but in the COF (i.e. is bugged). - if (LLAppearanceMgr::instance().getIsProtectedCOFItem(mUUID)) - { - if (get_is_item_worn(mUUID)) - { - return FALSE; - } - } - - const LLInventoryObject *obj = model->getItem(mUUID); - if (obj && obj->getIsLinkType()) - { - return TRUE; - } - if (get_is_item_worn(mUUID)) - { - return FALSE; - } - return TRUE; + return get_is_item_removable(getInventoryModel(), mUUID); } // Can be moved to another folder @@ -833,24 +802,7 @@ void LLInvFVBridge::changeCategoryParent(LLInventoryModel* model, const LLUUID& new_parent_id, BOOL restamp) { - // Can't move a folder into a child of itself. - if (model->isObjectDescendentOf(new_parent_id, cat->getUUID())) - { - return; - } - - LLInventoryModel::update_list_t update; - LLInventoryModel::LLCategoryUpdate old_folder(cat->getParentUUID(), -1); - update.push_back(old_folder); - LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1); - update.push_back(new_folder); - model->accountForUpdate(update); - - LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(cat); - new_cat->setParent(new_parent_id); - new_cat->updateParentOnServer(restamp); - model->updateCategory(new_cat); - model->notifyObservers(); + change_category_parent(model, cat, new_parent_id, restamp); } LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type, @@ -1538,26 +1490,7 @@ public: // Can be destroyed (or moved to trash) BOOL LLFolderBridge::isItemRemovable() const { - LLInventoryModel* model = getInventoryModel(); - if(!model) - { - return FALSE; - } - - if(!model->isObjectDescendentOf(mUUID, gInventory.getRootFolderID())) - { - return FALSE; - } - - if (!isAgentAvatarValid()) return FALSE; - - LLInventoryCategory* category = model->getCategory(mUUID); - if(!category) - { - return FALSE; - } - - if(LLFolderType::lookupIsProtectedType(category->getPreferredType())) + if (!get_is_category_removable(getInventoryModel(), mUUID)) { return FALSE; } @@ -1573,6 +1506,7 @@ BOOL LLFolderBridge::isItemRemovable() const return FALSE; } } + return TRUE; } @@ -2333,10 +2267,20 @@ LLUIImagePtr LLFolderBridge::getIcon(LLFolderType::EType preferred_type, BOOL is else return LLUI::getUIImage("Inv_FolderClosed_Link"); } - if (preferred_type == LLFolderType::FT_OUTFIT) + + switch (preferred_type) + { + case LLFolderType::FT_OUTFIT: return LLUI::getUIImage("Inv_LookFolderClosed"); - else + case LLFolderType::FT_LOST_AND_FOUND: + return LLUI::getUIImage("Inv_LostClosed"); + case LLFolderType::FT_TRASH: + return LLUI::getUIImage("Inv_TrashClosed"); + case LLFolderType::FT_NONE: return LLUI::getUIImage("Inv_FolderClosed"); + default: + return LLUI::getUIImage("Inv_SysClosed"); + } } LLUIImagePtr LLFolderBridge::getOpenIcon() const @@ -2350,29 +2294,27 @@ LLUIImagePtr LLFolderBridge::getOpenIcon() const else return LLUI::getUIImage("Inv_FolderOpen_Link"); } - if (getPreferredType() == LLFolderType::FT_OUTFIT) + + switch (getPreferredType()) + { + case LLFolderType::FT_OUTFIT: return LLUI::getUIImage("Inv_LookFolderOpen"); - else + case LLFolderType::FT_LOST_AND_FOUND: + return LLUI::getUIImage("Inv_LostOpen"); + case LLFolderType::FT_TRASH: + return LLUI::getUIImage("Inv_TrashOpen"); + case LLFolderType::FT_NONE: return LLUI::getUIImage("Inv_FolderOpen"); + default: + return LLUI::getUIImage("Inv_SysOpen"); + } + } BOOL LLFolderBridge::renameItem(const std::string& new_name) { - if(!isItemRenameable()) - return FALSE; - LLInventoryModel* model = getInventoryModel(); - if(!model) - return FALSE; - LLViewerInventoryCategory* cat = getCategory(); - if(cat && (cat->getName() != new_name)) - { - LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(cat); - new_cat->rename(new_name); - new_cat->updateServer(FALSE); - model->updateCategory(new_cat); + rename_category(getInventoryModel(), mUUID, new_name); - model->notifyObservers(); - } // return FALSE because we either notified observers (& therefore // rebuilt) or we didn't update. return FALSE; @@ -2426,36 +2368,7 @@ bool LLFolderBridge::removeItemResponse(const LLSD& notification, const LLSD& re { // move it to the trash LLPreview::hide(mUUID); - LLInventoryModel* model = getInventoryModel(); - if(!model) return FALSE; - - const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH); - - // Look for any gestures and deactivate them - LLInventoryModel::cat_array_t descendent_categories; - LLInventoryModel::item_array_t descendent_items; - gInventory.collectDescendents( mUUID, descendent_categories, descendent_items, FALSE ); - - for (LLInventoryModel::item_array_t::const_iterator iter = descendent_items.begin(); - iter != descendent_items.end(); - ++iter) - { - const LLViewerInventoryItem* item = (*iter); - const LLUUID& item_id = item->getUUID(); - if (item->getType() == LLAssetType::AT_GESTURE - && LLGestureMgr::instance().isGestureActive(item_id)) - { - LLGestureMgr::instance().deactivateGesture(item_id); - } - } - - // go ahead and do the normal remove if no 'last calling - // cards' are being removed. - LLViewerInventoryCategory* cat = getCategory(); - if(cat) - { - LLInvFVBridge::changeCategoryParent(model, cat, trash_id, TRUE); - } + remove_category(getInventoryModel(), mUUID); return TRUE; } return FALSE; @@ -2651,22 +2564,6 @@ BOOL LLFolderBridge::checkFolderForContentsOfType(LLInventoryModel* model, LLInv return ((item_array.count() > 0) ? TRUE : FALSE ); } -class LLFindWorn : public LLInventoryCollectFunctor -{ -public: - LLFindWorn() {} - virtual ~LLFindWorn() {} - virtual bool operator()(LLInventoryCategory* cat, - LLInventoryItem* item) - { - if (item && get_is_item_worn(item->getUUID())) - { - return TRUE; - } - return FALSE; - } -}; - BOOL LLFolderBridge::areAnyContentsWorn(LLInventoryModel* model) const { LLInventoryModel::cat_array_t cat_array; @@ -2985,22 +2882,7 @@ void LLFolderBridge::createWearable(LLFolderBridge* bridge, LLWearableType::ETyp { if(!bridge) return; LLUUID parent_id = bridge->getUUID(); - createWearable(parent_id, type); -} - -// Separate function so can be called by global menu as well as right-click -// menu. -// static -void LLFolderBridge::createWearable(const LLUUID &parent_id, LLWearableType::EType type) -{ - LLWearable* wearable = LLWearableList::instance().createNewWearable(type); - LLAssetType::EType asset_type = wearable->getAssetType(); - LLInventoryType::EType inv_type = LLInventoryType::IT_WEARABLE; - create_inventory_item(gAgent.getID(), gAgent.getSessionID(), - parent_id, wearable->getTransactionID(), wearable->getName(), - wearable->getDescription(), asset_type, inv_type, wearable->getType(), - wearable->getPermissions().getMaskNextOwner(), - LLPointer<LLInventoryCallback>(NULL)); + LLAgentWearables::createWearable(type, false, parent_id); } void LLFolderBridge::modifyOutfit(BOOL append) @@ -4877,13 +4759,7 @@ void LLWearableBridge::onEditOnAvatar(void* user_data) void LLWearableBridge::editOnAvatar() { - LLWearable* wearable = gAgentWearables.getWearableFromItemID(mUUID); - if( wearable ) - { - LLPanel * panel = LLSideTray::getInstance()->getPanel("sidepanel_appearance"); - - LLSidepanelAppearance::editWearable(wearable, panel); - } + LLAgentWearables::editWearable(mUUID); } // static diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index c5efefac7e..59c1f3d6fb 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -270,7 +270,6 @@ public: virtual BOOL copyToClipboard() const; static void createWearable(LLFolderBridge* bridge, LLWearableType::EType type); - static void createWearable(const LLUUID &parent_folder_id, LLWearableType::EType type); LLViewerInventoryCategory* getCategory() const; diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 0cc4b0e389..817da34c61 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -130,6 +130,90 @@ void change_item_parent(LLInventoryModel* model, } } +void change_category_parent(LLInventoryModel* model, + LLViewerInventoryCategory* cat, + const LLUUID& new_parent_id, + BOOL restamp) +{ + if (!model || !cat) + { + return; + } + + // Can't move a folder into a child of itself. + if (model->isObjectDescendentOf(new_parent_id, cat->getUUID())) + { + return; + } + + LLInventoryModel::update_list_t update; + LLInventoryModel::LLCategoryUpdate old_folder(cat->getParentUUID(), -1); + update.push_back(old_folder); + LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1); + update.push_back(new_folder); + model->accountForUpdate(update); + + LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(cat); + new_cat->setParent(new_parent_id); + new_cat->updateParentOnServer(restamp); + model->updateCategory(new_cat); + model->notifyObservers(); +} + +void remove_category(LLInventoryModel* model, const LLUUID& cat_id) +{ + if (!model || !get_is_category_removable(model, cat_id)) + { + return; + } + + // Look for any gestures and deactivate them + LLInventoryModel::cat_array_t descendent_categories; + LLInventoryModel::item_array_t descendent_items; + gInventory.collectDescendents(cat_id, descendent_categories, descendent_items, FALSE); + + for (LLInventoryModel::item_array_t::const_iterator iter = descendent_items.begin(); + iter != descendent_items.end(); + ++iter) + { + const LLViewerInventoryItem* item = (*iter); + const LLUUID& item_id = item->getUUID(); + if (item->getType() == LLAssetType::AT_GESTURE + && LLGestureMgr::instance().isGestureActive(item_id)) + { + LLGestureMgr::instance().deactivateGesture(item_id); + } + } + + // go ahead and do the normal remove if no 'last calling + // cards' are being removed. + LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id); + if (cat) + { + const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH); + change_category_parent(model, cat, trash_id, TRUE); + } +} + +void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::string& new_name) +{ + LLViewerInventoryCategory* cat; + + if (!model || + !get_is_category_renameable(model, cat_id) || + (cat = model->getCategory(cat_id)) == NULL || + cat->getName() == new_name) + { + return; + } + + LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(cat); + new_cat->rename(new_name); + new_cat->updateServer(FALSE); + model->updateCategory(new_cat); + + model->notifyObservers(); +} BOOL get_is_item_worn(const LLUUID& id) { @@ -160,6 +244,83 @@ BOOL get_is_item_worn(const LLUUID& id) return FALSE; } +BOOL get_is_item_removable(const LLInventoryModel* model, const LLUUID& id) +{ + if (!model) + { + return FALSE; + } + + // Can't delete an item that's in the library. + if (!model->isObjectDescendentOf(id, gInventory.getRootFolderID())) + { + return FALSE; + } + + // Disable delete from COF folder; have users explicitly choose "detach/take off", + // unless the item is not worn but in the COF (i.e. is bugged). + if (LLAppearanceMgr::instance().getIsProtectedCOFItem(id)) + { + if (get_is_item_worn(id)) + { + return FALSE; + } + } + + const LLInventoryObject *obj = model->getItem(id); + if (obj && obj->getIsLinkType()) + { + return TRUE; + } + if (get_is_item_worn(id)) + { + return FALSE; + } + return TRUE; +} + +BOOL get_is_category_removable(const LLInventoryModel* model, const LLUUID& id) +{ + // This function doesn't check the folder's children. + + if (!model) + { + return FALSE; + } + + if (!model->isObjectDescendentOf(id, gInventory.getRootFolderID())) + { + return FALSE; + } + + if (!isAgentAvatarValid()) return FALSE; + + LLInventoryCategory* category = model->getCategory(id); + if (!category) + { + return FALSE; + } + + if (LLFolderType::lookupIsProtectedType(category->getPreferredType())) + { + return FALSE; + } + + return TRUE; +} + +BOOL get_is_category_renameable(const LLInventoryModel* model, const LLUUID& id) +{ + LLViewerInventoryCategory* cat = model->getCategory(id); + + if (cat && !LLFolderType::lookupIsProtectedType(cat->getPreferredType()) && + cat->getOwnerID() == gAgent.getID()) + { + return TRUE; + } + return FALSE; +} + void show_item_profile(const LLUUID& item_uuid) { LLUUID linked_uuid = gInventory.getLinkedItemID(item_uuid); @@ -376,6 +537,26 @@ void LLFindWearablesOfType::setType(LLWearableType::EType type) mWearableType = type; } +bool LLFindWorn::operator()(LLInventoryCategory* cat, LLInventoryItem* item) +{ + return item && get_is_item_worn(item->getUUID()); +} + +bool LLFindNonRemovableObjects::operator()(LLInventoryCategory* cat, LLInventoryItem* item) +{ + if (item) + { + return !get_is_item_removable(&gInventory, item->getUUID()); + } + if (cat) + { + return !get_is_category_removable(&gInventory, cat->getUUID()); + } + + llwarns << "Not a category and not an item?" << llendl; + return false; +} + ///---------------------------------------------------------------------------- /// LLAssetIDMatches ///---------------------------------------------------------------------------- diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index bb365573d7..33b52cfd5e 100644 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -46,6 +46,12 @@ // Is this item or its baseitem is worn, attached, etc... BOOL get_is_item_worn(const LLUUID& id); +BOOL get_is_item_removable(const LLInventoryModel* model, const LLUUID& id); + +BOOL get_is_category_removable(const LLInventoryModel* model, const LLUUID& id); + +BOOL get_is_category_renameable(const LLInventoryModel* model, const LLUUID& id); + void show_item_profile(const LLUUID& item_uuid); void show_item_original(const LLUUID& item_uuid); @@ -55,6 +61,15 @@ void change_item_parent(LLInventoryModel* model, const LLUUID& new_parent_id, BOOL restamp); +void change_category_parent(LLInventoryModel* model, + LLViewerInventoryCategory* cat, + const LLUUID& new_parent_id, + BOOL restamp); + +void remove_category(LLInventoryModel* model, const LLUUID& cat_id); + +void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::string& new_name); + // Generates a string containing the path to the item specified by item_id. void append_path(const LLUUID& id, std::string& path); @@ -309,6 +324,22 @@ private: LLWearableType::EType mWearableType; }; +// Find worn items. +class LLFindWorn : public LLInventoryCollectFunctor +{ +public: + LLFindWorn() {} + virtual ~LLFindWorn() {} + virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item); +}; + +// Collect non-removable folders and items. +class LLFindNonRemovableObjects : public LLInventoryCollectFunctor +{ +public: + virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item); +}; + /** Inventory Collector Functions ** ** *******************************************************************************/ diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 4766c1c227..bb3f34dde2 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -49,6 +49,7 @@ #include "llsidepanelinventory.h" #include "llsidetray.h" #include "llscrollcontainer.h" +#include "llviewerattachmenu.h" #include "llviewerfoldertype.h" #include "llvoavatarself.h" @@ -877,48 +878,19 @@ bool LLInventoryPanel::beginIMSession() bool LLInventoryPanel::attachObject(const LLSD& userdata) { + // Copy selected item UUIDs to a vector. std::set<LLUUID> selected_items = mFolderRoot->getSelectionList(); - - std::string joint_name = userdata.asString(); - LLViewerJointAttachment* attachmentp = NULL; - for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); - iter != gAgentAvatarp->mAttachmentPoints.end(); ) - { - LLVOAvatar::attachment_map_t::iterator curiter = iter++; - LLViewerJointAttachment* attachment = curiter->second; - if (attachment->getName() == joint_name) - { - attachmentp = attachment; - break; - } - } - if (attachmentp == NULL) - { - return true; - } - + uuid_vec_t items; for (std::set<LLUUID>::const_iterator set_iter = selected_items.begin(); set_iter != selected_items.end(); ++set_iter) { - const LLUUID &id = *set_iter; - LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(id); - if(item && gInventory.isObjectDescendentOf(id, gInventory.getRootFolderID())) - { - rez_attachment(item, attachmentp); - } - else if(item && item->isFinished()) - { - // must be in library. copy it to our inventory and put it on. - LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(attachmentp); - copy_inventory_item(gAgent.getID(), - item->getPermissions().getOwner(), - item->getUUID(), - LLUUID::null, - std::string(), - cb); - } + items.push_back(*set_iter); } + + // Attach selected items. + LLViewerAttachMenu::attachObjects(items, userdata.asString()); + gFocusMgr.setKeyboardFocus(NULL); return true; diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp index 251c60b5bf..e5548007bd 100644 --- a/indra/newview/llnavigationbar.cpp +++ b/indra/newview/llnavigationbar.cpp @@ -713,6 +713,7 @@ void LLNavigationBar::onNavigationButtonHeldUp(LLButton* nav_button) void LLNavigationBar::handleLoginComplete() { + LLTeleportHistory::getInstance()->handleLoginComplete(); mCmbLocation->handleLoginComplete(); } diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 8f189a1e9f..94bf2f4c7a 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -43,12 +43,16 @@ #include "llinventoryfunctions.h" #include "llinventorymodel.h" #include "lllistcontextmenu.h" +#include "llnotificationsutil.h" +#include "llsidetray.h" #include "lltransutil.h" #include "llviewermenu.h" #include "llvoavatar.h" #include "llvoavatarself.h" #include "llwearableitemslist.h" +static bool is_tab_header_clicked(LLAccordionCtrlTab* tab, S32 y); + ////////////////////////////////////////////////////////////////////////// class OutfitContextMenu : public LLListContextMenu @@ -66,12 +70,63 @@ protected: boost::bind(&LLAppearanceMgr::addCategoryToCurrentOutfit, &LLAppearanceMgr::instance(), selected_id)); registrar.add("Outfit.TakeOff", boost::bind(&LLAppearanceMgr::takeOffOutfit, &LLAppearanceMgr::instance(), selected_id)); - // *TODO: implement this - // registrar.add("Outfit.Rename", boost::bind()); - // registrar.add("Outfit.Delete", boost::bind()); + registrar.add("Outfit.Edit", boost::bind(editOutfit)); + registrar.add("Outfit.Rename", boost::bind(renameOutfit, selected_id)); + registrar.add("Outfit.Delete", boost::bind(deleteOutfit, selected_id)); + + enable_registrar.add("Outfit.OnEnable", boost::bind(&OutfitContextMenu::onEnable, this, _2)); return createFromFile("menu_outfit_tab.xml"); } + + bool onEnable(const LLSD& data) + { + std::string param = data.asString(); + LLUUID outfit_cat_id = mUUIDs.back(); + bool is_worn = LLAppearanceMgr::instance().getBaseOutfitUUID() == outfit_cat_id; + + if ("wear_replace" == param) + { + return !is_worn; + } + else if ("wear_add" == param) + { + return !is_worn; + } + else if ("take_off" == param) + { + return is_worn; + } + else if ("edit" == param) + { + return is_worn; + } + else if ("rename" == param) + { + return get_is_category_renameable(&gInventory, outfit_cat_id); + } + else if ("delete" == param) + { + return LLAppearanceMgr::instance().getCanRemoveOutfit(outfit_cat_id); + } + + return true; + } + + static void editOutfit() + { + LLSideTray::getInstance()->showPanel("sidepanel_appearance", LLSD().with("type", "edit_outfit")); + } + + static void renameOutfit(const LLUUID& outfit_cat_id) + { + LLAppearanceMgr::instance().renameOutfit(outfit_cat_id); + } + + static void deleteOutfit(const LLUUID& outfit_cat_id) + { + remove_category(&gInventory, outfit_cat_id); + } }; ////////////////////////////////////////////////////////////////////////// @@ -176,8 +231,6 @@ void LLOutfitsList::refreshList(const LLUUID& category_id) static LLXMLNodePtr accordionXmlNode = getAccordionTabXMLNode(); LLAccordionCtrlTab* tab = LLUICtrlFactory::defaultBuilder<LLAccordionCtrlTab>(accordionXmlNode, NULL, NULL); - tab->setRightMouseDownCallback(boost::bind(&LLOutfitsList::onAccordionTabRightClick, this, - _1, _2, _3, cat_id)); tab->setName(name); tab->setTitle(name); @@ -198,6 +251,12 @@ void LLOutfitsList::refreshList(const LLUUID& category_id) // Map the new tab with outfit category UUID. mOutfitsMap.insert(LLOutfitsList::outfits_map_value_t(cat_id, tab)); + tab->setRightMouseDownCallback(boost::bind(&LLOutfitsList::onAccordionTabRightClick, this, + _1, _2, _3, cat_id)); + + tab->setDoubleClickCallback(boost::bind(&LLOutfitsList::onAccordionTabDoubleClick, this, + _1, _2, _3, cat_id)); + // Setting tab focus callback to monitor currently selected outfit. tab->setFocusReceivedCallback(boost::bind(&LLOutfitsList::changeOutfitSelection, this, list, cat_id)); @@ -301,6 +360,10 @@ void LLOutfitsList::performAction(std::string action) { LLAppearanceMgr::instance().wearInventoryCategory( cat, FALSE, TRUE ); } + else if ("rename_outfit" == action) + { + LLAppearanceMgr::instance().renameOutfit(mSelectedOutfitUUID); + } } void LLOutfitsList::setFilterSubString(const std::string& string) @@ -426,6 +489,10 @@ void LLOutfitsList::onFilteredWearableItemsListRefresh(LLUICtrl* ctrl) // hide tab if its title doesn't pass filter // and it has no visible items tab->setVisible(list->size() != 0); + + // remove title highlighting because it might + // have been previously highlighted by less restrictive filter + tab->setTitle(tab->getTitle()); } else { @@ -478,6 +545,10 @@ void LLOutfitsList::applyFilter(const std::string& new_filter_substring) // hide tab if its title doesn't pass filter // and it has no visible items tab->setVisible(list->size() != 0); + + // remove title highlighting because it might + // have been previously highlighted by less restrictive filter + tab->setTitle(tab->getTitle()); } else { @@ -510,22 +581,30 @@ void LLOutfitsList::applyFilter(const std::string& new_filter_substring) void LLOutfitsList::onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id) { LLAccordionCtrlTab* tab = dynamic_cast<LLAccordionCtrlTab*>(ctrl); - if(mOutfitMenu && tab && tab->getHeaderVisible() && cat_id.notNull()) + if(mOutfitMenu && is_tab_header_clicked(tab, y) && cat_id.notNull()) { - S32 header_bottom = tab->getLocalRect().getHeight() - tab->getHeaderHeight(); - if(y >= header_bottom) + // Focus tab header to trigger tab selection change. + LLUICtrl* header = tab->findChild<LLUICtrl>("dd_header"); + if (header) { - // Focus tab header to trigger tab selection change. - LLUICtrl* header = tab->findChild<LLUICtrl>("dd_header"); - if (header) - { - header->setFocus(TRUE); - } - - uuid_vec_t selected_uuids; - selected_uuids.push_back(cat_id); - mOutfitMenu->show(ctrl, selected_uuids, x, y); + header->setFocus(TRUE); } + + uuid_vec_t selected_uuids; + selected_uuids.push_back(cat_id); + mOutfitMenu->show(ctrl, selected_uuids, x, y); + } +} + +void LLOutfitsList::onAccordionTabDoubleClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id) +{ + LLAccordionCtrlTab* tab = dynamic_cast<LLAccordionCtrlTab*>(ctrl); + if(is_tab_header_clicked(tab, y) && cat_id.notNull()) + { + LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id); + if (!cat) return; + + LLAppearanceMgr::instance().wearInventoryCategory( cat, FALSE, FALSE ); } } @@ -551,4 +630,13 @@ void LLOutfitsList::onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y) LLWearableItemsList::ContextMenu::instance().show(list, selected_uuids, x, y); } + +bool is_tab_header_clicked(LLAccordionCtrlTab* tab, S32 y) +{ + if(!tab || !tab->getHeaderVisible()) return false; + + S32 header_bottom = tab->getLocalRect().getHeight() - tab->getHeaderHeight(); + return y >= header_bottom; +} + // EOF diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h index 1da7360c2e..4784ee777b 100644 --- a/indra/newview/lloutfitslist.h +++ b/indra/newview/lloutfitslist.h @@ -66,12 +66,12 @@ public: void refreshList(const LLUUID& category_id); - void onSelectionChange(LLUICtrl* ctrl); - void performAction(std::string action); void setFilterSubString(const std::string& string); + const LLUUID& getSelectedOutfitUUID() const { return mSelectedOutfitUUID; } + private: /** * Reads xml with accordion tab and Flat list from xml file. @@ -107,9 +107,13 @@ private: void applyFilter(const std::string& new_filter_substring); void onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id); - + void onAccordionTabDoubleClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id); void onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y); + void onSelectionChange(LLUICtrl* ctrl); + + static void onOutfitRename(const LLSD& notification, const LLSD& response); + LLInventoryCategoriesObserver* mCategoriesObserver; LLAccordionCtrl* mAccordion; diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index 4bf4f9eac1..7fb46fc84f 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -221,8 +221,6 @@ BOOL LLLandmarksPanel::postBuild() // mast be called before any other initXXX methods to init Gear menu initListCommandsHandlers(); - U32 sort_order = gSavedSettings.getU32(LLInventoryPanel::DEFAULT_SORT_ORDER); - mSortByDate = sort_order & LLInventoryFilter::SO_DATE; initFavoritesInventoryPanel(); initLandmarksInventoryPanel(); initMyInventoryPanel(); @@ -607,7 +605,8 @@ void LLLandmarksPanel::initLandmarksPanel(LLPlacesInventoryPanel* inventory_list inventory_list->setSelectCallback(boost::bind(&LLLandmarksPanel::onSelectionChange, this, inventory_list, _1, _2)); inventory_list->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); - updateSortOrder(inventory_list, mSortByDate); + bool sorting_order = gSavedSettings.getBOOL("LandmarksSortedByDate"); + updateSortOrder(inventory_list, sorting_order); LLPlacesFolderView* root_folder = dynamic_cast<LLPlacesFolderView*>(inventory_list->getRootFolder()); if (root_folder) @@ -875,10 +874,12 @@ void LLLandmarksPanel::onFoldingAction(const LLSD& userdata) } else if ("sort_by_date" == command_name) { - mSortByDate = !mSortByDate; - updateSortOrder(mLandmarksInventoryPanel, mSortByDate); - updateSortOrder(mMyInventoryPanel, mSortByDate); - updateSortOrder(mLibraryInventoryPanel, mSortByDate); + bool sorting_order = gSavedSettings.getBOOL("LandmarksSortedByDate"); + sorting_order=!sorting_order; + gSavedSettings.setBOOL("LandmarksSortedByDate",sorting_order); + updateSortOrder(mLandmarksInventoryPanel, sorting_order); + updateSortOrder(mMyInventoryPanel, sorting_order); + updateSortOrder(mLibraryInventoryPanel, sorting_order); } else { @@ -895,7 +896,8 @@ bool LLLandmarksPanel::isActionChecked(const LLSD& userdata) const if ( "sort_by_date" == command_name) { - return mSortByDate; + bool sorting_order = gSavedSettings.getBOOL("LandmarksSortedByDate"); + return sorting_order; } return false; diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h index 8f8d9c2708..0e70c72f11 100644 --- a/indra/newview/llpanellandmarks.h +++ b/indra/newview/llpanellandmarks.h @@ -167,7 +167,6 @@ private: LLInventoryObserver* mInventoryObserver; LLPanel* mListCommands; - bool mSortByDate; typedef std::vector<LLAccordionCtrlTab*> accordion_tabs_t; accordion_tabs_t mAccordionTabs; diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index 78de384cdc..42de6d1ef4 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -79,6 +79,70 @@ const U64 ALL_ITEMS_MASK = WEARABLE_MASK | ATTACHMENT_MASK; static const std::string REVERT_BTN("revert_btn"); +class LLPanelOutfitEditGearMenu +{ +public: + static LLMenuGL* create() + { + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + + registrar.add("Wearable.Create", boost::bind(onCreate, _2)); + + LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>( + "menu_cof_gear.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance()); + llassert(menu); + if (menu) + { + populateCreateWearableSubmenus(menu); + menu->buildDrawLabels(); + } + + return menu; + } + +private: + static void onCreate(const LLSD& param) + { + LLWearableType::EType type = LLWearableType::typeNameToType(param.asString()); + if (type == LLWearableType::WT_NONE) + { + llwarns << "Invalid wearable type" << llendl; + return; + } + + LLAgentWearables::createWearable(type, true); + } + + // Populate the menu with items like "New Skin", "New Pants", etc. + static void populateCreateWearableSubmenus(LLMenuGL* menu) + { + LLView* menu_clothes = gMenuHolder->findChildView("COF.Gear.New_Clothes", FALSE); + LLView* menu_bp = gMenuHolder->findChildView("COF.Geear.New_Body_Parts", FALSE); + + if (!menu_clothes || !menu_bp) + { + llassert(menu_clothes && menu_bp); + return; + } + + for (U8 i = LLWearableType::WT_SHAPE; i != (U8) LLWearableType::WT_COUNT; ++i) + { + LLWearableType::EType type = (LLWearableType::EType) i; + const std::string& type_name = LLWearableType::getTypeName(type); + + LLMenuItemCallGL::Params p; + p.name = type_name; + p.label = LLWearableType::getTypeDefaultNewName(type); + p.on_click.function_name = "Wearable.Create"; + p.on_click.parameter = LLSD(type_name); + + LLView* parent = LLWearableType::getAssetType(type) == LLAssetType::AT_CLOTHING ? + menu_clothes : menu_bp; + LLUICtrlFactory::create<LLMenuItemCallGL>(p, parent); + } + } +}; + class LLCOFObserver : public LLInventoryObserver { public: @@ -259,7 +323,6 @@ BOOL LLPanelOutfitEdit::postBuild() mFolderViewBtn = getChild<LLButton>("folder_view_btn"); mListViewBtn = getChild<LLButton>("list_view_btn"); - mAddToOutfitBtn = getChild<LLButton>("add_to_outfit_btn"); childSetCommitCallback("filter_button", boost::bind(&LLPanelOutfitEdit::showWearablesFilter, this), NULL); childSetCommitCallback("folder_view_btn", boost::bind(&LLPanelOutfitEdit::showFilteredFolderWearablesPanel, this), NULL); @@ -275,8 +338,6 @@ BOOL LLPanelOutfitEdit::postBuild() mCOFWearables->getCOFCallbacks().mMoveWearableCloser = boost::bind(&LLPanelOutfitEdit::moveWearable, this, true); mCOFWearables->getCOFCallbacks().mMoveWearableFurther = boost::bind(&LLPanelOutfitEdit::moveWearable, this, false); - mCOFWearables->childSetAction("add_btn", boost::bind(&LLPanelOutfitEdit::toggleAddWearablesPanel, this)); - mAddWearablesPanel = getChild<LLPanel>("add_wearables_panel"); mInventoryItemsPanel = getChild<LLInventoryPanel>("inventory_items"); @@ -298,7 +359,8 @@ BOOL LLPanelOutfitEdit::postBuild() mSearchFilter = getChild<LLFilterEditor>("look_item_filter"); mSearchFilter->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onSearchEdit, this, _2)); - + + childSetAction("show_add_wearables_btn", boost::bind(&LLPanelOutfitEdit::toggleAddWearablesPanel, this)); childSetAction("add_to_outfit_btn", boost::bind(&LLPanelOutfitEdit::onAddToOutfitClicked, this)); mEditWearableBtn = getChild<LLButton>("edit_wearable_btn"); @@ -341,15 +403,28 @@ void LLPanelOutfitEdit::moveWearable(bool closer_to_body) void LLPanelOutfitEdit::toggleAddWearablesPanel() { BOOL current_visibility = mAddWearablesPanel->getVisible(); - mAddWearablesPanel->setVisible(!current_visibility); + showAddWearablesPanel(!current_visibility); +} + +void LLPanelOutfitEdit::showAddWearablesPanel(bool show_add_wearables) +{ + mAddWearablesPanel->setVisible(show_add_wearables); + + childSetValue("show_add_wearables_btn", show_add_wearables); - mFolderViewBtn->setVisible(!current_visibility); - mListViewBtn->setVisible(!current_visibility); - mAddToOutfitBtn->setVisible(!current_visibility); + childSetVisible("filter_wearables_combobox", show_add_wearables); + childSetVisible("filter_button", show_add_wearables); - // Change right dummy icon to fill the toggled buttons space. - childSetVisible("add_wearables_dummy_icon", !current_visibility); - childSetVisible("dummy_right_icon", current_visibility); + //search filter should be disabled + if (!show_add_wearables) + { + childSetValue("filter_button", false); + showWearablesFilter(); + } + + //switching button bars + childSetVisible("no_add_wearables_button_bar", !show_add_wearables); + childSetVisible("add_wearables_button_bar", show_add_wearables); } void LLPanelOutfitEdit::showWearablesFilter() @@ -708,34 +783,18 @@ void LLPanelOutfitEdit::onGearButtonClick(LLUICtrl* clicked_button) { if(!mGearMenu) { - LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; - - registrar.add("Gear.OnClick", boost::bind(&LLPanelOutfitEdit::onGearMenuItemClick, this, _2)); - - mGearMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>( - "menu_cof_gear.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance()); - mGearMenu->buildDrawLabels(); - mGearMenu->updateParent(LLMenuGL::sMenuContainer); + mGearMenu = LLPanelOutfitEditGearMenu::create(); } S32 menu_y = mGearMenu->getRect().getHeight() + clicked_button->getRect().getHeight(); LLMenuGL::showPopup(clicked_button, mGearMenu, 0, menu_y); } -void LLPanelOutfitEdit::onGearMenuItemClick(const LLSD& data) -{ - std::string param = data.asString(); - if("add" == param) - { - // TODO - } -} - void LLPanelOutfitEdit::showFilteredWearableItemsList(LLWearableType::EType type) { mWearableListTypeCollector->setType(type); mWearableListManager->setFilterCollector(mWearableListTypeCollector); - mAddWearablesPanel->setVisible(TRUE); + showAddWearablesPanel(true); showFilteredWearablesPanel(); } diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h index 1569c55732..802386c573 100644 --- a/indra/newview/llpaneloutfitedit.h +++ b/indra/newview/llpaneloutfitedit.h @@ -93,6 +93,7 @@ public: void moveWearable(bool closer_to_body); void toggleAddWearablesPanel(); + void showAddWearablesPanel(bool show__add_wearables); void showWearablesFilter(); void showFilteredWearablesPanel(); void showFilteredFolderWearablesPanel(); @@ -131,7 +132,6 @@ public: private: void onGearButtonClick(LLUICtrl* clicked_button); - void onGearMenuItemClick(const LLSD& data); void showFilteredWearableItemsList(LLWearableType::EType type); @@ -144,7 +144,6 @@ private: LLButton* mEditWearableBtn; LLButton* mFolderViewBtn; LLButton* mListViewBtn; - LLButton* mAddToOutfitBtn; LLPanel* mAddWearablesPanel; LLFindNonLinksByMask* mWearableListMaskCollector; diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp index 21f69d3470..74631c03df 100644 --- a/indra/newview/llpaneloutfitsinventory.cpp +++ b/indra/newview/llpaneloutfitsinventory.cpp @@ -42,6 +42,7 @@ #include "llfloaterworldmap.h" #include "llfloaterinventory.h" #include "llfoldervieweventlistener.h" +#include "llinventorybridge.h" #include "llinventoryfunctions.h" #include "llinventorymodelbackgroundfetch.h" #include "llinventorypanel.h" @@ -70,11 +71,134 @@ static const std::string COF_TAB_NAME = "cof_tab"; static LLRegisterPanelClassWrapper<LLPanelOutfitsInventory> t_inventory("panel_outfits_inventory"); +class LLOutfitListGearMenu +{ +public: + LLOutfitListGearMenu(LLOutfitsList* olist) + : mOutfitList(olist), + mMenu(NULL) + { + llassert_always(mOutfitList); + + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; + + registrar.add("Gear.Wear", boost::bind(&LLOutfitListGearMenu::onWear, this)); + registrar.add("Gear.TakeOff", boost::bind(&LLOutfitListGearMenu::onTakeOff, this)); + registrar.add("Gear.Rename", boost::bind(&LLOutfitListGearMenu::onRename, this)); + registrar.add("Gear.Delete", boost::bind(&LLOutfitListGearMenu::onDelete, this)); + registrar.add("Gear.Create", boost::bind(&LLOutfitListGearMenu::onCreate, this, _2)); + + enable_registrar.add("Gear.OnEnable", boost::bind(&LLOutfitListGearMenu::onEnable, this, _2)); + + mMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>( + "menu_outfit_gear.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + llassert(mMenu); + } + + LLMenuGL* getMenu() { return mMenu; } + +private: + const LLUUID& getSelectedOutfitID() + { + return mOutfitList->getSelectedOutfitUUID(); + } + + LLViewerInventoryCategory* getSelectedOutfit() + { + const LLUUID& selected_outfit_id = getSelectedOutfitID(); + if (selected_outfit_id.isNull()) + { + return NULL; + } + + LLViewerInventoryCategory* cat = gInventory.getCategory(selected_outfit_id); + return cat; + } + + void onWear() + { + LLViewerInventoryCategory* selected_outfit = getSelectedOutfit(); + if (selected_outfit) + { + LLAppearanceMgr::instance().wearInventoryCategory( + selected_outfit, /*copy=*/ FALSE, /*append=*/ FALSE); + } + } + + void onTakeOff() + { + const LLUUID& selected_outfit_id = getSelectedOutfitID(); + if (selected_outfit_id.notNull()) + { + LLAppearanceMgr::instance().takeOffOutfit(selected_outfit_id); + } + } + + void onRename() + { + const LLUUID& selected_outfit_id = getSelectedOutfitID(); + if (selected_outfit_id.notNull()) + { + LLAppearanceMgr::instance().renameOutfit(selected_outfit_id); + } + } + + void onDelete() + { + const LLUUID& selected_outfit_id = getSelectedOutfitID(); + if (selected_outfit_id.notNull()) + { + remove_category(&gInventory, selected_outfit_id); + } + } + + void onCreate(const LLSD& data) + { + LLWearableType::EType type = LLWearableType::typeNameToType(data.asString()); + if (type == LLWearableType::WT_NONE) + { + llwarns << "Invalid wearable type" << llendl; + return; + } + + LLAgentWearables::createWearable(type, true); + } + + bool onEnable(LLSD::String param) + { + const LLUUID& selected_outfit_id = getSelectedOutfitID(); + bool is_worn = LLAppearanceMgr::instance().getBaseOutfitUUID() == selected_outfit_id; + + if ("wear" == param) + { + return !is_worn; + } + else if ("take_off" == param) + { + return is_worn; + } + else if ("rename" == param) + { + return get_is_category_renameable(&gInventory, selected_outfit_id); + } + else if ("delete" == param) + { + return LLAppearanceMgr::instance().getCanRemoveOutfit(selected_outfit_id); + } + + return true; + } + + LLOutfitsList* mOutfitList; + LLMenuGL* mMenu; +}; LLPanelOutfitsInventory::LLPanelOutfitsInventory() : mMyOutfitsPanel(NULL), mCurrentOutfitPanel(NULL), mParent(NULL), + mGearMenu(NULL), mInitialized(false) { mSavedFolderState = new LLSaveFolderState(); @@ -84,6 +208,7 @@ LLPanelOutfitsInventory::LLPanelOutfitsInventory() : LLPanelOutfitsInventory::~LLPanelOutfitsInventory() { + delete mGearMenu; delete mSavedFolderState; } @@ -374,7 +499,7 @@ void LLPanelOutfitsInventory::initListCommandsHandlers() { mListCommands = getChild<LLPanel>("bottom_panel"); - mListCommands->childSetAction("options_gear_btn", boost::bind(&LLPanelOutfitsInventory::onGearButtonClick, this)); + mListCommands->childSetAction("options_gear_btn", boost::bind(&LLPanelOutfitsInventory::showGearMenu, this)); mListCommands->childSetAction("trash_btn", boost::bind(&LLPanelOutfitsInventory::onTrashButtonClick, this)); mListCommands->childSetAction("wear_btn", boost::bind(&LLPanelOutfitsInventory::onWearButtonClick, this)); @@ -385,8 +510,7 @@ void LLPanelOutfitsInventory::initListCommandsHandlers() , _7 // EAcceptance* accept )); - mMenuGearDefault = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_outfit_gear.xml", - gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + mGearMenu = new LLOutfitListGearMenu(mMyOutfitsPanel); } void LLPanelOutfitsInventory::updateListCommands() @@ -401,18 +525,14 @@ void LLPanelOutfitsInventory::updateListCommands() mSaveComboBtn->setSaveBtnEnabled(make_outfit_enabled); } -void LLPanelOutfitsInventory::onGearButtonClick() -{ - showActionMenu(mMenuGearDefault,"options_gear_btn"); -} - -void LLPanelOutfitsInventory::showActionMenu(LLMenuGL* menu, std::string spawning_view_name) +void LLPanelOutfitsInventory::showGearMenu() { + LLMenuGL* menu = mGearMenu ? mGearMenu->getMenu() : NULL; if (menu) { menu->buildDrawLabels(); menu->updateParent(LLMenuGL::sMenuContainer); - LLView* spawning_view = getChild<LLView> (spawning_view_name); + LLView* spawning_view = getChild<LLView>("options_gear_btn"); S32 menu_x, menu_y; //show menu in co-ordinates of panel spawning_view->localPointToOtherView(0, spawning_view->getRect().getHeight(), &menu_x, &menu_y, this); diff --git a/indra/newview/llpaneloutfitsinventory.h b/indra/newview/llpaneloutfitsinventory.h index 7bdd37c16c..aff7839bcc 100644 --- a/indra/newview/llpaneloutfitsinventory.h +++ b/indra/newview/llpaneloutfitsinventory.h @@ -47,6 +47,7 @@ class LLMenuGL; class LLSidepanelAppearance; class LLTabContainer; class LLSaveOutfitComboBtn; +class LLOutfitListGearMenu; class LLPanelOutfitsInventory : public LLPanel { @@ -116,9 +117,8 @@ private: protected: void initListCommandsHandlers(); void updateListCommands(); - void onGearButtonClick(); void onWearButtonClick(); - void showActionMenu(LLMenuGL* menu, std::string spawning_view_name); + void showGearMenu(); void onTrashButtonClick(); void onClipboardAction(const LLSD& userdata); BOOL isActionEnabled(const LLSD& command_name); @@ -129,7 +129,7 @@ protected: void onWearablesLoaded(); private: LLPanel* mListCommands; - LLMenuGL* mMenuGearDefault; + LLOutfitListGearMenu* mGearMenu; LLMenuGL* mMenuAdd; // List Commands // //////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index 4f0946774a..f020ad9bc2 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -827,7 +827,8 @@ void LLParticipantList::LLParticipantListMenu::moderateVoiceAllParticipants(bool void LLParticipantList::LLParticipantListMenu::confirmMuteAllCallback(const LLSD& notification, const LLSD& response) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (option != 1) + // if Cancel pressed + if (option == 1) { return; } diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp index 9159f42968..3c97f01887 100644 --- a/indra/newview/llsidetray.cpp +++ b/indra/newview/llsidetray.cpp @@ -66,21 +66,6 @@ static const std::string TAB_PANEL_CAPTION_TITLE_BOX = "sidetray_tab_title"; LLSideTray* LLSideTray::sInstance = 0; -/** - * Updates visibility of sidetray tabs buttons according to "SidebarWithButtonsVisibility" setting - * - * @param force_set_visible if true method ignores setting value and set buttons visible. - */ -static void update_tabs_buttons_visibility(bool force_set_visible = false) -{ - LLView* side_bar_tabs = gViewerWindow->getRootView()->getChildView("side_bar_tabs"); - if (side_bar_tabs) - { - BOOL visible = LLUI::sSettingGroups["config"]->getBOOL("SidebarWithButtonsVisibility"); - side_bar_tabs->setVisible(force_set_visible || visible); - } -} - LLSideTray* LLSideTray::getInstance() { if (!sInstance) @@ -273,8 +258,6 @@ LLSideTray::LLSideTray(Params& params) p.name = "buttons_panel"; p.mouse_opaque = false; mButtonsPanel = LLUICtrlFactory::create<LLPanel>(p); - - initControlSettings(); } @@ -563,8 +546,6 @@ void LLSideTray::collapseSideBar() //mActiveTab->setVisible(FALSE); reflectCollapseChange(); setFocus( FALSE ); - - update_tabs_buttons_visibility(); } void LLSideTray::expandSideBar() @@ -589,8 +570,6 @@ void LLSideTray::expandSideBar() LLButton* btn = btn_it->second; btn->setImageOverlay( mActiveTab->mImageSelected ); } - - update_tabs_buttons_visibility(true); } void LLSideTray::highlightFocused() @@ -658,8 +637,6 @@ LLPanel* LLSideTray::showPanel (const std::string& panel_name, const LLSD& para panel->onOpen(params); } - update_tabs_buttons_visibility(true); - return panel; } } @@ -751,35 +728,3 @@ void LLSideTray::updateSidetrayVisibility() } } -void LLSideTray::initControlSettings() -{ - // set listeners to process runtime setting changes - LLUI::sSettingGroups["config"]->getControl("SidebarWithButtonsVisibility")->getSignal()->connect(boost::bind(&LLSideTray::toggleSidetrayAndTabButtonsVisibility, this, _2)); - - // update visibility according to current value - toggleSidetrayAndTabButtonsVisibility(LLUI::sSettingGroups["config"]->getBOOL("SidebarWithButtonsVisibility")); -} - -// sidebar visibility is implemented via its expanding/collapsing -void LLSideTray::toggleSidetrayAndTabButtonsVisibility(const LLSD::Boolean& new_visibility) -{ - // If new_visibility==FALSE it gets invisible but still can be expanded in other ways (Ctrl+I to see My Inventory) - - // store collapsed state to restore it properly on next call - static bool was_collapsed = false; - - if (!new_visibility && !mCollapsed) - { - collapseSideBar(); - was_collapsed = true; - } - // should be visible: expand only if it was expanded when has been collapsed on previous call - else if (new_visibility && was_collapsed) - { - if (mCollapsed) expandSideBar(); - was_collapsed = false; - } - - update_tabs_buttons_visibility(new_visibility); -} - diff --git a/indra/newview/llsidetray.h b/indra/newview/llsidetray.h index ed6b376d5c..e8fdee9430 100644 --- a/indra/newview/llsidetray.h +++ b/indra/newview/llsidetray.h @@ -179,16 +179,6 @@ private: LLSideTray::getInstance()->setEnabled(FALSE); } - /** - * Initializes listener of SidebarWithButtonsVisibility setting and updates state according to it. - */ - void initControlSettings(); - - /** - * Updates Sidebar and its Tab Buttons visibility according to passed value. - */ - void toggleSidetrayAndTabButtonsVisibility(const LLSD::Boolean& new_visibility); - private: LLPanel* mButtonsPanel; diff --git a/indra/newview/llteleporthistory.cpp b/indra/newview/llteleporthistory.cpp index 15684337f4..cac3b58464 100644 --- a/indra/newview/llteleporthistory.cpp +++ b/indra/newview/llteleporthistory.cpp @@ -38,6 +38,7 @@ #include "llsdserialize.h" #include "llagent.h" +#include "llvoavatarself.h" #include "llslurl.h" #include "llviewercontrol.h" // for gSavedSettings #include "llviewerparcelmgr.h" @@ -108,6 +109,16 @@ void LLTeleportHistory::onTeleportFailed() } } +void LLTeleportHistory::handleLoginComplete() +{ + if( mGotInitialUpdate ) + { + return; + } + updateCurrentLocation(gAgent.getPositionGlobal()); +} + + void LLTeleportHistory::updateCurrentLocation(const LLVector3d& new_pos) { if (mRequestedItem != -1) // teleport within the history in progress? @@ -117,6 +128,17 @@ void LLTeleportHistory::updateCurrentLocation(const LLVector3d& new_pos) } else { + //EXT-7034 + //skip initial update if agent avatar is no valid yet + //this may happen when updateCurrentLocation called while login process + //sometimes isAgentAvatarValid return false and in this case new_pos + //(which actually is gAgent.getPositionGlobal() ) is invalid + //if this position will be saved then teleport back will teleport user to wrong position + if ( !mGotInitialUpdate && !isAgentAvatarValid() ) + { + return ; + } + // If we're getting the initial location update // while we already have a (loaded) non-empty history, // there's no need to purge forward items or add a new item. diff --git a/indra/newview/llteleporthistory.h b/indra/newview/llteleporthistory.h index a82bec7c4f..e035451e71 100644 --- a/indra/newview/llteleporthistory.h +++ b/indra/newview/llteleporthistory.h @@ -136,6 +136,10 @@ public: * @see load() */ void dump() const; + /** + * Process login complete event. Basically put current location into history + */ + void handleLoginComplete(); private: diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 8a8bdd2dba..bc77ac5fd1 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -48,7 +48,7 @@ #include "llgiveinventory.h" #include "llhudmanager.h" #include "llhudeffecttrail.h" -//#include "llimview.h" +#include "llimview.h" #include "llinventorybridge.h" #include "llinventorydefines.h" #include "llinventoryfunctions.h" @@ -1422,12 +1422,42 @@ EAcceptance LLToolDragAndDrop::willObjectAcceptInventory(LLViewerObject* obj, LL } +static void give_inventory_cb(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + // if Cancel pressed + if (option == 1) + { + return; + } + + LLSD payload = notification["payload"]; + const LLUUID& session_id = payload["session_id"]; + const LLUUID& agent_id = payload["agent_id"]; + LLViewerInventoryItem * inv_item = gInventory.getItem(payload["item_id"]); + if (NULL == inv_item) + { + llassert(NULL != inv_item); + return; + } + + if (LLGiveInventory::doGiveInventoryItem(agent_id, inv_item, session_id)) + { + if ("avatarpicker" == payload["d&d_dest"].asString()) + { + LLFloaterReg::hideInstance("avatar_picker"); + } + LLNotificationsUtil::add("ItemsShared"); + } +} + // function used as drag-and-drop handler for simple agent give inventory requests //static bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_id, BOOL drop, EDragAndDropType cargo_type, void* cargo_data, - EAcceptance* accept) + EAcceptance* accept, + const LLSD& dest) { // check the type switch(cargo_type) @@ -1452,7 +1482,21 @@ bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_ *accept = ACCEPT_YES_COPY_SINGLE; if (drop) { - LLGiveInventory::doGiveInventoryItem(dest_agent, inv_item, session_id); + LLIMModel::LLIMSession * session = LLIMModel::instance().findIMSession(session_id); + if (NULL == session) + { + llassert(NULL != session); + return false; + } + LLSD substitutions; + substitutions["RESIDENTS"] = session->mName; + substitutions["ITEMS"] = inv_item->getName(); + LLSD payload; + payload["agent_id"] = dest_agent; + payload["item_id"] = inv_item->getUUID(); + payload["session_id"] = session_id; + payload["d&d_dest"] = dest.asString(); + LLNotificationsUtil::add("ShareItemsConfirmation", substitutions, payload, &give_inventory_cb); } } else diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h index 18334b5ee1..36e69c1db3 100644 --- a/indra/newview/lltooldraganddrop.h +++ b/indra/newview/lltooldraganddrop.h @@ -246,7 +246,8 @@ public: static bool handleGiveDragAndDrop(LLUUID agent, LLUUID session, BOOL drop, EDragAndDropType cargo_type, void* cargo_data, - EAcceptance* accept); + EAcceptance* accept, + const LLSD& dest = LLSD()); // Classes used for determining 3d drag and drop types. private: diff --git a/indra/newview/llviewerattachmenu.cpp b/indra/newview/llviewerattachmenu.cpp new file mode 100644 index 0000000000..f7f5ec72fd --- /dev/null +++ b/indra/newview/llviewerattachmenu.cpp @@ -0,0 +1,139 @@ +/** + * @file llviewerattachmenu.cpp + * @brief "Attach to" / "Attach to HUD" submenus. + * + * $LicenseInfo:firstyear=2010&license=viewergpl$ + * + * Copyright (c) 2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llviewerattachmenu.h" + +// project includes +#include "llagent.h" +#include "llinventorybridge.h" // for rez_attachment() +#include "llinventorymodel.h" +#include "llviewerinventory.h" +#include "llviewermenu.h" // for gMenuHolder +#include "llvoavatarself.h" + +// linden libraries +#include "llmenugl.h" +#include "lltrans.h" + +// static +void LLViewerAttachMenu::populateMenus(const std::string& attach_to_menu_name, const std::string& attach_to_hud_menu_name) +{ + // *TODO: share this code with other similar menus + // (inventory panel context menu, in-world object menu). + + if (attach_to_menu_name.empty() || attach_to_hud_menu_name.empty() || !isAgentAvatarValid()) return; + + LLContextMenu* attach_menu = gMenuHolder->getChild<LLContextMenu>(attach_to_menu_name); + LLContextMenu* attach_hud_menu = gMenuHolder->getChild<LLContextMenu>(attach_to_hud_menu_name); + + if (!attach_menu || attach_menu->getChildCount() != 0 || + !attach_hud_menu || attach_hud_menu->getChildCount() != 0) + { + return; + } + + // Populate "Attach to..." / "Attach to HUD..." submenus. + for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); + iter != gAgentAvatarp->mAttachmentPoints.end(); ) + { + LLVOAvatar::attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; + LLMenuItemCallGL::Params p; + std::string submenu_name = attachment->getName(); + std::string translated_submenu_name; + + if (LLTrans::findString(translated_submenu_name, submenu_name)) + { + p.name = (" ") + translated_submenu_name + " "; + } + else + { + p.name = submenu_name; + } + + LLSD cbparams; + cbparams["index"] = curiter->first; + cbparams["label"] = attachment->getName(); + p.on_click.function_name = "Object.Attach"; + p.on_click.parameter = LLSD(attachment->getName()); + p.on_enable.function_name = "Attachment.Label"; + p.on_enable.parameter = cbparams; + + LLMenuItemCallGL* item = LLUICtrlFactory::create<LLMenuItemCallGL>(p); + LLView* parent_menu = attachment->getIsHUDAttachment() ? attach_hud_menu : attach_menu; + parent_menu->addChild(item); + } +} + +// static +void LLViewerAttachMenu::attachObjects(const uuid_vec_t& items, const std::string& joint_name) +{ + LLViewerJointAttachment* attachmentp = NULL; + for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); + iter != gAgentAvatarp->mAttachmentPoints.end(); ) + { + LLVOAvatar::attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; + if (attachment->getName() == joint_name) + { + attachmentp = attachment; + break; + } + } + if (attachmentp == NULL) + { + return; + } + + for (uuid_vec_t::const_iterator it = items.begin(); it != items.end(); ++it) + { + const LLUUID &id = *it; + LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getLinkedItem(id); + if(item && gInventory.isObjectDescendentOf(id, gInventory.getRootFolderID())) + { + rez_attachment(item, attachmentp); + } + else if(item && item->isFinished()) + { + // must be in library. copy it to our inventory and put it on. + LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(attachmentp); + copy_inventory_item(gAgent.getID(), + item->getPermissions().getOwner(), + item->getUUID(), + LLUUID::null, + std::string(), + cb); + } + } +} diff --git a/indra/newview/llviewerattachmenu.h b/indra/newview/llviewerattachmenu.h new file mode 100644 index 0000000000..d1db9914f3 --- /dev/null +++ b/indra/newview/llviewerattachmenu.h @@ -0,0 +1,43 @@ +/** + * @file llviewerattachmenu.h + * @brief "Attach to" / "Attach to HUD" submenus. + * + * $LicenseInfo:firstyear=2010&license=viewergpl$ + * + * Copyright (c) 2010, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLVIEWERATTACHMENU_H +#define LL_LLVIEWERATTACHMENU_H + +class LLViewerAttachMenu +{ +public: + static void populateMenus(const std::string& attach_to_menu_name, const std::string& attach_to_hud_menu_name); + static void attachObjects(const uuid_vec_t& items, const std::string& joint_name); +}; + +#endif // LL_LLVIEWERATTACHMENU_H diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index e2be49e4cc..a788d3c457 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -39,6 +39,7 @@ #include "llagent.h" #include "llagentcamera.h" +#include "llagentwearables.h" #include "llviewerfoldertype.h" #include "llfolderview.h" #include "llviewercontrol.h" @@ -119,10 +120,10 @@ public: mInventoryItemsDict["Male - Wow"] = LLTrans::getString("Male - Wow"); //female - mInventoryItemsDict["FeMale - Excuse me"] = LLTrans::getString("FeMale - Excuse me"); - mInventoryItemsDict["FeMale - Get lost"] = LLTrans::getString("FeMale - Get lost"); - mInventoryItemsDict["FeMale - Blow kiss"] = LLTrans::getString("FeMale - Blow kiss"); - mInventoryItemsDict["FeMale - Boo"] = LLTrans::getString("FeMale - Boo"); + mInventoryItemsDict["Female - Excuse me"] = LLTrans::getString("Female - Excuse me"); + mInventoryItemsDict["Female - Get lost"] = LLTrans::getString("Female - Get lost"); + mInventoryItemsDict["Female - Blow kiss"] = LLTrans::getString("Female - Blow kiss"); + mInventoryItemsDict["Female - Boo"] = LLTrans::getString("Female - Boo"); mInventoryItemsDict["Female - Bored"] = LLTrans::getString("Female - Bored"); mInventoryItemsDict["Female - Hey"] = LLTrans::getString("Female - Hey"); mInventoryItemsDict["Female - Laugh"] = LLTrans::getString("Female - Laugh"); @@ -880,6 +881,14 @@ void WearOnAvatarCallback::fire(const LLUUID& inv_item) void ModifiedCOFCallback::fire(const LLUUID& inv_item) { LLAppearanceMgr::instance().updateAppearanceFromCOF(); + + if (LLSideTray::getInstance()->isPanelActive("sidepanel_appearance")) + { + // *HACK: Edit the wearable that has just been worn + // only if the Appearance SP is currently opened. + LLAgentWearables::editWearable(inv_item); + } + // TODO: camera mode may not be changed if a debug setting is tweaked if( gAgentCamera.cameraCustomizeAvatar() ) { @@ -1240,10 +1249,8 @@ void menu_create_inventory_item(LLFolderView* root, LLFolderBridge *bridge, cons LLWearableType::EType wearable_type = LLWearableType::typeNameToType(type_name); if (wearable_type >= LLWearableType::WT_SHAPE && wearable_type < LLWearableType::WT_COUNT) { - LLAssetType::EType asset_type = LLWearableType::getAssetType(wearable_type); - LLFolderType::EType folder_type = LLFolderType::assetTypeToFolderType(asset_type); - const LLUUID parent_id = bridge ? bridge->getUUID() : gInventory.findCategoryUUIDForType(folder_type); - LLFolderBridge::createWearable(parent_id, wearable_type); + const LLUUID parent_id = bridge ? bridge->getUUID() : LLUUID::null; + LLAgentWearables::createWearable(wearable_type, false, parent_id); } else { diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 7a232afba6..bb6afcc84d 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -68,6 +68,7 @@ #include "llmoveview.h" #include "llnotificationsutil.h" #include "llquantize.h" +#include "llrand.h" #include "llregionhandle.h" #include "llresmgr.h" #include "llselectmgr.h" @@ -6686,6 +6687,41 @@ void LLVOAvatar::onFirstTEMessageReceived() } //----------------------------------------------------------------------------- +// bool visualParamWeightsAreDefault() +//----------------------------------------------------------------------------- +bool LLVOAvatar::visualParamWeightsAreDefault() +{ + bool rtn = true; + + bool is_wearing_skirt = isWearingWearableType(LLWearableType::WT_SKIRT); + for (LLVisualParam *param = getFirstVisualParam(); + param; + param = getNextVisualParam()) + { + if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) + { + LLViewerVisualParam* vparam = dynamic_cast<LLViewerVisualParam*>(param); + llassert(vparam); + bool is_skirt_param = vparam && + LLWearableType::WT_SKIRT == vparam->getWearableType(); + if (param->getWeight() != param->getDefaultWeight() && + // we have to not care whether skirt weights are default, if we're not actually wearing a skirt + (is_wearing_skirt || !is_skirt_param)) + { + //llinfos << "param '" << param->getName() << "'=" << param->getWeight() << " which differs from default=" << param->getDefaultWeight() << llendl; + rtn = false; + break; + } + } + } + + //llinfos << "params are default ? " << int(rtn) << llendl; + + return rtn; +} + + +//----------------------------------------------------------------------------- // processAvatarAppearance() //----------------------------------------------------------------------------- void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) @@ -6753,16 +6789,17 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) { releaseComponentTextures(); } - - + // parse visual params S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam); - if( num_blocks > 1 ) + bool drop_visual_params_debug = gSavedSettings.getBOOL("BlockSomeAvatarAppearanceVisualParams") && (ll_rand(2) == 0); // pretend that ~12% of AvatarAppearance messages arrived without a VisualParam block, for testing + if( num_blocks > 1 && !drop_visual_params_debug) { BOOL params_changed = FALSE; BOOL interp_params = FALSE; LLVisualParam* param = getFirstVisualParam(); + llassert(param); // if this ever fires, we should do the same as when num_blocks<=1 if (!param) { llwarns << "No visual params!" << llendl; @@ -6778,8 +6815,8 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) if( !param ) { - llwarns << "Number of params in AvatarAppearance msg does not match number of params in avatar xml file." << llendl; - return; + // more visual params supplied than expected - just process what we know about + break; } U8 value; @@ -6804,14 +6841,10 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) } } - while( param && (param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) ) + const S32 expected_tweakable_count = getVisualParamCountInGroup(VISUAL_PARAM_GROUP_TWEAKABLE); + if (num_blocks != expected_tweakable_count) { - param = getNextVisualParam(); - } - if( param ) - { - llwarns << "Number of params in AvatarAppearance msg does not match number of params in avatar xml file." << llendl; - return; + llinfos << "Number of params in AvatarAppearance msg (" << num_blocks << ") does not match number of tweakable params in avatar xml file (" << expected_tweakable_count << "). Processing what we can. object: " << getID() << llendl; } if (params_changed) @@ -6828,16 +6861,37 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) updateSexDependentLayerSets( FALSE ); } } + + llassert( getSex() == ((getVisualParamWeight( "male" ) > 0.5f) ? SEX_MALE : SEX_FEMALE) ); } else { - llwarns << "AvatarAppearance msg received without any parameters, object: " << getID() << llendl; + // AvatarAppearance message arrived without visual params + if (drop_visual_params_debug) + { + llinfos << "Debug-faked lack of parameters on AvatarAppearance for object: " << getID() << llendl; + } + else + { + llinfos << "AvatarAppearance msg received without any parameters, object: " << getID() << llendl; + } + + // this isn't really a problem if we already have a non-default shape + if (visualParamWeightsAreDefault()) + { + // re-request appearance, hoping that it comes back with a shape next time + llinfos << "Re-requesting AvatarAppearance for object: " << getID() << llendl; + LLAvatarPropertiesProcessor::getInstance()->sendAvatarTexturesRequest(getID()); + } + else + { + llinfos << "That's okay, we already have a non-default shape for object: " << getID() << llendl; + // we don't really care. + } } setCompositeUpdatesEnabled( TRUE ); - llassert( getSex() == ((getVisualParamWeight( "male" ) > 0.5f) ? SEX_MALE : SEX_FEMALE) ); - // If all of the avatars are completely baked, release the global image caches to conserve memory. LLVOAvatar::cullAvatarsByPixelArea(); diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 3c940e03c0..b30cce09f6 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -249,6 +249,7 @@ public: //-------------------------------------------------------------------- public: BOOL isFullyLoaded() const; + bool visualParamWeightsAreDefault(); protected: virtual BOOL getIsCloud(); BOOL updateIsFullyLoaded(); diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index 161cd40cfc..c35b45d446 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -41,6 +41,7 @@ #include "llinventorymodel.h" #include "llmenugl.h" // for LLContextMenu #include "lltransutil.h" +#include "llviewerattachmenu.h" class LLFindOutfitItems : public LLInventoryCollectFunctor { @@ -94,6 +95,47 @@ LLPanelWearableListItem::LLPanelWearableListItem(LLViewerInventoryItem* item) ////////////////////////////////////////////////////////////////////////// // static +LLPanelWearableOutfitItem* LLPanelWearableOutfitItem::create(LLViewerInventoryItem* item) +{ + LLPanelWearableOutfitItem* list_item = NULL; + if (item) + { + list_item = new LLPanelWearableOutfitItem(item); + list_item->init(); + } + return list_item; +} + +BOOL LLPanelWearableOutfitItem::handleDoubleClick(S32 x, S32 y, MASK mask) +{ + LLViewerInventoryItem* item = getItem(); + if (item) + { + LLUUID id = item->getUUID(); + + if (get_is_item_worn(id)) + { + LLAppearanceMgr::getInstance()->removeItemFromAvatar(id); + } + else + { + LLAppearanceMgr::getInstance()->wearItemOnAvatar(id, true, false); + } + } + + return LLUICtrl::handleDoubleClick(x, y, mask); +} + +LLPanelWearableOutfitItem::LLPanelWearableOutfitItem(LLViewerInventoryItem* item) +: LLPanelInventoryListItemBase(item) +{ +} + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +// static LLPanelClothingListItem* LLPanelClothingListItem::create(LLViewerInventoryItem* item) { LLPanelClothingListItem* list_item = NULL; @@ -402,6 +444,27 @@ LLWearableItemsList::LLWearableItemsList(const LLWearableItemsList::Params& p) LLWearableItemsList::~LLWearableItemsList() {} +// virtual +void LLWearableItemsList::addNewItem(LLViewerInventoryItem* item, bool rearrange /*= true*/) +{ + if (!item) + { + llwarns << "No inventory item. Couldn't create flat list item." << llendl; + llassert(item != NULL); + } + + LLPanelWearableOutfitItem *list_item = LLPanelWearableOutfitItem::create(item); + if (!list_item) + return; + + bool is_item_added = addItem(list_item, item->getUUID(), ADD_BOTTOM, rearrange); + if (!is_item_added) + { + llwarns << "Couldn't add flat list item." << llendl; + llassert(is_item_added); + } +} + void LLWearableItemsList::updateList(const LLUUID& category_id) { LLInventoryModel::cat_array_t cat_array; @@ -449,7 +512,9 @@ LLContextMenu* LLWearableItemsList::ContextMenu::createMenu() // Register handlers common for all wearable types. registrar.add("Wearable.Wear", boost::bind(handleMultiple, wear, ids)); registrar.add("Wearable.Edit", boost::bind(handleMultiple, LLAgentWearables::editWearable, ids)); + registrar.add("Wearable.CreateNew", boost::bind(createNewWearable, selected_id)); registrar.add("Wearable.ShowOriginal", boost::bind(show_item_original, selected_id)); + registrar.add("Wearable.TakeOffDetach", boost::bind(handleMultiple, take_off, ids)); // Register handlers for clothing. registrar.add("Clothing.TakeOff", boost::bind(handleMultiple, take_off, ids)); @@ -459,12 +524,16 @@ LLContextMenu* LLWearableItemsList::ContextMenu::createMenu() // Register handlers for attachments. registrar.add("Attachment.Detach", boost::bind(handleMultiple, take_off, ids)); registrar.add("Attachment.Profile", boost::bind(show_item_profile, selected_id)); + registrar.add("Object.Attach", boost::bind(LLViewerAttachMenu::attachObjects, ids, _2)); // Create the menu. LLContextMenu* menu = createFromFile("menu_wearable_list_item.xml"); // Determine which items should be visible/enabled. updateItemsVisibility(menu); + + // Update labels for the items requiring that. + updateItemsLabels(menu); return menu; } @@ -478,10 +547,10 @@ void LLWearableItemsList::ContextMenu::updateItemsVisibility(LLContextMenu* menu const uuid_vec_t& ids = mUUIDs; // selected items IDs U32 mask = 0; // mask of selected items' types - U32 nitems = ids.size(); // number of selected items - U32 nworn = 0; // number of worn items among the selected ones - U32 nwornlinks = 0; // number of worn links among the selected items - U32 neditable = 0; // number of editable items among the selected ones + U32 n_items = ids.size(); // number of selected items + U32 n_worn = 0; // number of worn items among the selected ones + U32 n_links = 0; // number of links among the selected items + U32 n_editable = 0; // number of editable items among the selected ones for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it) { @@ -503,38 +572,82 @@ void LLWearableItemsList::ContextMenu::updateItemsVisibility(LLContextMenu* menu if (is_worn) { - ++nworn; - - if (is_link) - { - ++nwornlinks; - } + ++n_worn; } if (is_editable) { - ++neditable; + ++n_editable; + } + if (is_link) + { + ++n_links; } } // for // *TODO: eliminate multiple traversals over the menu items - // *TODO: try disabling items rather than hiding them - // *FIX: we may hide *all* items and thus get an ugly empty menu - setMenuItemVisible(menu, "wear", nworn == 0); - setMenuItemVisible(menu, "edit", mask & (MASK_CLOTHING|MASK_BODYPART) && nitems == 1 && neditable == 1); - setMenuItemVisible(menu, "show_original", nitems == 1 && nwornlinks == nitems); - setMenuItemVisible(menu, "take_off", mask == MASK_CLOTHING && nworn == nitems); // selected only worn clothes - setMenuItemVisible(menu, "detach", mask == MASK_ATTACHMENT && nworn == nitems); - setMenuItemVisible(menu, "object_profile", mask == MASK_ATTACHMENT && nitems == 1); + setMenuItemVisible(menu, "wear", n_worn == 0); + setMenuItemVisible(menu, "edit", mask & (MASK_CLOTHING|MASK_BODYPART) && n_items == 1); + setMenuItemEnabled(menu, "edit", n_editable == 1 && n_worn == 1); + setMenuItemVisible(menu, "create_new", mask & (MASK_CLOTHING|MASK_BODYPART) && n_items == 1); + setMenuItemEnabled(menu, "show_original", n_items == 1 && n_links == n_items); + setMenuItemVisible(menu, "take_off", mask == MASK_CLOTHING && n_worn == n_items); + setMenuItemVisible(menu, "detach", mask == MASK_ATTACHMENT && n_worn == n_items); + setMenuItemVisible(menu, "take_off_or_detach", mask == (MASK_ATTACHMENT|MASK_CLOTHING)); + setMenuItemEnabled(menu, "take_off_or_detach", n_worn == n_items); + setMenuItemVisible(menu, "object_profile", mask & (MASK_ATTACHMENT|MASK_CLOTHING)); + setMenuItemEnabled(menu, "object_profile", n_items == 1); + + // Populate or hide the "Attach to..." / "Attach to HUD..." submenus. + if (mask == MASK_ATTACHMENT && n_worn == 0) + { + LLViewerAttachMenu::populateMenus("wearable_attach_to", "wearable_attach_to_hud"); + } + else + { + setMenuItemVisible(menu, "wearable_attach_to", false); + setMenuItemVisible(menu, "wearable_attach_to_hud", false); + } + + if (mask & MASK_UNKNOWN) + { + llwarns << "Non-wearable items passed." << llendl; + } +} + +void LLWearableItemsList::ContextMenu::updateItemsLabels(LLContextMenu* menu) +{ + llassert(menu); + if (!menu) return; + + // Set proper label for the "Create new <WEARABLE_TYPE>" menu item. + LLViewerInventoryItem* item = gInventory.getLinkedItem(mUUIDs.back()); + if (!item || !item->isWearableType()) return; + + LLStringUtil::format_map_t args; + LLWearableType::EType w_type = item->getWearableType(); + args["[WEARABLE_TYPE]"] = LLWearableType::getTypeDefaultNewName(w_type); + std::string new_label = LLTrans::getString("CreateNewWearable", args); + + LLMenuItemGL* menu_item = menu->getChild<LLMenuItemGL>("create_new"); + menu_item->setLabel(new_label); } // We need this method to convert non-zero BOOL values to exactly 1 (TRUE). // Otherwise code relying on a BOOL value being TRUE may fail // (I experienced a weird assert in LLView::drawChildren() because of that. +// static void LLWearableItemsList::ContextMenu::setMenuItemVisible(LLContextMenu* menu, const std::string& name, bool val) { menu->setItemVisible(name, val); } +// static +void LLWearableItemsList::ContextMenu::setMenuItemEnabled(LLContextMenu* menu, const std::string& name, bool val) +{ + menu->setItemEnabled(name, val); +} + +// static void LLWearableItemsList::ContextMenu::updateMask(U32& mask, LLAssetType::EType at) { if (at == LLAssetType::AT_CLOTHING) @@ -551,8 +664,17 @@ void LLWearableItemsList::ContextMenu::updateMask(U32& mask, LLAssetType::EType } else { - llwarns << "Unsupported asset type: " << at << llendl; + mask |= MASK_UNKNOWN; } } +// static +void LLWearableItemsList::ContextMenu::createNewWearable(const LLUUID& item_id) +{ + LLViewerInventoryItem* item = gInventory.getLinkedItem(item_id); + if (!item || !item->isWearableType()) return; + + LLAgentWearables::createWearable(item->getWearableType(), true); +} + // EOF diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h index de024ed220..0ed480a92a 100644 --- a/indra/newview/llwearableitemslist.h +++ b/indra/newview/llwearableitemslist.h @@ -70,6 +70,29 @@ protected: LLPanelWearableListItem(LLViewerInventoryItem* item); }; +/** + * @class LLPanelWearableOutfitItem + * + * Outfit item for "My Outfits" list. + * Extends LLPanelInventoryListItemBase with handling + * double click to wear the item. + */ +class LLPanelWearableOutfitItem : public LLPanelInventoryListItemBase +{ + LOG_CLASS(LLPanelWearableOutfitItem); +public: + static LLPanelWearableOutfitItem* create(LLViewerInventoryItem* item); + + /** + * Puts item on if it is not worn by agent + * otherwise takes it off on double click. + */ + /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); + +protected: + + LLPanelWearableOutfitItem(LLViewerInventoryItem* item); +}; class LLPanelDeletableWearableListItem : public LLPanelWearableListItem { @@ -292,12 +315,16 @@ public: MASK_CLOTHING = 0x01, MASK_BODYPART = 0x02, MASK_ATTACHMENT = 0x04, + MASK_UNKNOWN = 0x08, }; /* virtual */ LLContextMenu* createMenu(); void updateItemsVisibility(LLContextMenu* menu); - void setMenuItemVisible(LLContextMenu* menu, const std::string& name, bool val); - void updateMask(U32& mask, LLAssetType::EType at); + void updateItemsLabels(LLContextMenu* menu); + static void setMenuItemVisible(LLContextMenu* menu, const std::string& name, bool val); + static void setMenuItemEnabled(LLContextMenu* menu, const std::string& name, bool val); + static void updateMask(U32& mask, LLAssetType::EType at); + static void createNewWearable(const LLUUID& item_id); }; struct Params : public LLInitParam::Block<Params, LLInventoryItemsList::Params> @@ -309,6 +336,8 @@ public: virtual ~LLWearableItemsList(); + /*virtual*/ void addNewItem(LLViewerInventoryItem* item, bool rearrange = true); + void updateList(const LLUUID& category_id); protected: diff --git a/indra/newview/skins/default/textures/icons/Inv_LostClosed.png b/indra/newview/skins/default/textures/icons/Inv_LostClosed.png Binary files differnew file mode 100644 index 0000000000..a800217e0d --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_LostClosed.png diff --git a/indra/newview/skins/default/textures/icons/Inv_LostOpen.png b/indra/newview/skins/default/textures/icons/Inv_LostOpen.png Binary files differnew file mode 100644 index 0000000000..8c4a1a9ac0 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_LostOpen.png diff --git a/indra/newview/skins/default/textures/icons/Inv_SysClosed.png b/indra/newview/skins/default/textures/icons/Inv_SysClosed.png Binary files differnew file mode 100644 index 0000000000..dcf998449f --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_SysClosed.png diff --git a/indra/newview/skins/default/textures/icons/Inv_SysOpen.png b/indra/newview/skins/default/textures/icons/Inv_SysOpen.png Binary files differnew file mode 100644 index 0000000000..0efd403c95 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_SysOpen.png diff --git a/indra/newview/skins/default/textures/icons/Inv_TrashClosed.png b/indra/newview/skins/default/textures/icons/Inv_TrashClosed.png Binary files differnew file mode 100644 index 0000000000..c5201e6f9a --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_TrashClosed.png diff --git a/indra/newview/skins/default/textures/icons/Inv_TrashOpen.png b/indra/newview/skins/default/textures/icons/Inv_TrashOpen.png Binary files differnew file mode 100644 index 0000000000..4a886a3f37 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_TrashOpen.png diff --git a/indra/newview/skins/default/textures/icons/back_arrow_off.png b/indra/newview/skins/default/textures/icons/back_arrow_off.png Binary files differnew file mode 100644 index 0000000000..422f67cf83 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/back_arrow_off.png diff --git a/indra/newview/skins/default/textures/icons/back_arrow_over.png b/indra/newview/skins/default/textures/icons/back_arrow_over.png Binary files differnew file mode 100644 index 0000000000..b4cc170f37 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/back_arrow_over.png diff --git a/indra/newview/skins/default/textures/icons/back_arrow_press.png b/indra/newview/skins/default/textures/icons/back_arrow_press.png Binary files differnew file mode 100644 index 0000000000..a9e2f326a7 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/back_arrow_press.png diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 130f5ffaf4..93c805f724 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -68,6 +68,10 @@ with the same filename but different name <texture name="BackArrow_Off" file_name="icons/BackArrow_Off.png" preload="false" /> + <texture name="BackButton_Off" file_name="icons/back_arrow_off.png" preload="false" /> + <texture name="BackButton_Over" file_name="icons/back_arrow_over.png" preload="false" /> + <texture name="BackButton_Press" file_name="icons/back_arrow_press.png" preload="false" /> + <texture name="Blank" file_name="Blank.png" preload="false" /> @@ -201,6 +205,8 @@ with the same filename but different name <texture name="Inv_Jacket" file_name="icons/Inv_Jacket.png" preload="false" /> <texture name="Inv_LookFolderOpen" file_name="icons/Inv_LookFolderOpen.png" preload="false" /> <texture name="Inv_LookFolderClosed" file_name="icons/Inv_LookFolderClosed.png" preload="false" /> + <texture name="Inv_LostClosed" file_name="icons/Inv_LostClosed.png" preload="false" /> + <texture name="Inv_LostOpen" file_name="icons/Inv_LostOpen.png" preload="false" /> <texture name="Inv_Landmark" file_name="icons/Inv_Landmark.png" preload="false" /> <texture name="Inv_Notecard" file_name="icons/Inv_Notecard.png" preload="false" /> <texture name="Inv_Object" file_name="icons/Inv_Object.png" preload="false" /> @@ -214,8 +220,12 @@ with the same filename but different name <texture name="Inv_Snapshot" file_name="icons/Inv_Snapshot.png" preload="false" /> <texture name="Inv_Socks" file_name="icons/Inv_Socks.png" preload="false" /> <texture name="Inv_Sound" file_name="icons/Inv_Sound.png" preload="false" /> + <texture name="Inv_SysClosed" file_name="icons/Inv_SysClosed.png" preload="false" /> + <texture name="Inv_SysOpen" file_name="icons/Inv_SysOpen.png" preload="false" /> <texture name="Inv_Tattoo" file_name="icons/Inv_Tattoo.png" preload="false" /> <texture name="Inv_Texture" file_name="icons/Inv_Texture.png" preload="false" /> + <texture name="Inv_TrashClosed" file_name="icons/Inv_TrashClosed.png" preload="false" /> + <texture name="Inv_TrashOpen" file_name="icons/Inv_TrashOpen.png" preload="false" /> <texture name="Inv_Underpants" file_name="icons/Inv_Underpants.png" preload="false" /> <texture name="Inv_Undershirt" file_name="icons/Inv_Undershirt.png" preload="false" /> diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml index 5f28fa6495..54ef6d65a7 100644 --- a/indra/newview/skins/default/xui/en/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en/floater_about_land.xml @@ -756,7 +756,7 @@ Leyla Linden </text> mouse_opaque="false" name="resellable_clause" word_wrap="true" - width="330"> + width="360"> Land in this region may not be resold. </text> <text diff --git a/indra/newview/skins/default/xui/en/floater_map.xml b/indra/newview/skins/default/xui/en/floater_map.xml index 249b091800..a0e28f7a42 100644 --- a/indra/newview/skins/default/xui/en/floater_map.xml +++ b/indra/newview/skins/default/xui/en/floater_map.xml @@ -5,7 +5,7 @@ can_minimize="true" can_resize="true" follows="top|right" - height="218" + height="174" layout="topleft" min_height="174" min_width="174" diff --git a/indra/newview/skins/default/xui/en/menu_bottomtray.xml b/indra/newview/skins/default/xui/en/menu_bottomtray.xml index ccd5388621..5beafef4e4 100644 --- a/indra/newview/skins/default/xui/en/menu_bottomtray.xml +++ b/indra/newview/skins/default/xui/en/menu_bottomtray.xml @@ -53,17 +53,6 @@ parameter="ShowSnapshotButton" /> </menu_item_check> <menu_item_check - label="Sidebar button" - layout="topleft" - name="ShowSidebarButton"> - <menu_item_check.on_click - function="ToggleControl" - parameter="ShowSidebarButton" /> - <menu_item_check.on_check - function="CheckControl" - parameter="ShowSidebarButton" /> - </menu_item_check> - <menu_item_check label="Build button" layout="topleft" name="ShowBuildButton"> diff --git a/indra/newview/skins/default/xui/en/menu_cof_attachment.xml b/indra/newview/skins/default/xui/en/menu_cof_attachment.xml index b422d87938..c402100fb1 100644 --- a/indra/newview/skins/default/xui/en/menu_cof_attachment.xml +++ b/indra/newview/skins/default/xui/en/menu_cof_attachment.xml @@ -10,12 +10,4 @@ function="Attachment.Detach" parameter="detach"/> </menu_item_call> - <context_menu - label="Attach to" - layout="topleft" - name="attach_to" /> - <context_menu - label="Attach to HUD" - layout="topleft" - name="attach_to_hud" /> </context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_cof_body_part.xml b/indra/newview/skins/default/xui/en/menu_cof_body_part.xml index 01008ef203..f0e8461360 100644 --- a/indra/newview/skins/default/xui/en/menu_cof_body_part.xml +++ b/indra/newview/skins/default/xui/en/menu_cof_body_part.xml @@ -19,4 +19,15 @@ function="BodyPart.OnEnable" parameter="edit" /> </menu_item_call> + <menu_item_call + label="Create New" + layout="topleft" + name="create_new" + translate="false"> + <on_click + function="BodyPart.Create"/> + <on_enable + function="BodyPart.OnEnable" + parameter="create" /> + </menu_item_call> </context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_cof_clothing.xml b/indra/newview/skins/default/xui/en/menu_cof_clothing.xml index f9cb29f0d7..12ee9b045b 100644 --- a/indra/newview/skins/default/xui/en/menu_cof_clothing.xml +++ b/indra/newview/skins/default/xui/en/menu_cof_clothing.xml @@ -8,6 +8,9 @@ name="take_off"> <on_click function="Clothing.TakeOff" /> + <on_enable + function="Clothing.OnEnable" + parameter="take_off" /> </menu_item_call> <menu_item_call label="Move Up a Layer" @@ -39,4 +42,15 @@ function="Clothing.OnEnable" parameter="edit" /> </menu_item_call> + <menu_item_call + label="Create New" + layout="topleft" + name="create_new" + translate="false"> + <on_click + function="Clothing.Create"/> + <on_enable + function="Clothing.OnEnable" + parameter="create" /> + </menu_item_call> </context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_cof_gear.xml b/indra/newview/skins/default/xui/en/menu_cof_gear.xml index 982d4f2015..c2a11a64ec 100644 --- a/indra/newview/skins/default/xui/en/menu_cof_gear.xml +++ b/indra/newview/skins/default/xui/en/menu_cof_gear.xml @@ -2,15 +2,12 @@ <menu layout="topleft" name="Gear COF"> - <menu_item_call - label="Add To Outfit" + <menu + label="New Clothes" layout="topleft" - name="add"> - <on_click - function="Gear.OnClick" - parameter="add"/> - <on_enable - function="Gear.OnEnable" - parameter="add" /> - </menu_item_call> + name="COF.Gear.New_Clothes" /> + <menu + label="New Body Parts" + layout="topleft" + name="COF.Geear.New_Body_Parts" /> </menu> diff --git a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml index dfc72b557c..b5eda8e999 100644 --- a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml +++ b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml @@ -7,31 +7,174 @@ layout="topleft" name="wear"> <on_click - function="Gear.OnClick" - parameter="wear"/> + function="Gear.Wear" /> <on_enable function="Gear.OnEnable" parameter="wear" /> </menu_item_call> <menu_item_call - label="Take Off - Remove Current Outfit" + label="Take Off - Remove from Current Outfit" layout="topleft" name="take_off"> <on_click - function="Gear.OnClick" - parameter="take_off"/> + function="Gear.TakeOff" /> <on_enable function="Gear.OnEnable" parameter="take_off" /> </menu_item_call> + + <menu_item_separator /> + <!-- copied (with minor modifications) from menu_inventory_add.xml --> + <!-- *TODO: generate dynamically? --> + <menu + height="175" + label="New Clothes" + layout="topleft" + left_delta="0" + mouse_opaque="false" + name="New Clothes" + top_pad="514" + width="125"> + <menu_item_call + label="New Shirt" + layout="topleft" + name="New Shirt"> + <menu_item_call.on_click + function="Gear.Create" + parameter="shirt" /> + </menu_item_call> + <menu_item_call + label="New Pants" + layout="topleft" + name="New Pants"> + <menu_item_call.on_click + function="Gear.Create" + parameter="pants" /> + </menu_item_call> + <menu_item_call + label="New Shoes" + layout="topleft" + name="New Shoes"> + <menu_item_call.on_click + function="Gear.Create" + parameter="shoes" /> + </menu_item_call> + <menu_item_call + label="New Socks" + layout="topleft" + name="New Socks"> + <menu_item_call.on_click + function="Gear.Create" + parameter="socks" /> + </menu_item_call> + <menu_item_call + label="New Jacket" + layout="topleft" + name="New Jacket"> + <menu_item_call.on_click + function="Gear.Create" + parameter="jacket" /> + </menu_item_call> + <menu_item_call + label="New Skirt" + layout="topleft" + name="New Skirt"> + <menu_item_call.on_click + function="Gear.Create" + parameter="skirt" /> + </menu_item_call> + <menu_item_call + label="New Gloves" + layout="topleft" + name="New Gloves"> + <menu_item_call.on_click + function="Gear.Create" + parameter="gloves" /> + </menu_item_call> + <menu_item_call + label="New Undershirt" + layout="topleft" + name="New Undershirt"> + <menu_item_call.on_click + function="Gear.Create" + parameter="undershirt" /> + </menu_item_call> + <menu_item_call + label="New Underpants" + layout="topleft" + name="New Underpants"> + <menu_item_call.on_click + function="Gear.Create" + parameter="underpants" /> + </menu_item_call> + <menu_item_call + label="New Alpha" + layout="topleft" + name="New Alpha"> + <menu_item_call.on_click + function="Gear.Create" + parameter="alpha" /> + </menu_item_call> + <menu_item_call + label="New Tattoo" + layout="topleft" + name="New Tattoo"> + <menu_item_call.on_click + function="Gear.Create" + parameter="tattoo" /> + </menu_item_call> + </menu> + <menu + height="85" + label="New Body Parts" + layout="topleft" + left_delta="0" + mouse_opaque="false" + name="New Body Parts" + top_pad="514" + width="118"> + <menu_item_call + label="New Shape" + layout="topleft" + name="New Shape"> + <menu_item_call.on_click + function="Gear.Create" + parameter="shape" /> + </menu_item_call> + <menu_item_call + label="New Skin" + layout="topleft" + name="New Skin"> + <menu_item_call.on_click + function="Gear.Create" + parameter="skin" /> + </menu_item_call> + <menu_item_call + label="New Hair" + layout="topleft" + name="New Hair"> + <menu_item_call.on_click + function="Gear.Create" + parameter="hair" /> + </menu_item_call> + <menu_item_call + label="New Eyes" + layout="topleft" + name="New Eyes"> + <menu_item_call.on_click + function="Gear.Create" + parameter="eyes" /> + </menu_item_call> + </menu> + <!-- copied from menu_inventory_add.xml --> + <menu_item_separator /> <menu_item_call label="Rename" layout="topleft" name="rename"> <on_click - function="Gear.OnClick" - parameter="rename"/> + function="Gear.Rename" /> <on_enable function="Gear.OnEnable" parameter="rename" /> @@ -41,10 +184,9 @@ layout="topleft" name="delete_outfit"> <on_click - function="Gear.OnClick" - parameter="delete_outfit"/> + function="Gear.Delete" /> <on_enable function="Gear.OnEnable" - parameter="delete_outfit" /> + parameter="delete" /> </menu_item_call> </menu> diff --git a/indra/newview/skins/default/xui/en/menu_outfit_tab.xml b/indra/newview/skins/default/xui/en/menu_outfit_tab.xml index 8f3e62157a..67559638d9 100644 --- a/indra/newview/skins/default/xui/en/menu_outfit_tab.xml +++ b/indra/newview/skins/default/xui/en/menu_outfit_tab.xml @@ -8,6 +8,9 @@ name="wear_replace"> <on_click function="Outfit.WearReplace" /> + <on_enable + function="Outfit.OnEnable" + parameter="wear_replace" /> </menu_item_call> <menu_item_call label="Wear - Add to Current Outfit" @@ -15,13 +18,29 @@ name="wear_add"> <on_click function="Outfit.WearAdd" /> + <on_enable + function="Outfit.OnEnable" + parameter="wear_add" /> </menu_item_call> <menu_item_call - label="Take Off - Remove Current Outfit" + label="Take Off - Remove from Current Outfit" layout="topleft" name="take_off"> <on_click function="Outfit.TakeOff" /> + <on_enable + function="Outfit.OnEnable" + parameter="take_off" /> + </menu_item_call> + <menu_item_call + label="Edit Outfit" + layout="topleft" + name="edit"> + <on_click + function="Outfit.Edit" /> + <on_enable + function="Outfit.OnEnable" + parameter="edit" /> </menu_item_call> <menu_item_separator /> <menu_item_call @@ -30,6 +49,9 @@ name="rename"> <on_click function="Outfit.Rename" /> + <on_enable + function="Outfit.OnEnable" + parameter="rename" /> </menu_item_call> <menu_item_call label="Delete Outfit" @@ -37,5 +59,8 @@ name="delete"> <on_click function="Outfit.Delete" /> + <on_enable + function="Outfit.OnEnable" + parameter="delete" /> </menu_item_call> </context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml index 7ea7eaade5..e645702f93 100644 --- a/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml +++ b/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml @@ -9,22 +9,27 @@ function="Wearable.Wear" /> </menu_item_call> <menu_item_call + label="Take Off / Detach" + layout="topleft" + name="take_off_or_detach"> + <on_click + function="Wearable.TakeOffDetach" /> + </menu_item_call> + <menu_item_call label="Detach" layout="topleft" name="detach"> <on_click function="Attachment.Detach" /> </menu_item_call> -<!-- *TODO: implement the submenus - <menu - label="Attach to" + <context_menu + label="Attach to ▶" layout="topleft" - name="attach_to" /> - <menu - label="Attach to HUD" + name="wearable_attach_to" /> + <context_menu + label="Attach to HUD ▶" layout="topleft" - name="attach_to_hud" /> ---> + name="wearable_attach_to_hud" /> <menu_item_call label="Object Profile" layout="topleft" @@ -37,16 +42,14 @@ layout="topleft" name="take_off"> <on_click - function="Clothing.TakeOff" - parameter="take_off"/> + function="Clothing.TakeOff" /> </menu_item_call> <menu_item_call label="Edit" layout="topleft" name="edit"> <on_click - function="Wearable.Edit" - parameter="edit"/> + function="Wearable.Edit" /> </menu_item_call> <menu_item_call label="Show Original" @@ -55,4 +58,12 @@ <on_click function="Wearable.ShowOriginal" /> </menu_item_call> + <menu_item_call + label="Create New" + layout="topleft" + name="create_new" + translate="false"> + <on_click + function="Wearable.CreateNew" /> + </menu_item_call> </context_menu> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 079d029eab..5ead756d20 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -1090,7 +1090,9 @@ The region [REGION] does not allow terraforming. icon="alertmodal.tga" name="CannotCopyWarning" type="alertmodal"> -You do not have permission to copy this item and will lose it from your inventory if you give it away. Do you really want to offer this item? +You do not have permission to copy the following items: +[ITEMS] +and will lose it from your inventory if you give it away. Do you really want to offer these items? <usetemplate name="okcancelbuttons" notext="No" @@ -2068,6 +2070,28 @@ Would you be my friend? <notification icon="alertmodal.tga" + label="Rename Outfit" + name="RenameOutfit" + type="alertmodal"> + New outfit name: + <form name="form"> + <input name="new_name" type="text"> + [NAME] + </input> + <button + default="true" + index="0" + name="Offer" + text="OK"/> + <button + index="1" + name="Cancel" + text="Cancel"/> + </form> + </notification> + + <notification + icon="alertmodal.tga" name="RemoveFromFriends" type="alertmodal"> Do you want to remove [FIRST_NAME] [LAST_NAME] from your Friends List? @@ -6120,6 +6144,28 @@ Drag items from inventory onto a person in the resident picker </notification> <notification icon="notifytip.tga" + name="ShareItemsConfirmation" + type="alertmodal"> +Are you sure you want to share the following items: + +[ITEMS] + +With the following Residents: + +[RESIDENTS] + <usetemplate + name="okcancelbuttons" + notext="Cancel" + yestext="Ok"/> + </notification> + <notification + icon="notifytip.tga" + name="ItemsShared" + type="notifytip"> +Items are successfully shared. + </notification> + <notification + icon="notifytip.tga" name="DeedToGroupFail" type="notifytip"> Deed to group failed. @@ -6263,8 +6309,8 @@ Mute everyone? <usetemplate ignoretext="Confirm before I mute all participants in a group call" name="okcancelignore" - notext="Ok" - yestext="Cancel"/> + yestext="Ok" + notext="Cancel"/> <unique/> </notification> diff --git a/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml index d3f6695375..1e6a31d388 100644 --- a/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml +++ b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml @@ -11,14 +11,16 @@ width="280"> <button follows="top|left" - height="25" - image_overlay="BackArrow_Off" + height="24" + image_hover_unselected="BackButton_Over" + image_pressed="BackButton_Press" + image_unselected="BackButton_Off" layout="topleft" name="back" - left="10" + left="4" tab_stop="false" - top="0" - width="25"/> + top="1" + width="30"/> <text follows="top|left|right" font="SansSerifLargeBold" diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml index ac61c7da5d..82b2405ec9 100644 --- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml +++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml @@ -222,38 +222,6 @@ min_height="28" min_width="52" mouse_opaque="false" - name="sidebar_btn_panel" - user_resize="false" - width="83"> -<!--*TODO: Implement toggle of sidebar with buttons -Disabled for now. ---> - <button - control_name="SidebarWithButtonsVisibility" - follows="left|right" - height="23" - image_pressed="PushButton_Press" - image_pressed_selected="PushButton_Selected_Press" - image_selected="PushButton_Selected_Press" - is_toggle="true" - label="Sidebar" - layout="topleft" - left="0" - name="sidebar_btn" - tool_tip="Shows/hides Sidebar" - top="5" - use_ellipses="true" - width="80"> - </button> - </layout_panel> - <layout_panel - auto_resize="false" - follows="left|right" - height="28" - layout="topleft" - min_height="28" - min_width="52" - mouse_opaque="false" name="build_btn_panel" user_resize="false" width="83"> diff --git a/indra/newview/skins/default/xui/en/panel_classified_info.xml b/indra/newview/skins/default/xui/en/panel_classified_info.xml index e3b331799c..859cc82e81 100644 --- a/indra/newview/skins/default/xui/en/panel_classified_info.xml +++ b/indra/newview/skins/default/xui/en/panel_classified_info.xml @@ -40,15 +40,17 @@ </panel.string> <button follows="top|right" - height="23" - image_overlay="BackArrow_Off" + height="24" + image_hover_unselected="BackButton_Over" + image_pressed="BackButton_Press" + image_unselected="BackButton_Off" layout="topleft" name="back_btn" picture_style="true" - left="11" + left="9" tab_stop="false" top="2" - width="23" /> + width="30" /> <text follows="top|left|right" font="SansSerifHugeBold" diff --git a/indra/newview/skins/default/xui/en/panel_cof_wearables.xml b/indra/newview/skins/default/xui/en/panel_cof_wearables.xml index cf84c31078..5f34c24bca 100644 --- a/indra/newview/skins/default/xui/en/panel_cof_wearables.xml +++ b/indra/newview/skins/default/xui/en/panel_cof_wearables.xml @@ -9,6 +9,7 @@ name="cof_wearables" width="311"> <accordion + fit_parent="true" follows="all" height="200" layout="topleft" @@ -38,73 +39,31 @@ layout="topleft" name="tab_clothing" title="Clothing"> - - <!-- *NOTE there should be no any gaps between the button bar and the list - - accordiong-list adaptor won't employ them while calculating new height when the size of the list changes --> - <panel - background_visible="false" - class="accordion_list_adaptor" + <flat_list_view + allow_select="true" follows="all" - height="45" + height="10" layout="topleft" left="0" - name="button_bar_adaptor" + multi_select="true" + name="list_clothing" top="0" - width="311"> - <panel - bevel="none" - filename="panel_clothing_list_button_bar.xml" - height="35" - name="button_bar" - top="0" - width="311" /> - <flat_list_view - allow_select="true" - follows="all" - height="10" - layout="topleft" - left="0" - multi_select="true" - name="list_clothing" - top_pad="0" - width="311" /> - </panel> + width="311" /> </accordion_tab> <accordion_tab layout="topleft" name="tab_body_parts" title="Body Parts"> - - <!-- *NOTE there should be no any gaps between the button bar and the list - - accordiong-list adaptor won't employ them while calculating new height when the size of the list changes --> - <panel - background_visible="false" - class="accordion_list_adaptor" + <flat_list_view + allow_select="true" follows="all" - height="45" + height="10" layout="topleft" left="0" - name="button_bar_adaptor" + multi_select="true" + name="list_body_parts" top="0" - width="311"> - <panel - bevel="none" - filename="panel_bodyparts_list_button_bar.xml" - height="35" - name="button_bar" - top="0" - width="311"/> - <flat_list_view - allow_select="true" - follows="all" - height="10" - layout="topleft" - left="0" - multi_select="true" - name="list_body_parts" - top_pad="0" - width="311" /> - </panel> + width="311" /> </accordion_tab> </accordion> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_edit_classified.xml b/indra/newview/skins/default/xui/en/panel_edit_classified.xml index 7383edf63d..1b4f547f9d 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_classified.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_classified.xml @@ -24,15 +24,17 @@ </string> <button follows="top|right" - height="23" - image_overlay="BackArrow_Off" + height="24" + image_hover_unselected="BackButton_Over" + image_pressed="BackButton_Press" + image_unselected="BackButton_Off" layout="topleft" name="back_btn" picture_style="true" - left="12" + left="7" tab_stop="false" top="2" - width="23" /> + width="30" /> <text type="string" length="1" diff --git a/indra/newview/skins/default/xui/en/panel_edit_eyes.xml b/indra/newview/skins/default/xui/en/panel_edit_eyes.xml index 4149a0b06f..f173a2f3cb 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_eyes.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_eyes.xml @@ -51,6 +51,7 @@ top_pad="10" width="313"> <accordion + fit_parent="true" follows="all" height ="300" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_edit_gloves.xml b/indra/newview/skins/default/xui/en/panel_edit_gloves.xml index 94fd2f9080..a490f27b9f 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_gloves.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_gloves.xml @@ -65,6 +65,7 @@ top_pad="10" width="313"> <accordion + fit_parent="true" follows="all" height ="300" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_edit_hair.xml b/indra/newview/skins/default/xui/en/panel_edit_hair.xml index 9b60e83387..6bb5d2fa9b 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_hair.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_hair.xml @@ -51,6 +51,7 @@ top_pad="10" width="313"> <accordion + fit_parent="true" follows="all" height ="300" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_edit_jacket.xml b/indra/newview/skins/default/xui/en/panel_edit_jacket.xml index 248ae9fe04..929cdffb3d 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_jacket.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_jacket.xml @@ -80,6 +80,7 @@ top_pad="10" width="313"> <accordion + fit_parent="true" follows="all" height ="300" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_edit_pants.xml b/indra/newview/skins/default/xui/en/panel_edit_pants.xml index 3ed1df2399..f22cf983aa 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_pants.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_pants.xml @@ -65,6 +65,7 @@ top_pad="10" width="313"> <accordion + fit_parent="true" follows="all" height ="300" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_edit_pick.xml b/indra/newview/skins/default/xui/en/panel_edit_pick.xml index 08ee0306dd..589ea10e8d 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_pick.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_pick.xml @@ -18,14 +18,16 @@ </panel.string> <button follows="top|right" - height="23" - image_overlay="BackArrow_Off" + height="24" + image_hover_unselected="BackButton_Over" + image_pressed="BackButton_Press" + image_unselected="BackButton_Off" layout="topleft" name="back_btn" - left="12" + left="7" tab_stop="false" top="2" - width="23" /> + width="30" /> <text type="string" length="1" diff --git a/indra/newview/skins/default/xui/en/panel_edit_shirt.xml b/indra/newview/skins/default/xui/en/panel_edit_shirt.xml index e088aa05ac..85823073b5 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_shirt.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_shirt.xml @@ -65,6 +65,7 @@ top_pad="10" width="313"> <accordion + fit_parent="true" follows="all" height ="300" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_edit_shoes.xml b/indra/newview/skins/default/xui/en/panel_edit_shoes.xml index e079047a86..b26fde68f1 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_shoes.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_shoes.xml @@ -65,6 +65,7 @@ top_pad="10" width="313"> <accordion + fit_parent="true" follows="all" height ="300" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_edit_skin.xml b/indra/newview/skins/default/xui/en/panel_edit_skin.xml index 9158685c40..45591ba2ad 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_skin.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_skin.xml @@ -85,6 +85,7 @@ width="313"> <accordion layout="topleft" + fit_parent="true" follows="all" height ="300" left="0" diff --git a/indra/newview/skins/default/xui/en/panel_edit_skirt.xml b/indra/newview/skins/default/xui/en/panel_edit_skirt.xml index 87f3270b31..bb8e0dca07 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_skirt.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_skirt.xml @@ -65,6 +65,7 @@ top_pad="10" width="313"> <accordion + fit_parent="true" follows="all" height ="300" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_edit_socks.xml b/indra/newview/skins/default/xui/en/panel_edit_socks.xml index 5bd99969a2..d813d94d93 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_socks.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_socks.xml @@ -65,6 +65,7 @@ top_pad="10" width="313"> <accordion + fit_parent="true" follows="all" height ="300" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_edit_underpants.xml b/indra/newview/skins/default/xui/en/panel_edit_underpants.xml index bbe5230341..19225e9757 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_underpants.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_underpants.xml @@ -65,6 +65,7 @@ top_pad="10" width="313"> <accordion + fit_parent="true" follows="all" height ="300" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_edit_undershirt.xml b/indra/newview/skins/default/xui/en/panel_edit_undershirt.xml index a79c1b9eaa..720a55dcc2 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_undershirt.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_undershirt.xml @@ -65,6 +65,7 @@ top_pad="10" width="313"> <accordion + fit_parent="true" follows="all" height ="300" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml index 0455086ef3..67ff71cef1 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml @@ -132,12 +132,14 @@ left="0" </string> <button follows="top|left" - height="25" - width="25" - image_overlay="BackArrow_Off" + height="24" + width="30" + image_hover_unselected="BackButton_Over" + image_pressed="BackButton_Press" + image_unselected="BackButton_Off" layout="topleft" name="back_btn" - left="10" + left="11" top="7" /> <text follows="top|left" diff --git a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml index 789d69bc68..58b78cfa02 100644 --- a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml +++ b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml @@ -36,14 +36,16 @@ background_visible="true" layout="topleft"> <button follows="top|right" - height="23" - image_overlay="BackArrow_Off" + height="24" + image_hover_unselected="BackButton_Over" + image_pressed="BackButton_Press" + image_unselected="BackButton_Off" layout="topleft" name="back" - left="8" + left="7" tab_stop="false" top="2" - width="23" /> + width="30" /> <text_editor allow_scroll="false" bg_visible="false" diff --git a/indra/newview/skins/default/xui/en/panel_landmark_info.xml b/indra/newview/skins/default/xui/en/panel_landmark_info.xml index 31ba539c44..25674a1a39 100644 --- a/indra/newview/skins/default/xui/en/panel_landmark_info.xml +++ b/indra/newview/skins/default/xui/en/panel_landmark_info.xml @@ -55,15 +55,17 @@ value="Parcel_R_Dark" /> <button follows="top|right" - height="23" - image_overlay="BackArrow_Off" + height="24" + image_hover_unselected="BackButton_Over" + image_pressed="BackButton_Press" + image_unselected="BackButton_Off" layout="topleft" - left="11" + left="8" name="back_btn" tool_tip="Back" tab_stop="false" top="4" - width="23" /> + width="30" /> <text follows="top|left|right" font="SansSerifHugeBold" diff --git a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml index abd96c89e7..2ff46637f1 100644 --- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml +++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml @@ -52,30 +52,19 @@ <string name="Filter.Clothes/Body" value="Clothes/Body"/> <string name="Filter.Objects" value="Objects"/> - <!-- - TODO remove this button. Added it temporary for QA to be able to test new edit wearable - panel (see EXT-6564) - --> - <button - follows="left|top|right" - height="20" - label="edit" - left="0" - top="0" - layout="topleft" - name="edit_wearable_btn" - width="40" /> - + <button follows="top|left" - height="23" - image_overlay="BackArrow_Off" + height="24" + image_hover_unselected="BackButton_Over" + image_pressed="BackButton_Press" + image_unselected="BackButton_Off" layout="topleft" name="back_btn" left="5" tab_stop="false" top="2" - width="23" /> + width="30" /> <text follows="top|right" font="SansSerifHugeBold" @@ -150,8 +139,8 @@ <!-- LIST OF WEARABLES (CURRENT OUTFIT/ WEARABLES TO ADD) --> -<!-- *NOTE: border_size is used to calculate space between layout panel and for resize bar height -required height for dragbar is 10, so resizebar height should be 10 px. +<!-- *NOTE: border_size is used to calculate space between layout panels and also to calculate resize bar's height. +Required height for dragbar (icon in spec) is 10, so resizebar height should be 10 px. It is calculated as border_size + 2*UIResizeBarOverlap --> <layout_stack @@ -160,7 +149,7 @@ It is calculated as border_size + 2*UIResizeBarOverlap clip="false" default_tab_group="2" follows="all" - height="468" + height="465" width="313" layout="topleft" orientation="vertical" @@ -170,7 +159,7 @@ It is calculated as border_size + 2*UIResizeBarOverlap left="5"> <layout_panel layout="topleft" - height="193" + height="187" label="IM Control Panel" min_height="100" name="outfit_wearables_panel" @@ -178,94 +167,89 @@ It is calculated as border_size + 2*UIResizeBarOverlap auto_resize="true" user_resize="true"> - <!-- List containing items from the COF and Base outfit --> - <panel - background_visible="false" - class="cof_wearables" - filename="panel_cof_wearables.xml" - follows="left|top|right|bottom" - height="193" - layout="topleft" - left="1" - name="cof_wearables_list" - top="0" - width="311" /> - </layout_panel> - - - <layout_panel - background_visible="true" - bg_alpha_color="DkGray2" - auto_resize="true" - default_tab_group="3" - height="184" - min_height="210" - name="add_wearables_panel" - width="313" - tab_group="2" - user_resize="true" - visible="false"> - <icon - follows="left|top|right" - height="10" - image_name="Dragbar" - left="0" - top_pad="-9" - width="313" /> - <text - follows="top|left|right" - font="SansSerifBold" - height="13" - layout="topleft" - left="5" - name="add_to_outfit_label" - text_color="LtGray" - top="4" - value="Add to Outfit:" - use_ellipses="true" - width="150" /> - <button - follows="top|right" - height="20" - image_overlay="Search_Icon" - is_toggle="true" - layout="topleft" - left_pad="5" - name="filter_button" - top_delta="0" - width="20" /> - <combo_box - follows="top|left|right" - height="20" - layout="topleft" - right="-5" - name="filter_wearables_combobox" - top_delta="0" - width="110"/> - <layout_stack animate="true" + border_size="0" follows="all" - height="155" + height="185" width="313" layout="topleft" name="filter_panels" - top_pad="5" + top="0" left="0"> <layout_panel - auto_resize="false" + auto_resize="true" + background_visible="true" + bg_alpha_color="DkGray2" layout="topleft" - follows="left|top|right" + height="154" + label="add_button_and_combobox" + name="add_button_and_combobox" + width="311" + user_resize="false" + visible="true"> + + <!-- List containing items from the COF and Base outfit --> + <panel + background_visible="false" + class="cof_wearables" + filename="panel_cof_wearables.xml" + follows="all" + height="129" + layout="topleft" + left="1" + name="cof_wearables_list" + top="0" + width="311" /> + + <button + follows="left|bottom" + height="22" + is_toggle="true" + label="Add More..." + layout="topleft" + left="2" + name="show_add_wearables_btn" + top_pad="2" + width="125" /> + + <combo_box + follows="left|right|bottom" + height="22" + layout="topleft" + left_pad="5" + name="filter_wearables_combobox" + top_delta="0" + visible="false" + width="152"/> + + <button + follows="bottom|right" + height="22" + image_overlay="Search_Icon" + is_toggle="true" + layout="topleft" + name="filter_button" + right="-5" + top_delta="0" + visible="false" + width="20" /> + </layout_panel> + + <layout_panel + auto_resize="false" + background_visible="true" + bg_alpha_color="DkGray2" height="30" - label="IM Control Panel" name="filter_panel" width="311" - user_resize="false" - visible="false"> + visible="false" + user_resize="false"> + <filter_editor background_image="TextField_Search_Off" enabled="true" - follows="left|top|right" + follows="left|right|top" font="SansSerif" label="Filter" layout="topleft" @@ -276,60 +260,114 @@ It is calculated as border_size + 2*UIResizeBarOverlap text_color="black" text_pad_left="25" visible="true"/> - </layout_panel> - <layout_panel - auto_resize="true" - background_visible="true" - bg_alpha_color="0.107 0.107 0.107 1" - height="145" - min_width="130" - name="inventory_panel" - width="311" - user_resize="true"> - <inventory_panel - allow_multi_select="true" - background_visible="false" - border="false" - follows="left|top|right|bottom" - height="140" - layout="topleft" - left="0" - mouse_opaque="false" - name="inventory_items" - top_pad="5" - width="310" - visible="false"/> - <panel - name="filtered_wearables_panel" - background_opaque="true" - background_visible="false" - layout="topleft" - follows="left|top|right|bottom" - border="false" - height="140" - left="0" - mouse_opaque="false" - width="311" - top_delta="0" - visible="true"> - <wearable_items_list - color="0.107 0.107 0.107 1" - name="filtered_wearables_list" - allow_select="true" - layout="topleft" - follows="all" - multi_select="true" - width="310" - height="140" - left="0" - top="0"/> - </panel> + </layout_panel> </layout_stack> - </layout_panel> + </layout_panel> + + + <layout_panel + background_visible="true" + bg_alpha_color="DkGray2" + auto_resize="true" + default_tab_group="3" + height="211" + min_height="210" + name="add_wearables_panel" + width="313" + tab_group="2" + user_resize="true" + visible="false"> + + <!-- this icon represent dragbar between layout panels. + This is a workaround implemented in EXT-7255 becouse of an issue with layout stack (EXT-7471) --> + <icon + follows="left|top|right" + height="10" + image_name="Dragbar" + left="0" + top_pad="-9" + width="313" /> + + <inventory_panel + allow_multi_select="true" + background_visible="false" + border="false" + follows="left|top|right|bottom" + height="210" + layout="topleft" + left="0" + mouse_opaque="false" + name="inventory_items" + top_pad="5" + width="310" + visible="false"/> + <panel + name="filtered_wearables_panel" + background_opaque="true" + background_visible="false" + layout="topleft" + follows="left|top|right|bottom" + border="false" + height="210" + left="0" + mouse_opaque="false" + width="311" + top_delta="0" + visible="true"> + <wearable_items_list + color="0.107 0.107 0.107 1" + name="filtered_wearables_list" + allow_select="true" + layout="topleft" + follows="all" + multi_select="true" + width="310" + height="210" + left="0" + top="0"/> + </panel> + + </layout_panel> </layout_stack> - <!-- Button bar --> + + <!-- BUTTON BAR --> + <panel + background_visible="true" + bevel_style="none" + follows="bottom|left|right" + height="27" + label="bottom_panel" + layout="topleft" + left="5" + name="no_add_wearables_button_bar" + top_pad="0" + width="313"> + <button + follows="bottom|left" + height="25" + image_hover_unselected="Toolbar_Left_Over" + image_overlay="OptionsMenu_Off" + image_selected="Toolbar_Left_Selected" + image_unselected="Toolbar_Left_Off" + layout="topleft" + left="0" + name="gear_menu_btn" + top="1" + width="31" /> + <icon + follows="bottom|left|right" + height="25" + image_name="Toolbar_Right_Off" + layout="topleft" + left_pad="1" + name="dummy_right_icon" + width="281" /> + </panel> + + + <!-- BUTTON BAR - WEARABLES ADDING MODE --> <panel background_visible="true" bevel_style="none" @@ -337,9 +375,10 @@ It is calculated as border_size + 2*UIResizeBarOverlap height="27" label="add_wearables_button_bar" layout="topleft" - left="4" + left="5" name="add_wearables_button_bar" - top_pad="0" + top_delta="0" + visible="false" width="313"> <button follows="bottom|left" @@ -365,7 +404,6 @@ It is calculated as border_size + 2*UIResizeBarOverlap left_pad="1" name="folder_view_btn" top="1" - visible="false" width="31" /> <button follows="bottom|left" @@ -379,7 +417,6 @@ It is calculated as border_size + 2*UIResizeBarOverlap left_pad="1" name="list_view_btn" top="1" - visible="false" width="31" /> <button follows="bottom|left" @@ -393,31 +430,19 @@ It is calculated as border_size + 2*UIResizeBarOverlap left_pad="1" name="add_to_outfit_btn" top="1" - visible="false" width="31" /> - <icon - follows="bottom|left|right" - height="25" - image_name="Toolbar_Right_Off" - layout="topleft" - left_pad="1" - name="add_wearables_dummy_icon" - top="1" - visible="false" - width="184" > - </icon> - <icon - follows="bottom|left|right" - height="25" - image_name="Toolbar_Right_Off" - layout="topleft" - left="32" - name="dummy_right_icon" - top="1" - width="281" > - </icon> + <icon + follows="bottom|left|right" + height="25" + image_name="Toolbar_Right_Off" + layout="topleft" + left_pad="1" + name="dummy_right_icon" + width="184" > + </icon> </panel> - + + <!-- SAVE AND REVERT BUTTONS --> <panel follows="left|right|bottom" height="30" diff --git a/indra/newview/skins/default/xui/en/panel_pick_info.xml b/indra/newview/skins/default/xui/en/panel_pick_info.xml index ecf5516390..49e1d16f6a 100644 --- a/indra/newview/skins/default/xui/en/panel_pick_info.xml +++ b/indra/newview/skins/default/xui/en/panel_pick_info.xml @@ -12,14 +12,16 @@ width="333"> <button follows="top|right" - height="23" - image_overlay="BackArrow_Off" + height="24" + image_hover_unselected="BackButton_Over" + image_pressed="BackButton_Press" + image_unselected="BackButton_Off" layout="topleft" name="back_btn" - left="12" + left="7" tab_stop="false" top="2" - width="23" /> + width="30" /> <text follows="top|left|right" font="SansSerifHugeBold" diff --git a/indra/newview/skins/default/xui/en/panel_place_profile.xml b/indra/newview/skins/default/xui/en/panel_place_profile.xml index 9725e9952a..57ac79686d 100644 --- a/indra/newview/skins/default/xui/en/panel_place_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_place_profile.xml @@ -140,15 +140,17 @@ value="Parcel_DamageNo_Dark" /> <button follows="top|right" - height="23" - image_overlay="BackArrow_Off" + height="24" + image_hover_unselected="BackButton_Over" + image_pressed="BackButton_Press" + image_unselected="BackButton_Off" layout="topleft" - left="11" + left="7" name="back_btn" tool_tip="Back" tab_stop="false" top="4" - width="23" /> + width="30" /> <text follows="top|left|right" font="SansSerifHugeBold" @@ -318,6 +320,7 @@ value="unknown" width="268" /> <accordion + fit_parent="true" follows="all" height="223" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_profile_view.xml b/indra/newview/skins/default/xui/en/panel_profile_view.xml index 5a96ba2dd2..cc5ba334d6 100644 --- a/indra/newview/skins/default/xui/en/panel_profile_view.xml +++ b/indra/newview/skins/default/xui/en/panel_profile_view.xml @@ -18,14 +18,16 @@ </string> <button follows="top|right" - height="23" - image_overlay="BackArrow_Off" + height="24" + image_hover_unselected="BackButton_Over" + image_pressed="BackButton_Press" + image_unselected="BackButton_Off" layout="topleft" name="back" - left="12" + left="9" tab_stop="false" top="2" - width="23" /> + width="30" /> <text_editor h_pad="0" v_pad="0" diff --git a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml index b840fdd31b..c816fd1479 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml @@ -40,14 +40,16 @@ width="18" /> <button follows="top|right" - height="23" - image_overlay="BackArrow_Off" + height="24" + image_hover_unselected="BackButton_Over" + image_pressed="BackButton_Press" + image_unselected="BackButton_Off" layout="topleft" - left="14" + left="12" name="back_btn" tab_stop="false" top="2" - width="23" /> + width="30" /> <text follows="top|left|right" font="SansSerifHugeBold" diff --git a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml index d46783e058..faa1ae4e8b 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml @@ -58,14 +58,16 @@ </panel.string> <button follows="top|right" - height="23" - image_overlay="BackArrow_Off" + height="24" + image_hover_unselected="BackButton_Over" + image_pressed="BackButton_Press" + image_unselected="BackButton_Off" layout="topleft" - left="10" + left="8" name="back_btn" tab_stop="false" top="0" - width="23" /> + width="30" /> <text follows="top|left|right" font="SansSerifHuge" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 51cf47b28f..ed6484302f 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -318,6 +318,10 @@ <!-- For use when we do not have land type back from the server --> <string name="land_type_unknown">(unknown)</string> + <!-- For land type back from the simulator --> + <string name="Estate / Full Region">Estate / Full Region</string> + <string name="Mainland / Full Region">Mainland / Full Region</string> + <!-- File load/save dialogs --> <string name="all_files">All Files</string> <string name="sound_files">Sounds</string> @@ -1826,6 +1830,7 @@ Clears (deletes) the media and all params from the given face. <!-- Wearable List--> <string name="NewWearable">New [WEARABLE_ITEM]</string> + <string name="CreateNewWearable">Create [WEARABLE_TYPE]</string> <!-- LLGroupNotify --> <!-- used in the construction of a Group Notice blue dialog box, buttons, tooltip etc. Seems to be no longer utilized by code in Viewer 2.0 --> @@ -3154,10 +3159,10 @@ Abuse Report</string> <string name="Male - Stick tougue out">Male - Stick tougue out</string> <string name="Male - Wow">Male - Wow</string> - <string name="FeMale - Excuse me">FeMale - Excuse me</string> - <string name="FeMale - Get lost">FeMale - Get lost</string> - <string name="FeMale - Blow kiss">FeMale - Blow kiss</string> - <string name="FeMale - Boo">FeMale - Boo</string> + <string name="Female - Excuse me">Female - Excuse me</string> + <string name="Female - Get lost">Female - Get lost</string> + <string name="Female - Blow kiss">Female - Blow kiss</string> + <string name="Female - Boo">Female - Boo</string> <string name="Female - Bored">Female - Bored</string> <string name="Female - Hey">Female - Hey</string> <string name="Female - Laugh">Female - Laugh</string> @@ -3174,6 +3179,7 @@ Abuse Report</string> <!-- language specific white-space characters, delimiters, spacers, item separation symbols --> <string name="sentences_separator" value=" "></string> + <string name="words_separator">, </string> <string name="server_is_down"> Despite our best efforts, something unexpected has gone wrong. diff --git a/indra/newview/skins/default/xui/en/widgets/tab_container.xml b/indra/newview/skins/default/xui/en/widgets/tab_container.xml index 30b0a8462a..c37ead0be2 100644 --- a/indra/newview/skins/default/xui/en/widgets/tab_container.xml +++ b/indra/newview/skins/default/xui/en/widgets/tab_container.xml @@ -11,31 +11,28 @@ label_pad_left - padding to the left of tab button labels tab_height="21" label_pad_bottom="2" label_pad_left="4"> + <!-- + Possible additional attributes for tabs: + tab_bottom_image_flash + tab_left_image_flash + tab_top_image_flash + --> <first_tab tab_top_image_unselected="TabTop_Left_Off" tab_top_image_selected="TabTop_Left_Selected" - tab_top_image_flash="FlashIconAbsent" tab_bottom_image_unselected="Toolbar_Left_Off" tab_bottom_image_selected="Toolbar_Left_Selected" - tab_bottom_image_flash="FlashIconAbsent" tab_left_image_unselected="SegmentedBtn_Left_Disabled" - tab_left_image_selected="SegmentedBtn_Left_Selected_Over" - tab_left_image_flash="FlashIconAbsent"/> + tab_left_image_selected="SegmentedBtn_Left_Selected_Over"/> <middle_tab tab_top_image_unselected="TabTop_Middle_Off" tab_top_image_selected="TabTop_Middle_Selected" - tab_top_image_flash="FlashIconAbsent" tab_bottom_image_unselected="Toolbar_Middle_Off" tab_bottom_image_selected="Toolbar_Middle_Selected" - tab_bottom_image_flash="FlashIconAbsent" tab_left_image_unselected="SegmentedBtn_Left_Disabled" - tab_left_image_selected="SegmentedBtn_Left_Selected_Over" - tab_left_image_flash="FlashIconAbsent"/> + tab_left_image_selected="SegmentedBtn_Left_Selected_Over"/> <last_tab tab_top_image_unselected="TabTop_Right_Off" tab_top_image_selected="TabTop_Right_Selected" - tab_top_image_flash="FlashIconAbsent" tab_bottom_image_unselected="Toolbar_Right_Off" tab_bottom_image_selected="Toolbar_Right_Selected" - tab_bottom_image_flash="FlashIconAbsent" tab_left_image_unselected="SegmentedBtn_Left_Disabled" - tab_left_image_selected="SegmentedBtn_Left_Selected_Over" - tab_left_image_flash="FlashIconAbsent"/> + tab_left_image_selected="SegmentedBtn_Left_Selected_Over"/> </tab_container> diff --git a/indra/newview/skins/default/xui/fr/panel_bodyparts_list_button_bar.xml b/indra/newview/skins/default/xui/fr/panel_bodyparts_list_button_bar.xml index afd9001df0..5e7442b877 100644 --- a/indra/newview/skins/default/xui/fr/panel_bodyparts_list_button_bar.xml +++ b/indra/newview/skins/default/xui/fr/panel_bodyparts_list_button_bar.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="clothing_list_button_bar_panel"> - <button label="Permuter" name="switch_btn"/> + <button label="Changer" name="switch_btn"/> <button label="Acheter >" name="bodyparts_shop_btn"/> </panel> diff --git a/indra/newview/skins/default/xui/fr/panel_clothing_list_button_bar.xml b/indra/newview/skins/default/xui/fr/panel_clothing_list_button_bar.xml index 24cb92dde7..0b58a4e40b 100644 --- a/indra/newview/skins/default/xui/fr/panel_clothing_list_button_bar.xml +++ b/indra/newview/skins/default/xui/fr/panel_clothing_list_button_bar.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="clothing_list_button_bar_panel"> - <button label="Ajouter +" name="add_btn"/> + <button label="Ajout +" name="add_btn"/> <button label="Acheter >" name="clothing_shop_btn"/> </panel> diff --git a/indra/newview/skins/default/xui/fr/panel_region_estate.xml b/indra/newview/skins/default/xui/fr/panel_region_estate.xml index 2c12547d61..fb650ff646 100644 --- a/indra/newview/skins/default/xui/fr/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/fr/panel_region_estate.xml @@ -73,6 +73,6 @@ domaine. <button label="?" name="ban_resident_help"/> <button label="Ajouter..." name="add_banned_avatar_btn"/> <button label="Supprimer..." name="remove_banned_avatar_btn"/> - <button label="Envoyer un message au domaine..." name="message_estate_btn"/> - <button label="Éjecter un résident du domaine..." name="kick_user_from_estate_btn"/> + <button label="Message au domaine..." name="message_estate_btn"/> + <button label="Éjecter du domaine..." name="kick_user_from_estate_btn"/> </panel> diff --git a/indra/newview/skins/default/xui/ja/notifications.xml b/indra/newview/skins/default/xui/ja/notifications.xml index 5d162eb80f..1ac7677b07 100644 --- a/indra/newview/skins/default/xui/ja/notifications.xml +++ b/indra/newview/skins/default/xui/ja/notifications.xml @@ -639,7 +639,7 @@ L$ が不足しているのでこのグループに参加することができ 次のファイルのエンコードができません: [FILE] </notification> <notification name="CorruptedProtectedDataStore"> - あなたの保護されたデータを読みとることが出来ないためリセットされます。 + 保護されているデータを読みとることが出来ないためリセットされます。 ネットワーク設定を変更すると起こることがあります。 <usetemplate name="okbutton" yestext="OK"/> </notification> diff --git a/indra/newview/skins/default/xui/pl/floater_about_land.xml b/indra/newview/skins/default/xui/pl/floater_about_land.xml index e4908deb07..163868f200 100644 --- a/indra/newview/skins/default/xui/pl/floater_about_land.xml +++ b/indra/newview/skins/default/xui/pl/floater_about_land.xml @@ -196,13 +196,13 @@ Idź do Świat > O Posiadłości albo wybierz inną posiadłość żeby pokaz <text name="resellable_lbl"> Odsprzedaj: </text> - <text left="115" name="resellable_clause" width="338"> + <text left="115" name="resellable_clause"> Posiadłość zakupiona w tym Regionie nie może być odsprzedana. </text> <text name="changeable_lbl"> Podziel: </text> - <text left="115" name="changeable_clause" width="338"> + <text left="115" name="changeable_clause"> Posiadłość zakupiona w tym Regionie nie może być łączona/dzielona. </text> |