diff --git a/autobuild.xml b/autobuild.xml index 9c114ef0b..5cbedba89 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -802,7 +802,7 @@ fmodstudio copyright - FMOD Studio, copyright (c) Firelight Technologies Pty, Ltd., 2012-2017. + FMOD Studio, copyright (c) Firelight Technologies Pty, Ltd., 2012-2019. description FMOD Studio audio system library license @@ -818,15 +818,29 @@ archive hash - d1ede6c7be5db022897b44830cb5b095 + 4a4e1bfd0e1e982643e75533ead10c55 hash_algorithm md5 url - https://bitbucket.org/SingularityViewer/libraries/downloads/fmodstudio-2.00.02.191841858-darwin64-191841858.tar.bz2 + https://pkg.alchemyviewer.org/repository/autobuild-internal/fmodstudio/darwin/fmodstudio-2.00.03.192211300-darwin-192211300.tar.bz2 name darwin + darwin64 + + archive + + hash + fe1a606582fb72d5d1c9ec4a2d906830 + hash_algorithm + md5 + url + https://pkg.alchemyviewer.org/repository/autobuild-internal/fmodstudio/darwin64/fmodstudio-2.00.03.192211302-darwin64-192211302.tar.bz2 + + name + darwin64 + linux archive @@ -836,7 +850,7 @@ hash_algorithm md5 url - http://depot.alchemyviewer.org/pub/linux/lib/fmodstudio-1.06.07-linux-201507231333.tar.bz2 + https://depot.alchemyviewer.org/pub/linux/lib/fmodstudio-1.06.07-linux-201507231333.tar.bz2 name linux @@ -846,11 +860,11 @@ archive hash - 602e798cc969f2d46315775f1dd43c41 + 54dbd41322a08a1fc333ca6d96af5502 hash_algorithm md5 url - https://bitbucket.org/SingularityViewer/libraries/downloads/fmodstudio-2.00.02.191991250-linux64-191991250.tar.bz2 + /opt/devel/secondlife/pkg/fmodstudio-2.00.02.191991250-linux64-191991250.tar.bz2 name linux64 @@ -860,11 +874,11 @@ archive hash - 2e18d5c43fad15d869dd96860f1e1871 + e0e87e0423fa42e4d2997b47b92eac6e hash_algorithm md5 url - https://bitbucket.org/SingularityViewer/libraries/downloads/fmodstudio-2.00.02-windows-191832253.tar.bz2 + https://pkg.alchemyviewer.org/repository/autobuild-internal/fmodstudio/windows/fmodstudio-2.00.03.192211030-windows-192211030.tar.bz2 name windows @@ -874,11 +888,11 @@ archive hash - 6146c96719680c2f1a8aaab1dabdef8e + c2e55e1bfef7e066a0e40867a64b4cce hash_algorithm md5 url - https://bitbucket.org/SingularityViewer/libraries/downloads/fmodstudio-2.00.02-windows64-191832321.tar.bz2 + https://pkg.alchemyviewer.org/repository/autobuild-internal/fmodstudio/windows64/fmodstudio-2.00.03.192211029-windows64-192211029.tar.bz2 name windows64 diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index b0572a070..f1999410c 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -436,20 +436,67 @@ class ContextUrl : public LLMemberListener } }; -class ContextUrlCopy : public LLMemberListener +class ContextIDUrl : public LLMemberListener { - - bool handleEvent(LLPointer, const LLSD& userdata) override +protected: + std::string getID(const std::string& type) const { const auto& url = get_focused_url(); - const auto& type = userdata.asStringRef(); // Empty works like avatar and group, "object" is an object (you needed to be told this) - const auto& id = type.empty() ? LLUrlAction::getUserID(url) : LLUrlAction::getObjectId(url); - LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(id)); + return type.empty() ? LLUrlAction::getUserID(url) : LLUrlAction::getObjectId(url); + } +}; + +class ContextUrlCopy : public ContextIDUrl +{ + bool handleEvent(LLPointer, const LLSD& userdata) override + { + LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(getID(userdata.asStringRef()))); return true; } }; +class ContextUrlExt : public ContextIDUrl +{ + bool handleEvent(LLPointer, const LLSD& userdata) override + { + std::string cmd = userdata.asStringRef(); + std::string type; + const auto sep = cmd.find(','); + if (sep != std::string::npos) + { + type = cmd.substr(sep); + cmd = cmd.substr(0, sep); + } + mExtCallback(cmd, LLUUID(getID(type))); + return true; + } + LLTextEditor::ext_slurl_cb mExtCallback; +public: + ContextUrlExt(LLTextEditor::ext_slurl_cb cb) : mExtCallback(cb) {} +}; + +class ContextUrlExtVisible : public ContextIDUrl +{ + bool handleEvent(LLPointer, const LLSD& userdata) override + { + std::string cmd = userdata["data"]; + std::string type; + const auto sep = cmd.find(','); + if (sep != std::string::npos) + { + type = cmd.substr(sep); + cmd = cmd.substr(0, sep); + } + + LLMenuGL::sMenuContainer->findControl(userdata["control"].asString())->setValue(mExtVCB(cmd, LLUUID(getID(type)))); + return true; + } + LLTextEditor::ext_slurl_visible_cb mExtVCB; +public: + ContextUrlExtVisible(LLTextEditor::ext_slurl_visible_cb vcb) : mExtVCB(vcb) {} +}; + void LLTextEditor::spell_correct(void* data) { @@ -528,11 +575,13 @@ void LLTextEditor::spell_add(void* data) } //static -void LLTextEditor::addMenuListeners() +void LLTextEditor::addMenuListeners(ext_slurl_cb cb, ext_slurl_visible_cb vcb) { (new ContextText)->registerListener(LLMenuGL::sMenuContainer, "Text"); (new ContextUrl)->registerListener(LLMenuGL::sMenuContainer, "Text.Url"); (new ContextUrlCopy)->registerListener(LLMenuGL::sMenuContainer, "Text.Url.CopyUUID"); + (new ContextUrlExt(cb))->registerListener(LLMenuGL::sMenuContainer, "Text.Url.Ext"); + (new ContextUrlExtVisible(vcb))->registerListener(LLMenuGL::sMenuContainer, "Text.Url.ExtVisible"); } void LLTextEditor::setTrackColor( const LLColor4& color ) @@ -721,8 +770,8 @@ LLMenuGL* LLTextEditor::createUrlContextMenu(S32 x, S32 y, const std::string &in if (addFriendButton && removeFriendButton) { - addFriendButton->setEnabled(!isFriend); - removeFriendButton->setEnabled(isFriend); + addFriendButton->setVisible(!isFriend); + removeFriendButton->setVisible(isFriend); } } diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index c8a67fdbd..b5d3eb699 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -80,7 +80,11 @@ public: static boost::signals2::connection setIsFriendCallback(const is_friend_signal_t::slot_type& cb); static boost::signals2::connection setIsObjectBlockedCallback(const is_blocked_signal_t::slot_type& cb); - static void addMenuListeners(); + + typedef std::function ext_slurl_cb; + typedef std::function ext_slurl_visible_cb; + static void addMenuListeners(ext_slurl_cb cb, ext_slurl_visible_cb vcb); + void setKeystrokeCallback(const keystroke_signal_t::slot_type& callback); virtual LLXMLNodePtr getXML(bool save_children = true) const; diff --git a/indra/newview/llfloateravatarlist.cpp b/indra/newview/llfloateravatarlist.cpp index 1a9636a44..51122e51b 100644 --- a/indra/newview/llfloateravatarlist.cpp +++ b/indra/newview/llfloateravatarlist.cpp @@ -312,6 +312,42 @@ BOOL LLFloaterAvatarList::handleRightMouseDown(S32 x, S32 y, MASK mask) return LLFloater::handleRightMouseDown(x, y, mask); } +bool is_nearby(const LLUUID& id) +{ + if (id.isNull()) return false; + if (const auto inst = LLFloaterAvatarList::getIfExists()) + return inst->getAvatarEntry(id); + uuid_vec_t avatars; + LLWorld::instance().getAvatars(&avatars); + return std::find(avatars.begin(), avatars.end(), id) != avatars.end(); +} + +void track_av(const LLUUID& id) +{ + if (auto inst = LLFloaterAvatarList::getIfExists()) + if (inst->getAvatarEntry(id)) + { + inst->trackAvatar(id); + return; + } + + LLWorld::pos_map_t avatars; + LLWorld::instance().getAvatars(&avatars); + LLTracker::trackLocation(avatars[id], LLStringUtil::null, LLStringUtil::null); +} + +void teleport_to(const LLUUID& id) +{ + if (auto entry = LLFloaterAvatarList::instanceExists() ? LLFloaterAvatarList::instance().getAvatarEntry(id) : nullptr) + gAgent.teleportViaLocation(entry->getPosition()); + else + { + LLWorld::pos_map_t avatars; + LLWorld::instance().getAvatars(&avatars); + gAgent.teleportViaLocation(avatars[id]); + } +} + static void cmd_profile(const LLAvatarListEntry* entry); static void cmd_toggle_mark(LLAvatarListEntry* entry); static void cmd_ar(const LLAvatarListEntry* entry); @@ -369,7 +405,7 @@ namespace { bool handleEvent(LLPointer event, const LLSD& userdata) { - LLFloaterAvatarList::instance().doCommand(cmd_teleport, true); + teleport_to(get_focused_list_id_selected()); return true; } }; @@ -388,13 +424,13 @@ void addMenu(view_listener_t* menu, const std::string& name); void add_radar_listeners() { - addMenu(new RadarTrack(), "Radar.Track"); - addMenu(new RadarMark(), "Radar.Mark"); - addMenu(new RadarFocus(), "Radar.Focus"); - addMenu(new RadarFocusPrev(), "Radar.FocusPrev"); - addMenu(new RadarFocusNext(), "Radar.FocusNext"); - addMenu(new RadarTeleportTo(), "Radar.TeleportTo"); - addMenu(new RadarAnnounceKeys(), "Radar.AnnounceKeys"); + addMenu(new RadarTrack, "Radar.Track"); + addMenu(new RadarMark, "Radar.Mark"); + addMenu(new RadarFocus, "Radar.Focus"); + addMenu(new RadarFocusPrev, "Radar.FocusPrev"); + addMenu(new RadarFocusNext, "Radar.FocusNext"); + addMenu(new RadarTeleportTo, "Radar.TeleportTo"); + addMenu(new RadarAnnounceKeys, "Radar.AnnounceKeys"); } BOOL LLFloaterAvatarList::postBuild() @@ -1099,8 +1135,11 @@ void LLFloaterAvatarList::onClickTrack() LLScrollListItem* item = mAvatarList->getFirstSelected(); if (!item) return; - LLUUID agent_id = item->getUUID(); + trackAvatar(item->getUUID()); +} +void LLFloaterAvatarList::trackAvatar(const LLUUID& agent_id) +{ if (mTracking && mTrackedAvatar == agent_id) { LLTracker::stopTracking(false); diff --git a/indra/newview/llfloateravatarlist.h b/indra/newview/llfloateravatarlist.h index 233eb4618..480e52f52 100644 --- a/indra/newview/llfloateravatarlist.h +++ b/indra/newview/llfloateravatarlist.h @@ -266,6 +266,7 @@ public: void focusOnNext(bool marked_only); void refreshTracker(); + void trackAvatar(const LLUUID& agent_id); void trackAvatar(const LLAvatarListEntry* entry) const; /** diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index b82d26c36..a494a025d 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -63,6 +63,7 @@ #include "lldebugview.h" #include "llenvmanager.h" #include "llfirstuse.h" +#include "llfloateravatarlist.h" #include "llfloateravatartextures.h" #include "llfloaterbuy.h" #include "llfloaterbuycontents.h" @@ -9255,11 +9256,16 @@ class ListShare : public view_listener_t } }; +bool can_show_web_profile() +{ + return !gSavedSettings.getString("WebProfileURL").empty(); +} + +void show_log_browser(const LLUUID& id); class ListShowLog : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - void show_log_browser(const LLUUID& id); for (const LLUUID& id : get_focused_list_ids_selected()) show_log_browser(id); return true; @@ -9347,24 +9353,50 @@ void parcel_mod_notice_callback(const uuid_vec_t& ids, S32 choice, boost::functi cb(*it, choice); } +bool is_nearby(const LLUUID& id); +class ListIsNearby : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + gMenuHolder->findControl(userdata["control"].asString())->setValue(is_nearby(get_focused_list_id_selected())); + return true; + } +}; + +void track_av(const LLUUID& id); +class ListTrack : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + track_av(get_focused_list_id_selected()); + return true; + } +}; + void send_eject(const LLUUID& avatar_id, bool ban); +void confirm_eject(const uuid_vec_t& ids) +{ + LLNotificationsUtil::add("EjectAvatarFullname", create_args(ids, "AVATAR_NAME"), LLSD(), boost::bind(parcel_mod_notice_callback, ids, boost::bind(LLNotificationsUtil::getSelectedOption, _1, _2), send_eject)); +} class ListEject : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - const uuid_vec_t& ids = get_focused_list_ids_selected(); - LLNotificationsUtil::add("EjectAvatarFullname", create_args(ids, "AVATAR_NAME"), LLSD(), boost::bind(parcel_mod_notice_callback, ids, boost::bind(LLNotificationsUtil::getSelectedOption, _1, _2), send_eject)); + confirm_eject(get_focused_list_ids_selected()); return true; } }; void send_freeze(const LLUUID& avatar_id, bool freeze); +void confirm_freeze(const uuid_vec_t& ids) +{ + LLNotificationsUtil::add("FreezeAvatarFullname", create_args(ids, "AVATAR_NAME"), LLSD(), boost::bind(parcel_mod_notice_callback, ids, boost::bind(LLNotificationsUtil::getSelectedOption, _1, _2), send_freeze)); +} class ListFreeze : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - const uuid_vec_t& ids = get_focused_list_ids_selected(); - LLNotificationsUtil::add("FreezeAvatarFullname", create_args(ids, "AVATAR_NAME"), LLSD(), boost::bind(parcel_mod_notice_callback, ids, boost::bind(LLNotificationsUtil::getSelectedOption, _1, _2), send_freeze)); + confirm_freeze(get_focused_list_ids_selected()); return true; } }; @@ -9395,22 +9427,28 @@ void estate_bulk_eject(const uuid_vec_t& ids, bool ban, S32 option) if (!tphome) send_estate_message("kickestate", strings); } +void confirm_estate_ban(const uuid_vec_t& ids) +{ + LLNotificationsUtil::add("EstateBanUser", create_args(ids, "EVIL_USER"), LLSD(), boost::bind(estate_bulk_eject, ids, true, boost::bind(LLNotificationsUtil::getSelectedOption, _1, _2))); +} class ListEstateBan : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - const uuid_vec_t& ids = get_focused_list_ids_selected(); - LLNotificationsUtil::add("EstateBanUser", create_args(ids, "EVIL_USER"), LLSD(), boost::bind(estate_bulk_eject, ids, true, boost::bind(LLNotificationsUtil::getSelectedOption, _1, _2))); + confirm_estate_ban(get_focused_list_ids_selected()); return true; } }; +void confirm_estate_kick(const uuid_vec_t& ids) +{ + LLNotificationsUtil::add("EstateKickUser", create_args(ids, "EVIL_USER"), LLSD(), boost::bind(estate_bulk_eject, ids, false, boost::bind(LLNotificationsUtil::getSelectedOption, _1, _2))); +} class ListEstateEject : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - const uuid_vec_t& ids = get_focused_list_ids_selected(); - LLNotificationsUtil::add("EstateKickUser", create_args(ids, "EVIL_USER"), LLSD(), boost::bind(estate_bulk_eject, ids, false, boost::bind(LLNotificationsUtil::getSelectedOption, _1, _2))); + confirm_estate_kick(get_focused_list_ids_selected()); return true; } }; @@ -9426,6 +9464,59 @@ class ListToggleMute : public view_listener_t } }; +struct MenuSLURLDict : public LLSingleton +{ + typedef std::function cb; + typedef std::function vcb; + typedef std::map> slurl_menu_map; + slurl_menu_map mEntries; + MenuSLURLDict() + { + // Text Editor menus + LLTextEditor::setIsObjectBlockedCallback(boost::bind(&LLMuteList::isMuted, LLMuteList::getInstance(), _1, _2, 0)); + LLTextEditor::setIsFriendCallback(LLAvatarActions::isFriend); + LLTextEditor::addMenuListeners(boost::bind(&MenuSLURLDict::action, this, _1, _2), boost::bind(&MenuSLURLDict::visible, this, _1, _2)); + + // Add the entries + insert("ShowWebProfile", boost::bind(LLAvatarActions::showProfile, _1, true), boost::bind(can_show_web_profile)); + insert("Pay", LLAvatarActions::pay); + insert("Call", LLAvatarActions::startCall); + insert("Share", LLAvatarActions::share); + insert("AbuseReport", LLFloaterReporter::showFromObject); + insert("InviteToGroup", [](const LLUUID& id) { LLAvatarActions::inviteToGroup(id); }); + insert("BanFromGroup", [](const LLUUID& id) { ban_from_group(uuid_vec_t(1, id)); }); + insert("ShowLog", [](const LLUUID& id) { show_log_browser(id); }); + insert("OfferTeleport", [](const LLUUID& id) { LLAvatarActions::offerTeleport(id); }, [](const LLUUID& id) { return LLAvatarActions::canOfferTeleport(id); }); + insert("RequestTeleport", LLAvatarActions::teleportRequest); + void teleport_to(const LLUUID& id); + insert("TeleportTo", teleport_to, is_nearby); + insert("Focus", LLFloaterAvatarList::setFocusAvatar, is_nearby); + insert("ParcelEject", [](const LLUUID& id) { confirm_eject(uuid_vec_t(1, id)); }, is_nearby); + insert("Freeze", [](const LLUUID& id) { confirm_freeze(uuid_vec_t(1, id)); }, is_nearby); + insert("EstateBan", [](const LLUUID& id) { confirm_estate_ban(uuid_vec_t(1, id)); }, is_nearby); + insert("EstateEject", [](const LLUUID & id) { confirm_estate_kick(uuid_vec_t(1, id)); }, is_nearby); + insert("Mute", LLAvatarActions::toggleBlock, [](const LLUUID& id) { return LLAvatarActions::canBlock(id) && !LLAvatarActions::isBlocked(id); }); + insert("Unmute", LLAvatarActions::toggleBlock, LLAvatarActions::isBlocked); + } + + void insert(const std::string& key, cb callback, vcb vcallback = nullptr) + { + mEntries[key] = std::make_pair(callback, vcallback); + } + + void action(const std::string& cmd, LLUUID id) const + { + auto it = mEntries.find(cmd); + if (it != mEntries.end()) + (*it).second.first(id); + } + bool visible(const std::string& cmd, LLUUID id) const + { + auto it = mEntries.find(cmd); + return it == mEntries.end() || !(*it).second.second || (*it).second.second(id); + } +}; + LLMediaCtrl* get_focused_media_ctrl() { auto media_ctrl = dynamic_cast(gFocusMgr.getKeyboardFocus()); @@ -9807,6 +9898,8 @@ void initialize_menus() addMenu(new ListStartConference(), "List.StartConference"); addMenu(new ListStartIM(), "List.StartIM"); addMenu(new ListAbuseReport(), "List.AbuseReport"); + addMenu(new ListIsNearby, "List.IsNearby"); + addMenu(new ListTrack, "List.Track"); addMenu(new ListEject(), "List.ParcelEject"); addMenu(new ListFreeze(), "List.Freeze"); addMenu(new ListEstateBan(), "List.EstateBan"); @@ -9815,10 +9908,7 @@ void initialize_menus() add_radar_listeners(); - // Text Editor menus - LLTextEditor::setIsObjectBlockedCallback(boost::bind(&LLMuteList::isMuted, LLMuteList::getInstance(), _1, _2, 0)); - LLTextEditor::setIsFriendCallback(LLAvatarActions::isFriend); - LLTextEditor::addMenuListeners(); + MenuSLURLDict::getInstance(); // Media Ctrl menus addMenu(new MediaCtrlCopyURL(), "Copy.PageURL"); diff --git a/indra/newview/skins/default/xui/en-us/floater_active_speakers.xml b/indra/newview/skins/default/xui/en-us/floater_active_speakers.xml index 9a6bf7117..f90862e9f 100644 --- a/indra/newview/skins/default/xui/en-us/floater_active_speakers.xml +++ b/indra/newview/skins/default/xui/en-us/floater_active_speakers.xml @@ -6,13 +6,13 @@ - - + diff --git a/indra/newview/skins/default/xui/en-us/menu_avs_list.xml b/indra/newview/skins/default/xui/en-us/menu_avs_list.xml index 1e66307c2..acec8e1b8 100644 --- a/indra/newview/skins/default/xui/en-us/menu_avs_list.xml +++ b/indra/newview/skins/default/xui/en-us/menu_avs_list.xml @@ -4,82 +4,118 @@ - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/en-us/menu_local_avs.xml b/indra/newview/skins/default/xui/en-us/menu_local_avs.xml index 2db0e2275..49c076252 100644 --- a/indra/newview/skins/default/xui/en-us/menu_local_avs.xml +++ b/indra/newview/skins/default/xui/en-us/menu_local_avs.xml @@ -1,10 +1,10 @@ + + + + - - - - @@ -49,7 +49,7 @@ - + @@ -66,9 +66,10 @@ - + + diff --git a/indra/newview/skins/default/xui/en-us/menu_url_agent.xml b/indra/newview/skins/default/xui/en-us/menu_url_agent.xml index f9403282e..a6eb22eca 100644 --- a/indra/newview/skins/default/xui/en-us/menu_url_agent.xml +++ b/indra/newview/skins/default/xui/en-us/menu_url_agent.xml @@ -2,20 +2,25 @@ - - + name="Url Popup"> + + + + + + - - + + + + + + + + + + + - - - + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/en-us/menu_url_agent_mini.xml b/indra/newview/skins/default/xui/en-us/menu_url_agent_mini.xml index ba3c272d7..bbddfcce3 100644 --- a/indra/newview/skins/default/xui/en-us/menu_url_agent_mini.xml +++ b/indra/newview/skins/default/xui/en-us/menu_url_agent_mini.xml @@ -1,15 +1,74 @@ - - + layout="topleft" + label="User" + name="Url Mini Popup"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/en-us/panel_speaker_controls.xml b/indra/newview/skins/default/xui/en-us/panel_speaker_controls.xml index 14b998f55..7a876e900 100644 --- a/indra/newview/skins/default/xui/en-us/panel_speaker_controls.xml +++ b/indra/newview/skins/default/xui/en-us/panel_speaker_controls.xml @@ -9,11 +9,11 @@ - + - +