diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 219fe0473..20c53ca42 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -1740,6 +1740,7 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask) if (col->mHeader && col->mHeader->getRect().pointInRect(x,y)) // Right clicking a column header shouldn't bring up a menu return FALSE; } + gFocusMgr.setKeyboardFocus(this); // Menu listeners rely on this mPopupMenu->buildDrawLabels(); LLMenuGL::showPopup(this, mPopupMenu, x, y); return TRUE; diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 412fc1f36..3ec2295b5 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -696,6 +696,17 @@ Value 0 + LiruLegacyLandmarks + + Comment + When creating a new landmark, the legacy format (parcel name, region name (x, y, z)) will be used. + Persist + 1 + Type + Boolean + Value + 1 + LiruLegacyOutfitStoreObjChanges Comment diff --git a/indra/newview/app_settings/settings_ascent.xml b/indra/newview/app_settings/settings_ascent.xml index c71094880..dc4a0498d 100644 --- a/indra/newview/app_settings/settings_ascent.xml +++ b/indra/newview/app_settings/settings_ascent.xml @@ -598,6 +598,17 @@ Value /away + SinguCmdLineURL + + Comment + Open SLURLS and URLs from chatbar. + Persist + 1 + Type + String + Value + /open + SinguCompleteNameProfiles Comment @@ -609,6 +620,17 @@ Value 0 + SinguMotionResetsCamera + + Comment + Allow camera to reset when moving. + Persist + 1 + Type + Boolean + Value + 1 + UseWebProfiles Comment diff --git a/indra/newview/ascentprefssys.cpp b/indra/newview/ascentprefssys.cpp index aaafd84ae..d4d25fcbc 100644 --- a/indra/newview/ascentprefssys.cpp +++ b/indra/newview/ascentprefssys.cpp @@ -74,6 +74,7 @@ LLPrefsAscentSys::LLPrefsAscentSys() getChild("AscentCmdLineMapTo")->setCommitCallback(boost::bind(&LLPrefsAscentSys::onCommitCmdLine, this, _1, _2)); getChild("AscentCmdLineTP2")->setCommitCallback(boost::bind(&LLPrefsAscentSys::onCommitCmdLine, this, _1, _2)); getChild("SinguCmdLineAway")->setCommitCallback(boost::bind(&LLPrefsAscentSys::onCommitCmdLine, this, _1, _2)); + getChild("SinguCmdLineURL")->setCommitCallback(boost::bind(&LLPrefsAscentSys::onCommitCmdLine, this, _1, _2)); //Security ---------------------------------------------------------------------------- getChild("disable_click_sit_check")->setCommitCallback(boost::bind(&LLPrefsAscentSys::onCommitCheckBox, this, _1, _2)); @@ -179,6 +180,7 @@ void LLPrefsAscentSys::onCommitCmdLine(LLUICtrl* ctrl, const LLSD& value) childSetEnabled("map_to_keep_pos", enabled); childSetEnabled("AscentCmdLineTP2", enabled); childSetEnabled("SinguCmdLineAway", enabled); + childSetEnabled("SinguCmdLineURL", enabled); } else { @@ -240,6 +242,7 @@ void LLPrefsAscentSys::refreshValues() mCmdMapToKeepPos = gSavedSettings.getBOOL("AscentMapToKeepPos"); mCmdLineTP2 = gSavedSettings.getString("AscentCmdLineTP2"); mCmdLineAway = gSavedSettings.getString("SinguCmdLineAway"); + mCmdLineURL = gSavedSettings.getString("SinguCmdLineURL"); //Security ---------------------------------------------------------------------------- mBroadcastViewerEffects = gSavedSettings.getBOOL("BroadcastViewerEffects"); @@ -314,6 +317,7 @@ void LLPrefsAscentSys::refresh() childSetEnabled("map_to_keep_pos", mCmdLine); childSetEnabled("AscentCmdLineTP2", mCmdLine); childSetEnabled("SinguCmdLineAway", mCmdLine); + childSetEnabled("SinguCmdLineURL", mCmdLine); //Security ---------------------------------------------------------------------------- childSetValue("AscentCmdLinePos", mCmdLinePos); @@ -330,6 +334,7 @@ void LLPrefsAscentSys::refresh() childSetValue("AscentCmdLineMapTo", mCmdLineMapTo); childSetValue("AscentCmdLineTP2", mCmdLineTP2); childSetValue("SinguCmdLineAway", mCmdLineAway); + childSetValue("SinguCmdLineURL", mCmdLineURL); //Build ------------------------------------------------------------------------------- childSetValue("alpha", mAlpha); @@ -392,6 +397,7 @@ void LLPrefsAscentSys::cancel() gSavedSettings.setBOOL("AscentMapToKeepPos", mCmdMapToKeepPos); gSavedSettings.setString("AscentCmdLineTP2", mCmdLineTP2); gSavedSettings.setString("SinguCmdLineAway", mCmdLineAway); + gSavedSettings.setString("SinguCmdLineURL", mCmdLineURL); //Security ---------------------------------------------------------------------------- gSavedSettings.setBOOL("BroadcastViewerEffects", mBroadcastViewerEffects); diff --git a/indra/newview/ascentprefssys.h b/indra/newview/ascentprefssys.h index 7e60d42c9..701a8e582 100644 --- a/indra/newview/ascentprefssys.h +++ b/indra/newview/ascentprefssys.h @@ -93,6 +93,7 @@ protected: BOOL mCmdMapToKeepPos; std::string mCmdLineTP2; std::string mCmdLineAway; + std::string mCmdLineURL; //Security ---------------------------------------------------------------------------- BOOL mBroadcastViewerEffects; diff --git a/indra/newview/chatbar_as_cmdline.cpp b/indra/newview/chatbar_as_cmdline.cpp index 5b9d7817a..83b1f3709 100644 --- a/indra/newview/chatbar_as_cmdline.cpp +++ b/indra/newview/chatbar_as_cmdline.cpp @@ -237,8 +237,9 @@ bool cmd_line_chat(std::string revised_text, EChatType type) static LLCachedControl sAscentCmdLineMapToKeepPos(gSavedSettings, "AscentMapToKeepPos"); static LLCachedControl sAscentCmdLineCalc(gSavedSettings, "AscentCmdLineCalc"); static LLCachedControl sAscentCmdLineTP2(gSavedSettings, "AscentCmdLineTP2"); - static LLCachedControl sSinguCmdLineClearChat(gSavedSettings, "SinguCmdLineAway"); static LLCachedControl sAscentCmdLineClearChat(gSavedSettings, "AscentCmdLineClearChat"); + static LLCachedControl sSinguCmdLineAway(gSavedSettings, "SinguCmdLineAway"); + static LLCachedControl sSinguCmdLineURL(gSavedSettings, "SinguCmdLineURL"); if(sAscentCmdLine) { @@ -371,21 +372,16 @@ bool cmd_line_chat(std::string revised_text, EChatType type) { if (revised_text.length() > command.length() + 1) //Typing this command with no argument was causing a crash. -Madgeek { - LLVector3d agentPos = gAgent.getPositionGlobal(); - S32 agent_x = llround( (F32)fmod( agentPos.mdV[VX], (F64)REGION_WIDTH_METERS ) ); - S32 agent_y = llround( (F32)fmod( agentPos.mdV[VY], (F64)REGION_WIDTH_METERS ) ); - S32 agent_z = llround( (F32)agentPos.mdV[VZ] ); - std::string region_name = LLWeb::escapeURL(revised_text.substr(command.length()+1)); + LLSLURL slurl(LLWeb::escapeURL(revised_text.substr(command.length()+1))); - if(!sAscentCmdLineMapToKeepPos) + // The user wants to keep their position between MapTos and they have not passed a position (position is defaulted) + if (sAscentCmdLineMapToKeepPos && slurl.getPosition() == LLVector3(REGION_WIDTH_METERS/2, REGION_WIDTH_METERS/2, 0)) { - agent_x = 128; - agent_y = 128; - agent_z = 0; + LLVector3d agentPos = gAgent.getPositionGlobal(); + slurl = LLSLURL(slurl.getRegion(), LLVector3(fmod(agentPos.mdV[VX], (F64)REGION_WIDTH_METERS), fmod(agentPos.mdV[VY], (F64)REGION_WIDTH_METERS), agentPos.mdV[VZ])); } - LLSLURL slurl(region_name,LLVector3(agent_x,agent_y,agent_z)); - LLUrlAction::teleportToLocation(std::string("secondlife:///app/teleport/")+slurl.getLocationString()); + LLUrlAction::teleportToLocation(LLWeb::escapeURL(std::string("secondlife:///app/teleport/")+slurl.getLocationString())); } return false; } @@ -428,11 +424,19 @@ bool cmd_line_chat(std::string revised_text, EChatType type) } return false; } - else if(command == utf8str_tolower(sSinguCmdLineClearChat)) + else if(command == utf8str_tolower(sSinguCmdLineAway)) { handle_fake_away_status(NULL); return false; } + else if(command == utf8str_tolower(sSinguCmdLineURL)) + { + if (revised_text.length() > command.length() + 1) + { + LLUrlAction::clickAction(revised_text.substr(command.length()+1)); + } + return false; + } else if(command == "typingstop") { std::string text; diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 50c8bc5cc..f42739b20 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -131,6 +131,20 @@ const F32 MAX_FIDGET_TIME = 20.f; // seconds LLAgent gAgent; std::string gAuthString; +void camera_reset_on_motion() +{ + static const LLCachedControl motion_resets_cam("SinguMotionResetsCamera"); + if (motion_resets_cam) + { + gAgentCamera.resetView(); + } + else if (LLSelectMgr::getInstance()->getSelection()->isAttachment()) // If attachments are still selected during movement, bad things happen + { + LLSelectMgr::getInstance()->deselectAll(); + if (gMenuHolder) gMenuHolder->hideMenus(); // Attachments may be selected through menus, deselection will invalidate these menus + } +} + class LLTeleportRequest { public: @@ -540,7 +554,7 @@ void LLAgent::moveAt(S32 direction, bool reset) if (reset) { - gAgentCamera.resetView(); + camera_reset_on_motion(); } } @@ -563,7 +577,7 @@ void LLAgent::moveAtNudge(S32 direction) setControlFlags(AGENT_CONTROL_NUDGE_AT_NEG); } - gAgentCamera.resetView(); + camera_reset_on_motion(); } //----------------------------------------------------------------------------- @@ -585,7 +599,7 @@ void LLAgent::moveLeft(S32 direction) setControlFlags(AGENT_CONTROL_LEFT_NEG | AGENT_CONTROL_FAST_LEFT); } - gAgentCamera.resetView(); + camera_reset_on_motion(); } //----------------------------------------------------------------------------- @@ -607,7 +621,7 @@ void LLAgent::moveLeftNudge(S32 direction) setControlFlags(AGENT_CONTROL_NUDGE_LEFT_NEG); } - gAgentCamera.resetView(); + camera_reset_on_motion(); } //----------------------------------------------------------------------------- @@ -629,7 +643,7 @@ void LLAgent::moveUp(S32 direction) setControlFlags(AGENT_CONTROL_UP_NEG | AGENT_CONTROL_FAST_UP); } - if (!isCrouch) gAgentCamera.resetView(); + if (!isCrouch) camera_reset_on_motion(); } //----------------------------------------------------------------------------- @@ -650,7 +664,7 @@ void LLAgent::moveYaw(F32 mag, bool reset_view) if (reset_view) { - gAgentCamera.resetView(); + camera_reset_on_motion(); } } @@ -783,7 +797,7 @@ void LLAgent::toggleFlying() BOOL fly = !gAgent.getFlying(); gAgent.setFlying( fly ); - gAgentCamera.resetView(); + camera_reset_on_motion(); } // static diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index d1454847d..bbaee5358 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -366,7 +366,7 @@ const char *VFS_DATA_FILE_BASE = "data.db2.x."; const char *VFS_INDEX_FILE_BASE = "index.db2.x."; static std::string gSecondLife; -static std::string gWindowTitle; +std::string gWindowTitle; std::string gLoginPage; std::vector gLoginURIs; diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index efc51d319..143f18da7 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -54,6 +54,9 @@ #include "rlvhandler.h" // [/RLVa:KB] +#include "llviewerwindow.h" +#include "llwindow.h" + extern const S32 TRANS_GIFT; void give_money(const LLUUID& uuid, LLViewerRegion* region, S32 amount, BOOL is_group = FALSE, S32 trx_type = TRANS_GIFT, const std::string& desc = LLStringUtil::null); void handle_lure(const uuid_vec_t& ids); @@ -379,6 +382,13 @@ void LLAvatarActions::showProfile(const LLUUID& id, bool web) } } +// static +void LLAvatarActions::showProfiles(const uuid_vec_t& ids, bool web) +{ + for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it) + showProfile(*it, web); +} + //static bool LLAvatarActions::profileVisible(const LLUUID& id) { @@ -490,6 +500,48 @@ void LLAvatarActions::csr(const LLUUID& id) // Singu TODO: Share inventory code block should live here +// static +void LLAvatarActions::buildResidentsString(std::vector avatar_names, std::string& residents_string) +{ + llassert(avatar_names.size() > 0); + + std::sort(avatar_names.begin(), avatar_names.end()); + const std::string& separator = LLTrans::getString("words_separator"); + for (std::vector::const_iterator it = avatar_names.begin(); ; ) + { + residents_string.append((*it).getCompleteName()); + if (++it == avatar_names.end()) + { + break; + } + residents_string.append(separator); + } +} + +// static +void LLAvatarActions::buildResidentsString(const uuid_vec_t& avatar_uuids, std::string& residents_string) +{ + std::vector avatar_names; + uuid_vec_t::const_iterator it = avatar_uuids.begin(); + for (; it != avatar_uuids.end(); ++it) + { + LLAvatarName av_name; + if (LLAvatarNameCache::get(*it, &av_name)) + { + avatar_names.push_back(av_name); + } + } + + // We should check whether the vector is not empty to pass the assertion + // that avatar_names.size() > 0 in LLAvatarActions::buildResidentsString. + if (!avatar_names.empty()) + { + LLAvatarActions::buildResidentsString(avatar_names, residents_string); + } +} + +// Singu TODO: Share inventory code block should live here, too + // static void LLAvatarActions::toggleBlock(const LLUUID& id) { @@ -754,3 +806,24 @@ bool LLAvatarActions::canBlock(const LLUUID& id) bool is_self = id == gAgentID; return !is_self && !is_linden; } + +// static +void LLAvatarActions::copyUUIDs(const uuid_vec_t& ids) +{ + std::string ids_string; + const std::string& separator = LLTrans::getString("words_separator"); + for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it) + { + const LLUUID& id = *it; + if (id.isNull()) + continue; + + if (!ids_string.empty()) + ids_string.append(separator); + + ids_string.append(id.asString()); + } + + if (!ids_string.empty()) + gViewerWindow->mWindow->copyTextToClipboard(utf8str_to_wstring(ids_string)); +} diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h index 6131954a6..fcd5d6a70 100644 --- a/indra/newview/llavataractions.h +++ b/indra/newview/llavataractions.h @@ -27,6 +27,7 @@ #ifndef LL_LLAVATARACTIONS_H #define LL_LLAVATARACTIONS_H +class LLAvatarName; class LLFloater; /** @@ -86,6 +87,7 @@ public: * Show avatar profile. */ static void showProfile(const LLUUID& id, bool web = false); + static void showProfiles(const uuid_vec_t& ids, bool web = false); static void hideProfile(const LLUUID& id); static bool profileVisible(const LLUUID& id); static LLFloater* getProfileFloater(const LLUUID& id); @@ -180,6 +182,27 @@ public: */ static bool canOfferTeleport(const uuid_vec_t& ids); + /** + * Builds a string of residents' display names separated by "words_separator" string. + * + * @param avatar_names - a vector of given avatar names from which resulting string is built + * @param residents_string - the resulting string + */ + static void buildResidentsString(std::vector avatar_names, std::string& residents_string); + + /** + * Builds a string of residents' display names separated by "words_separator" string. + * + * @param avatar_uuids - a vector of given avatar uuids from which resulting string is built + * @param residents_string - the resulting string + */ + static void buildResidentsString(const uuid_vec_t& avatar_uuids, std::string& residents_string); + + /** + * Copy the selected avatar's UUID to clipboard + */ + static void copyUUIDs(const uuid_vec_t& id); + private: static bool callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response); static bool handleRemove(const LLSD& notification, const LLSD& response); diff --git a/indra/newview/llfloateravatarlist.cpp b/indra/newview/llfloateravatarlist.cpp index 2ed61cf89..36b7265b6 100644 --- a/indra/newview/llfloateravatarlist.cpp +++ b/indra/newview/llfloateravatarlist.cpp @@ -337,6 +337,87 @@ static void cmd_profile(const LLAvatarListEntry* entry); static void cmd_toggle_mark(LLAvatarListEntry* entry); static void cmd_ar(const LLAvatarListEntry* entry); static void cmd_teleport(const LLAvatarListEntry* entry); + +namespace +{ + typedef LLMemberListener view_listener_t; + class RadarTrack : public view_listener_t + { + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLFloaterAvatarList::instance().onClickTrack(); + return true; + } + }; + + class RadarMark : public view_listener_t + { + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLFloaterAvatarList::instance().doCommand(cmd_toggle_mark); + return true; + } + }; + + class RadarFocus : public view_listener_t + { + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLFloaterAvatarList::instance().onClickFocus(); + return true; + } + }; + + class RadarFocusPrev : public view_listener_t + { + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLFloaterAvatarList::instance().focusOnPrev(userdata); + return true; + } + }; + + class RadarFocusNext : public view_listener_t + { + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLFloaterAvatarList::instance().focusOnNext(userdata); + return true; + } + }; + + class RadarTeleportTo : public view_listener_t + { + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLFloaterAvatarList::instance().doCommand(cmd_teleport, true); + return true; + } + }; + + class RadarAnnounceKeys : public view_listener_t + { + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLFloaterAvatarList::instance().sendKeys(); + return true; + } + }; +} + +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"); +} + BOOL LLFloaterAvatarList::postBuild() { // Set callbacks @@ -1303,7 +1384,7 @@ bool LLFloaterAvatarList::onConfirmRadarChatKeys(const LLSD& notification, const return false; } -static void send_freeze(const LLUUID& avatar_id, bool freeze) +void send_freeze(const LLUUID& avatar_id, bool freeze) { U32 flags = 0x0; if (!freeze) @@ -1328,7 +1409,7 @@ static void send_freeze(const LLUUID& avatar_id, bool freeze) } } -static void send_eject(const LLUUID& avatar_id, bool ban) +void send_eject(const LLUUID& avatar_id, bool ban) { LLMessageSystem* msg = gMessageSystem; LLVOAvatar* avatarp = gObjectList.findAvatar(avatar_id); diff --git a/indra/newview/llfloateravatarlist.h b/indra/newview/llfloateravatarlist.h index 7b7291e21..33f02ce9b 100644 --- a/indra/newview/llfloateravatarlist.h +++ b/indra/newview/llfloateravatarlist.h @@ -250,7 +250,6 @@ public: typedef boost::shared_ptr LLAvatarListEntryPtr; typedef std::vector< LLAvatarListEntryPtr > av_list_t; -private: // when a line editor loses keyboard focus, it is committed. // commit callbacks are named onCommitWidgetName by convention. //void onCommitBaz(LLUICtrl* ctrl, void *userdata); diff --git a/indra/newview/llregioninfomodel.h b/indra/newview/llregioninfomodel.h index d22a0de46..f3db96f13 100644 --- a/indra/newview/llregioninfomodel.h +++ b/indra/newview/llregioninfomodel.h @@ -86,6 +86,7 @@ protected: private: void reset(); +public: // *FIXME: Duplicated code from LLPanelRegionInfo static void sendEstateOwnerMessage( LLMessageSystem* msg, @@ -93,6 +94,7 @@ private: const LLUUID& invoice, const std::vector& strings); +private: update_signal_t mUpdateSignal; }; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index f3f55ca45..6c6356cbb 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -257,6 +257,7 @@ LLPointer gStartTexture; // extern S32 gStartImageWidth; extern S32 gStartImageHeight; +extern std::string gWindowTitle; // // local globals @@ -1550,7 +1551,7 @@ bool idle_startup() { name += " " + lastname; } - gViewerWindow->getWindow()->setTitle(LLAppViewer::instance()->getWindowTitle() + "- " + name); + gViewerWindow->getWindow()->setTitle(gWindowTitle += "- " + name); // Pass the user information to the voice chat server interface. LLVoiceClient::getInstance()->userAuthorized(name, gAgentID); // create the default proximal channel diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 0031f2a87..9c6c05ec1 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -136,6 +136,7 @@ #include "llnotify.h" #include "llpanellogin.h" #include "llparcel.h" +#include "llregioninfomodel.h" #include "llselectmgr.h" #include "llstatusbar.h" #include "lltextureview.h" @@ -6051,7 +6052,7 @@ class LLWorldCreateLandmark : public view_listener_t LLUUID folder_id; folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK); std::string pos_string; - LLAgentUI::buildLocationString(pos_string); + LLAgentUI::buildLocationString(pos_string, gSavedSettings.getBOOL("LiruLegacyLandmarks") ? LLAgentUI::LOCATION_FORMAT_NO_MATURITY : LLAgentUI::LOCATION_FORMAT_LANDMARK); create_inventory_item(gAgent.getID(), gAgent.getSessionID(), folder_id, LLTransactionID::tnull, @@ -9206,6 +9207,324 @@ class VisibleNotSecondLife : public view_listener_t } }; +LLScrollListCtrl* get_focused_list() +{ + LLScrollListCtrl* list = dynamic_cast(gFocusMgr.getKeyboardFocus()); + llassert(list); // This listener only applies to lists + return list; +} + +class ListEnableAnySelected : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLScrollListCtrl* list = get_focused_list(); + if (!list) return false; + gMenuHolder->findControl(userdata["control"].asString())->setValue(list->getNumSelected()); + return true; + } +}; + +class ListEnableMultipleSelected : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLScrollListCtrl* list = get_focused_list(); + if (!list) return false; + gMenuHolder->findControl(userdata["control"].asString())->setValue(list->getNumSelected() > 1); + return true; + } +}; + +class ListEnableSingleSelected : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLScrollListCtrl* list = get_focused_list(); + if (!list) return false; + gMenuHolder->findControl(userdata["control"].asString())->setValue(list->getNumSelected() == 1); + return true; + } +}; + +class ListEnableCall : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLScrollListCtrl* list = get_focused_list(); + if (!list) return false; + gMenuHolder->findControl(userdata["control"].asString())->setValue(LLAvatarActions::canCall()); + return true; + } +}; + +class ListEnableIsFriend : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLScrollListCtrl* list = get_focused_list(); + if (!list) return false; + gMenuHolder->findControl(userdata["control"].asString())->setValue(LLAvatarActions::isFriend(list->getStringUUIDSelectedItem())); + return true; + } +}; + +class ListEnableIsNotFriend : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLScrollListCtrl* list = get_focused_list(); + if (!list) return false; + gMenuHolder->findControl(userdata["control"].asString())->setValue(!LLAvatarActions::isFriend(list->getStringUUIDSelectedItem())); + return true; + } +}; + +class ListEnableMute : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLScrollListCtrl* list = get_focused_list(); + if (!list) return false; + uuid_vec_t ids = list->getSelectedIDs(); + bool can_block = true; + for (uuid_vec_t::const_iterator it = ids.begin(); can_block && it != ids.end(); ++it) + can_block = LLAvatarActions::canBlock(*it); + gMenuHolder->findControl(userdata["control"].asString())->setValue(can_block); + return true; + } +}; + +class ListEnableOfferTeleport : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLScrollListCtrl* list = get_focused_list(); + if (!list) return false; + gMenuHolder->findControl(userdata["control"].asString())->setValue(LLAvatarActions::canOfferTeleport(list->getSelectedIDs())); + return true; + } +}; + +class ListCopyUUIDs : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLScrollListCtrl* list = get_focused_list(); + if (!list) return false; + LLAvatarActions::copyUUIDs(list->getSelectedIDs()); + return true; + } +}; + +class ListOfferTeleport : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLScrollListCtrl* list = get_focused_list(); + if (!list) return false; + LLAvatarActions::offerTeleport(list->getSelectedIDs()); + return true; + } +}; + +class ListPay : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLScrollListCtrl* list = get_focused_list(); + if (!list) return false; + LLAvatarActions::pay(list->getStringUUIDSelectedItem()); + return true; + } +}; + +class ListRemoveFriend : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLScrollListCtrl* list = get_focused_list(); + if (!list) return false; + LLAvatarActions::removeFriendDialog(list->getStringUUIDSelectedItem()); + return true; + } +}; + +class ListRequestFriendship : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLScrollListCtrl* list = get_focused_list(); + if (!list) return false; + LLAvatarActions::requestFriendshipDialog(list->getStringUUIDSelectedItem()); + return true; + } +}; + +class ListShowProfile : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLScrollListCtrl* list = get_focused_list(); + if (!list) return false; + LLAvatarActions::showProfiles(list->getSelectedIDs()); + return true; + } +}; + +class ListStartAdhocCall : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLScrollListCtrl* list = get_focused_list(); + if (!list) return false; + LLAvatarActions::startAdhocCall(list->getSelectedIDs()); + return true; + } +}; + +class ListStartCall : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLScrollListCtrl* list = get_focused_list(); + if (!list) return false; + LLAvatarActions::startCall(list->getStringUUIDSelectedItem()); + return true; + } +}; + +class ListStartConference : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLScrollListCtrl* list = get_focused_list(); + if (!list) return false; + LLAvatarActions::startConference(list->getSelectedIDs()); + return true; + } +}; + +class ListStartIM : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLScrollListCtrl* list = get_focused_list(); + if (!list) return false; + LLAvatarActions::startIM(list->getStringUUIDSelectedItem()); + return true; + } +}; + +class ListAbuseReport : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLScrollListCtrl* list = get_focused_list(); + if (!list) return false; + LLFloaterReporter::showFromObject(list->getStringUUIDSelectedItem()); + return true; + } +}; + +// Create the args for administrative notifications used in lists, tossing the selected names into it. +LLSD create_args(const uuid_vec_t& ids, const std::string& token) +{ + std::string names; + LLAvatarActions::buildResidentsString(ids, names); + LLSD args; + args[token] = names; + return args; +} + +void parcel_mod_notice_callback(const uuid_vec_t& ids, S32 choice, boost::function cb) +{ + if (ids.empty() || (choice != 1 && choice != 0)) return; // choice must be 1 or 0 to take action + + for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it) + cb(*it, choice); +} + +void send_eject(const LLUUID& avatar_id, bool ban); +class ListEject : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLScrollListCtrl* list = get_focused_list(); + if (!list) return false; + const uuid_vec_t& ids = list->getSelectedIDs(); + LLNotificationsUtil::add("EjectAvatarFullname", create_args(ids, "AVATAR_NAME"), LLSD(), boost::bind(parcel_mod_notice_callback, ids, boost::bind(LLNotificationsUtil::getSelectedOption, _1, _2), send_eject)); + return true; + } +}; + +void send_freeze(const LLUUID& avatar_id, bool freeze); +class ListFreeze : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLScrollListCtrl* list = get_focused_list(); + if (!list) return false; + const uuid_vec_t& ids = list->getSelectedIDs(); + LLNotificationsUtil::add("FreezeAvatarFullname", create_args(ids, "AVATAR_NAME"), LLSD(), boost::bind(parcel_mod_notice_callback, ids, boost::bind(LLNotificationsUtil::getSelectedOption, _1, _2), send_freeze)); + return true; + } +}; + +void estate_bulk_eject(const uuid_vec_t& ids, bool ban, S32 zero) +{ + if (ids.empty() || zero != 0) return; + std::vector strings; + strings[0] = gAgentID.asString(); // [0] = our agent id + for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it) + { + LLUUID id(*it); + if (id.isNull()) continue; + strings[1] = id.asString(); // [1] = target agent id + + LLRegionInfoModel::sendEstateOwnerMessage(gMessageSystem, "teleporthomeuser", LLFloaterRegionInfo::getLastInvoice(), strings); + if (ban) + LLPanelEstateInfo::sendEstateAccessDelta(ESTATE_ACCESS_BANNED_AGENT_ADD | ESTATE_ACCESS_ALLOWED_AGENT_REMOVE | ESTATE_ACCESS_NO_REPLY, id); + } +} + +class ListEstateBan : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLScrollListCtrl* list = get_focused_list(); + if (!list) return false; + const uuid_vec_t& ids = list->getSelectedIDs(); + LLNotificationsUtil::add("EstateBanUser", create_args(ids, "EVIL_USER"), LLSD(), boost::bind(estate_bulk_eject, ids, true, boost::bind(LLNotificationsUtil::getSelectedOption, _1, _2))); + return true; + } +}; + +class ListEstateEject : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLScrollListCtrl* list = get_focused_list(); + if (!list) return false; + const uuid_vec_t& ids = list->getSelectedIDs(); + LLNotificationsUtil::add("EstateKickUser", create_args(ids, "EVIL_USER"), LLSD(), boost::bind(estate_bulk_eject, ids, false, boost::bind(LLNotificationsUtil::getSelectedOption, _1, _2))); + return true; + } +}; + +class ListToggleMute : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + LLScrollListCtrl* list = get_focused_list(); + if (!list) return false; + uuid_vec_t ids = list->getSelectedIDs(); + for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it) + LLAvatarActions::toggleBlock(*it); + return true; + } +}; + void addMenu(view_listener_t *menu, const std::string& name) { sMenus.push_back(menu); @@ -9509,6 +9828,32 @@ void initialize_menus() addMenu(new VisibleNotSecondLife(), "VisibleNotSecondLife"); + // List-bound menus + addMenu(new ListEnableAnySelected(), "List.EnableAnySelected"); + addMenu(new ListEnableMultipleSelected(), "List.EnableMultipleSelected"); + addMenu(new ListEnableSingleSelected(), "List.EnableSingleSelected"); + addMenu(new ListEnableCall(), "List.EnableCall"); + addMenu(new ListEnableIsFriend(), "List.EnableIsFriend"); + addMenu(new ListEnableIsNotFriend(), "List.EnableIsNotFriend"); + addMenu(new ListEnableMute(), "List.EnableMute"); + addMenu(new ListEnableOfferTeleport(), "List.EnableOfferTeleport"); + addMenu(new ListCopyUUIDs(), "List.CopyUUIDs"); + addMenu(new ListOfferTeleport(), "List.OfferTeleport"); + addMenu(new ListPay(), "List.Pay"); + addMenu(new ListRemoveFriend(), "List.RemoveFriend"); + addMenu(new ListRequestFriendship(), "List.RequestFriendship"); + addMenu(new ListShowProfile(), "List.ShowProfile"); + addMenu(new ListStartAdhocCall(), "List.StartAdhocCall"); + addMenu(new ListStartCall(), "List.StartCall"); + addMenu(new ListStartConference(), "List.StartConference"); + addMenu(new ListStartIM(), "List.StartIM"); + addMenu(new ListAbuseReport(), "List.AbuseReport"); + addMenu(new ListEject(), "List.ParcelEject"); + addMenu(new ListFreeze(), "List.Freeze"); + addMenu(new ListEstateBan(), "List.EstateBan"); + addMenu(new ListEstateEject(), "List.EstateEject"); + addMenu(new ListToggleMute(), "List.ToggleMute"); + LLToolMgr::getInstance()->initMenu(sMenus); } diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index eaabf2e80..37d333f6a 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -6211,7 +6211,7 @@ LLViewerJointAttachment* LLVOAvatar::getTargetAttachmentPoint(LLViewerObject* vi if (isSelf() && attachmentID == 127 && gSavedSettings.getBOOL("SGDetachBridge")) { llinfos << "Bridge detected! detaching" << llendl; - LLAppearanceMgr::getInstance()->removeItemFromAvatar(viewer_object->getAttachmentItemID()); + LLVOAvatarSelf::detachAttachmentIntoInventory(viewer_object->getAttachmentItemID()); return 0; } // attachment = get_if_there(mAttachmentPoints, 1, (LLViewerJointAttachment*)NULL); // Arbitrary using 1 (chest) diff --git a/indra/newview/skins/default/colors_base.xml b/indra/newview/skins/default/colors_base.xml index 88469baa7..f7b934f81 100644 --- a/indra/newview/skins/default/colors_base.xml +++ b/indra/newview/skins/default/colors_base.xml @@ -151,7 +151,7 @@ - + diff --git a/indra/newview/skins/default/xui/en-us/floater_radar.xml b/indra/newview/skins/default/xui/en-us/floater_radar.xml index 568c9e884..2ccc31ca6 100644 --- a/indra/newview/skins/default/xui/en-us/floater_radar.xml +++ b/indra/newview/skins/default/xui/en-us/floater_radar.xml @@ -6,7 +6,7 @@ Radar (1 Avatar) Radar ([COUNT] Avatars) - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/en-us/menu_viewer.xml b/indra/newview/skins/default/xui/en-us/menu_viewer.xml index b55483aab..192d3ff7b 100644 --- a/indra/newview/skins/default/xui/en-us/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en-us/menu_viewer.xml @@ -309,6 +309,10 @@ mouse_opaque="true" name="Reset View" shortcut="Esc" width="211"> + + + + diff --git a/indra/newview/skins/default/xui/en-us/panel_preferences_ascent_system.xml b/indra/newview/skins/default/xui/en-us/panel_preferences_ascent_system.xml index b848f8313..ee2057ffa 100644 --- a/indra/newview/skins/default/xui/en-us/panel_preferences_ascent_system.xml +++ b/indra/newview/skins/default/xui/en-us/panel_preferences_ascent_system.xml @@ -59,10 +59,12 @@ Clear the chat history (usage: cmd) + Open url/slurl (usage: cmd slurl) + - - Change Draw Distance (usage: cmd meters) + Change Draw Distance (usage: cmd meters) Teleport to cam position (usage: cmd) diff --git a/indra/newview/skins/default/xui/en-us/strings.xml b/indra/newview/skins/default/xui/en-us/strings.xml index 9ecd2c66e..07151f0f9 100644 --- a/indra/newview/skins/default/xui/en-us/strings.xml +++ b/indra/newview/skins/default/xui/en-us/strings.xml @@ -4313,6 +4313,10 @@ Abuse Report dance7 dance8 none/none + + + + Chat diff --git a/indra/newview/skins/default/xui/es/floater_about_land.xml b/indra/newview/skins/default/xui/es/floater_about_land.xml index 814838255..c11128f59 100644 --- a/indra/newview/skins/default/xui/es/floater_about_land.xml +++ b/indra/newview/skins/default/xui/es/floater_about_land.xml @@ -5,9 +5,11 @@ Nombre: + Descripción: + Tipo: @@ -30,6 +32,7 @@ Grupo: +