llfloateravatarinfo.cpp 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  1. /**
  2. * @file llfloateravatarinfo.cpp
  3. * @brief LLFloaterAvatarInfo class implementation
  4. * Avatar information as shown in a floating window from right-click
  5. * Profile. Used for editing your own avatar info. Just a wrapper
  6. * for LLPanelAvatar, shared with the Find directory.
  7. *
  8. * $LicenseInfo:firstyear=2002&license=viewergpl$
  9. *
  10. * Copyright (c) 2002-2009, Linden Research, Inc.
  11. *
  12. * Second Life Viewer Source Code
  13. * The source code in this file ("Source Code") is provided by Linden Lab
  14. * to you under the terms of the GNU General Public License, version 2.0
  15. * ("GPL"), unless you have obtained a separate licensing agreement
  16. * ("Other License"), formally executed by you and Linden Lab. Terms of
  17. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  18. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  19. *
  20. * There are special exceptions to the terms and conditions of the GPL as
  21. * it is applied to this Source Code. View the full text of the exception
  22. * in the file doc/FLOSS-exception.txt in this software distribution, or
  23. * online at
  24. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  25. *
  26. * By copying, modifying or distributing this software, you acknowledge
  27. * that you have read and understood your obligations described above,
  28. * and agree to abide by those obligations.
  29. *
  30. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  31. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  32. * COMPLETENESS OR PERFORMANCE.
  33. * $/LicenseInfo$
  34. */
  35. #include "llviewerprecompiledheaders.h"
  36. #include "llfloateravatarinfo.h"
  37. #include "llinventory.h"
  38. #include "llnotifications.h"
  39. #include "lluictrlfactory.h"
  40. #include "llmessage.h"
  41. #include "llagent.h"
  42. #include "llcommandhandler.h"
  43. #include "llgridmanager.h" // For gIsInSecondLife
  44. #include "llfloaterinventory.h"
  45. #include "llviewercontrol.h"
  46. #include "llweb.h"
  47. LLFloaterAvatarInfo::instances_map_t LLFloaterAvatarInfo::sInstances;
  48. //-----------------------------------------------------------------------------
  49. // Command handler
  50. //-----------------------------------------------------------------------------
  51. class LLProfileHandler final : public LLCommandHandler
  52. {
  53. public:
  54. LLProfileHandler()
  55. : LLCommandHandler("profile", UNTRUSTED_THROTTLE)
  56. {
  57. }
  58. bool handle(const LLSD& params, const LLSD&, LLMediaCtrl*) override
  59. {
  60. if (params.size() < 1) return false;
  61. std::string agent_name = params[0];
  62. std::string url = LLFloaterAvatarInfo::getProfileURL(agent_name);
  63. if (url.empty())
  64. {
  65. LLSD args;
  66. args["NAME"] = agent_name;
  67. gNotifications.add("NoWebProfile", args);
  68. }
  69. else
  70. {
  71. llinfos << "Opening web profile of: " << agent_name << llendl;
  72. LLWeb::loadURL(url);
  73. }
  74. return true;
  75. }
  76. };
  77. LLProfileHandler gProfileHandler;
  78. class LLShareWithAvatarHandler : public LLCommandHandler
  79. {
  80. public:
  81. LLShareWithAvatarHandler()
  82. : LLCommandHandler("sharewithavatar", UNTRUSTED_THROTTLE)
  83. {
  84. }
  85. bool handle(const LLSD& params, const LLSD&, LLMediaCtrl* web)
  86. {
  87. // Make sure we have some parameters
  88. if (params.size() == 0)
  89. {
  90. return false;
  91. }
  92. // Get the ID
  93. LLUUID id;
  94. if (!id.set(params[0], false))
  95. {
  96. return false;
  97. }
  98. // Select the 2nd Life tab in the profile panel.
  99. LLFloaterAvatarInfo::showFromObject(id, "2nd Life");
  100. // Open the inventory floater and/or bring it to front
  101. LLFloaterInventory::showAgentInventory();
  102. // Give some clue to the user as what to do now
  103. gNotifications.add("ShareInventory");
  104. return true;
  105. }
  106. };
  107. LLShareWithAvatarHandler gShareWithAvatar;
  108. class LLPickHandler final : public LLCommandHandler
  109. {
  110. public:
  111. LLPickHandler()
  112. : LLCommandHandler("pick", UNTRUSTED_THROTTLE)
  113. {
  114. }
  115. bool canHandleUntrusted(const LLSD& params, const LLSD&,
  116. LLMediaCtrl*, const std::string& nav_type) override
  117. {
  118. if (!params.size())
  119. {
  120. return true; // Do not block; it will fail later in handle()
  121. }
  122. if (nav_type == "clicked" || nav_type == "external")
  123. {
  124. return true;
  125. }
  126. return params[0].asString() != "create";
  127. }
  128. bool handle(const LLSD& params, const LLSD&, LLMediaCtrl*) override
  129. {
  130. // Make sure we have some parameters
  131. if (!params.size())
  132. {
  133. return false;
  134. }
  135. // *TODO: implement pick selection by UUID (and move to
  136. // llpanelpick.cpp ?). For now, simply select the Picks tab in the
  137. // profile panel.
  138. llinfos << "STUB code for URI secondlife://app/pick/ - Selecting Picks tab in avatar profile."
  139. << llendl;
  140. LLFloaterAvatarInfo::showFromObject(gAgentID, "Picks");
  141. return true;
  142. }
  143. };
  144. LLPickHandler gPickHandler;
  145. //-----------------------------------------------------------------------------
  146. // LLFloaterAvatarInfo class
  147. //-----------------------------------------------------------------------------
  148. void* LLFloaterAvatarInfo::createPanelAvatar(void* data)
  149. {
  150. LLFloaterAvatarInfo* self = (LLFloaterAvatarInfo*)data;
  151. self->mPanelAvatarp = new LLPanelAvatar("PanelAv", LLRect(), true);
  152. return self->mPanelAvatarp;
  153. }
  154. bool LLFloaterAvatarInfo::postBuild()
  155. {
  156. return true;
  157. }
  158. LLFloaterAvatarInfo::LLFloaterAvatarInfo(const LLUUID& avatar_id)
  159. : LLPreview("avatarinfo"),
  160. mAvatarID(avatar_id),
  161. mSuggestedOnlineStatus(ONLINE_STATUS_NO)
  162. {
  163. setAutoFocus(true);
  164. LLCallbackMap::map_t factory_map;
  165. factory_map["Panel Avatar"] = LLCallbackMap(createPanelAvatar, this);
  166. LLUICtrlFactory::getInstance()->buildFloater(this, "floater_profile.xml",
  167. &factory_map);
  168. if (mPanelAvatarp)
  169. {
  170. mPanelAvatarp->selectTab(0);
  171. }
  172. // Must be done before callback below is called.
  173. sInstances[avatar_id] = this;
  174. LLAvatarNameCache::get(avatar_id,
  175. boost::bind(&callbackLoadAvatarName, _1, _2));
  176. }
  177. //virtual
  178. LLFloaterAvatarInfo::~LLFloaterAvatarInfo()
  179. {
  180. // Child views automatically deleted
  181. sInstances.erase(mAvatarID);
  182. }
  183. void LLFloaterAvatarInfo::listAgentGroups()
  184. {
  185. if (mAvatarID == gAgentID)
  186. {
  187. mPanelAvatarp->listAgentGroups();
  188. }
  189. }
  190. //static
  191. LLFloaterAvatarInfo* LLFloaterAvatarInfo::show(const LLUUID& avatar_id)
  192. {
  193. if (avatar_id.isNull())
  194. {
  195. return NULL;
  196. }
  197. LLFloaterAvatarInfo* floater;
  198. instances_map_t::iterator it = sInstances.find(avatar_id);
  199. if (it != sInstances.end())
  200. {
  201. // Bring the existing floater to front
  202. floater = it->second;
  203. floater->open();
  204. }
  205. else
  206. {
  207. floater = new LLFloaterAvatarInfo(avatar_id);
  208. floater->open();
  209. }
  210. return floater;
  211. }
  212. // Open profile to a certain tab.
  213. //static
  214. void LLFloaterAvatarInfo::showFromObject(const LLUUID& avatar_id,
  215. std::string tab_name)
  216. {
  217. LLFloaterAvatarInfo* floater = show(avatar_id);
  218. if (floater)
  219. {
  220. floater->mPanelAvatarp->setAvatarID(avatar_id, LLStringUtil::null,
  221. ONLINE_STATUS_NO);
  222. floater->mPanelAvatarp->selectTabByName(tab_name);
  223. }
  224. }
  225. //static
  226. void LLFloaterAvatarInfo::showFromDirectory(const LLUUID& avatar_id)
  227. {
  228. LLFloaterAvatarInfo* floater = show(avatar_id);
  229. if (floater)
  230. {
  231. floater->mPanelAvatarp->setAvatarID(avatar_id, LLStringUtil::null,
  232. ONLINE_STATUS_NO);
  233. }
  234. }
  235. //static
  236. void LLFloaterAvatarInfo::showFromFriend(const LLUUID& agent_id, bool online)
  237. {
  238. LLFloaterAvatarInfo* floater = show(agent_id);
  239. if (floater)
  240. {
  241. floater->mSuggestedOnlineStatus = online ? ONLINE_STATUS_YES
  242. : ONLINE_STATUS_NO;
  243. }
  244. }
  245. //static
  246. void LLFloaterAvatarInfo::showFromProfile(const LLUUID& avatar_id, LLRect rect)
  247. {
  248. if (avatar_id.isNull())
  249. {
  250. return;
  251. }
  252. LLFloaterAvatarInfo* floater;
  253. instances_map_t::iterator it = sInstances.find(avatar_id);
  254. if (it != sInstances.end())
  255. {
  256. // Use the existing floater
  257. floater = it->second;
  258. }
  259. else
  260. {
  261. floater = new LLFloaterAvatarInfo(avatar_id);
  262. floater->translate(rect.mLeft - floater->getRect().mLeft + 16,
  263. rect.mTop - floater->getRect().mTop - 16);
  264. floater->mPanelAvatarp->setAvatarID(avatar_id, LLStringUtil::null,
  265. ONLINE_STATUS_NO);
  266. }
  267. if (floater)
  268. {
  269. floater->open();
  270. }
  271. }
  272. void LLFloaterAvatarInfo::showProfileCallback(S32 option, void *userdata)
  273. {
  274. if (option == 0)
  275. {
  276. showFromObject(gAgentID);
  277. }
  278. }
  279. //static
  280. void LLFloaterAvatarInfo::callbackLoadAvatarName(const LLUUID& id,
  281. const LLAvatarName& avatar_name)
  282. {
  283. LLFloaterAvatarInfo* floater = get_ptr_in_map(sInstances, id);
  284. if (floater)
  285. {
  286. // Build a new title including the avatar name.
  287. std::ostringstream title;
  288. if (LLAvatarNameCache::useDisplayNames())
  289. {
  290. // Always show "Display Name [Legacy Name]" for security reasons
  291. title << avatar_name.getNames() << " - " << floater->getTitle();
  292. }
  293. else
  294. {
  295. title << avatar_name.getLegacyName() << " - "
  296. << floater->getTitle();
  297. }
  298. floater->setTitle(title.str());
  299. }
  300. }
  301. //virtual
  302. void LLFloaterAvatarInfo::draw()
  303. {
  304. // skip LLPreview::draw()
  305. LLFloater::draw();
  306. }
  307. //virtual
  308. bool LLFloaterAvatarInfo::canClose()
  309. {
  310. return mPanelAvatarp && mPanelAvatarp->canClose();
  311. }
  312. LLFloaterAvatarInfo* LLFloaterAvatarInfo::getInstance(const LLUUID& id)
  313. {
  314. return get_ptr_in_map(sInstances, id);
  315. }
  316. void LLFloaterAvatarInfo::loadAsset()
  317. {
  318. if (mPanelAvatarp)
  319. {
  320. mPanelAvatarp->setAvatarID(mAvatarID, LLStringUtil::null,
  321. mSuggestedOnlineStatus);
  322. mAssetStatus = PREVIEW_ASSET_LOADING;
  323. }
  324. }
  325. LLPreview::EAssetStatus LLFloaterAvatarInfo::getAssetStatus()
  326. {
  327. if (mPanelAvatarp && mPanelAvatarp->haveData())
  328. {
  329. mAssetStatus = PREVIEW_ASSET_LOADED;
  330. }
  331. return mAssetStatus;
  332. }
  333. //static
  334. std::string LLFloaterAvatarInfo::getProfileURL(const std::string& user_name)
  335. {
  336. std::string url = gSavedSettings.getString("WebProfileURL");
  337. bool sl_profile = url.find("secondlife") != std::string::npos;
  338. if ((gIsInSecondLife && !sl_profile) || (!gIsInSecondLife && sl_profile))
  339. {
  340. return "";
  341. }
  342. LLStringUtil::format_map_t subs;
  343. subs["[AGENT_NAME]"] = user_name;
  344. url = LLWeb::expandURLSubstitutions(url, subs);
  345. LLStringUtil::toLower(url);
  346. return url;
  347. }