llpanelavatar.cpp 58 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261
  1. /**
  2. * @file llpanelavatar.cpp
  3. * @brief LLPanelAvatar and related class implementations
  4. *
  5. * $LicenseInfo:firstyear=2004&license=viewergpl$
  6. *
  7. * Copyright (c) 2004-2009, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #include "llviewerprecompiledheaders.h"
  33. #include "llpanelavatar.h"
  34. #include "llcachename.h"
  35. #include "llcheckboxctrl.h"
  36. #include "llclassifiedflags.h"
  37. #include "llcombobox.h"
  38. #include "lleconomy.h"
  39. #include "llfloater.h"
  40. #include "lliconctrl.h"
  41. #include "lllineeditor.h"
  42. #include "llnameeditor.h"
  43. #include "llpluginclassmedia.h"
  44. #include "llscrolllistctrl.h"
  45. #include "lltabcontainer.h"
  46. #include "lltextbox.h"
  47. #include "lltexturectrl.h"
  48. #include "lluictrlfactory.h"
  49. #include "roles_constants.h"
  50. #include "llagent.h"
  51. #include "llavataractions.h"
  52. #include "llavatartracker.h"
  53. #include "llfloateravatarinfo.h"
  54. #include "llfloaterfriends.h"
  55. #include "llfloatergroupinfo.h"
  56. #include "llfloatermediabrowser.h"
  57. #include "llfloatermute.h"
  58. #include "llfloaterworldmap.h"
  59. #include "llgridmanager.h" // For gIsInSecondLife
  60. #include "llinventorymodel.h"
  61. #include "llmutelist.h"
  62. #include "llpanelclassified.h"
  63. #include "llpanelpick.h"
  64. //MK
  65. #include "mkrlinterface.h"
  66. //mk
  67. #include "llstatusbar.h"
  68. #include "lltooldraganddrop.h"
  69. #include "llviewercontrol.h"
  70. #include "llviewermessage.h" // For send_generic_message()
  71. #include "llviewerobjectlist.h"
  72. #include "llviewerregion.h"
  73. #include "llviewertexteditor.h"
  74. #include "llvoavatar.h"
  75. #include "llweb.h"
  76. //static
  77. bool LLPanelAvatar::sAllowFirstLife = false;
  78. std::string LLPanelAvatar::sLoading;
  79. std::string LLPanelAvatar::sClickToEnlarge;
  80. std::string LLPanelAvatar::sShowOnMapNonFriend;
  81. std::string LLPanelAvatar::sShowOnMapFriendOffline;
  82. std::string LLPanelAvatar::sShowOnMapFriendOnline;
  83. std::string LLPanelAvatar::sTeleportGod;
  84. std::string LLPanelAvatar::sTeleportPrelude;
  85. std::string LLPanelAvatar::sTeleportNormal;
  86. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  87. // Class LLDropTarget
  88. //
  89. // This handy class is a simple way to drop something on another
  90. // view. It handles drop events, always setting itself to the size of
  91. // its parent.
  92. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  93. class LLDropTarget : public LLView
  94. {
  95. protected:
  96. LOG_CLASS(LLDropTarget);
  97. public:
  98. LLDropTarget(const std::string& name, const LLRect& rect,
  99. const LLUUID& agent_id);
  100. void doDrop(EDragAndDropType cargo_type, void* cargo_data);
  101. // LLView functionality
  102. bool handleDragAndDrop(S32 x, S32 y, MASK mask, bool drop,
  103. EDragAndDropType cargo_type, void* cargo_data,
  104. EAcceptance* accept, std::string& tooltip) override;
  105. void setAgentID(const LLUUID& agent_id) { mAgentID = agent_id; }
  106. protected:
  107. LLUUID mAgentID;
  108. };
  109. LLDropTarget::LLDropTarget(const std::string& name, const LLRect& rect,
  110. const LLUUID& agent_id)
  111. : LLView(name, rect, false, FOLLOWS_ALL),
  112. mAgentID(agent_id)
  113. {
  114. }
  115. void LLDropTarget::doDrop(EDragAndDropType cargo_type, void* cargo_data)
  116. {
  117. llinfos << "No operation." << llendl;
  118. }
  119. bool LLDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, bool drop,
  120. EDragAndDropType cargo_type,
  121. void* cargo_data,
  122. EAcceptance* accept,
  123. std::string& tooltip_msg)
  124. {
  125. if (getParent())
  126. {
  127. LLToolDragAndDrop::handleGiveDragAndDrop(mAgentID, LLUUID::null, drop,
  128. cargo_type, cargo_data, accept);
  129. return true;
  130. }
  131. return false;
  132. }
  133. //-----------------------------------------------------------------------------
  134. // LLPanelAvatarTab class
  135. //-----------------------------------------------------------------------------
  136. LLPanelAvatarTab::LLPanelAvatarTab(const std::string& name, const LLRect& rect,
  137. LLPanelAvatar* panel_avatar)
  138. : LLPanel(name, rect),
  139. mPanelAvatar(panel_avatar),
  140. mDataRequested(false)
  141. {
  142. }
  143. //virtual
  144. void LLPanelAvatarTab::draw()
  145. {
  146. refresh();
  147. LLPanel::draw();
  148. }
  149. void LLPanelAvatarTab::sendAvatarProfileRequestIfNeeded(S32 type)
  150. {
  151. if (!mDataRequested)
  152. {
  153. mDataRequested = true;
  154. LLAvatarProperties::sendGenericRequest(mPanelAvatar->getAvatarID(),
  155. type);
  156. }
  157. }
  158. //-----------------------------------------------------------------------------
  159. // LLPanelAvatarSecondLife class
  160. //-----------------------------------------------------------------------------
  161. LLPanelAvatarSecondLife::LLPanelAvatarSecondLife(const std::string& name,
  162. const LLRect& rect,
  163. LLPanelAvatar* panel_avatar)
  164. : LLPanelAvatarTab(name, rect, panel_avatar),
  165. mPartnerNamePending(false)
  166. {
  167. }
  168. bool LLPanelAvatarSecondLife::postBuild()
  169. {
  170. mLegacyName = getChild<LLNameEditor>("name");
  171. mCompleteName = getChild<LLNameEditor>("complete_name");
  172. mBornText = getChild<LLLineEditor>("born");
  173. mBornText->setEnabled(false);
  174. mAccountInfoText = getChild<LLTextBox>("acct");
  175. childSetEnabled("partner_edit", false);
  176. childSetAction("partner_help", onClickPartnerHelp, this);
  177. mPartnerInfoButton = getChild<LLButton>("partner_info");
  178. mPartnerInfoButton->setClickedCallback(onClickPartnerInfo, this);
  179. mPartnerInfoButton->setEnabled(mPartnerID.notNull());
  180. mAboutCharLimitText = getChild<LLTextBox>("sl_about_limit");
  181. bool limited = LLPanelAvatar::sAllowFirstLife &&
  182. !(gSavedSettings.getBool("UseAgentProfileCap") &&
  183. gAgent.hasRegionCapability("AgentProfile"));
  184. mAboutCharLimitText->setVisible(limited);
  185. mAbout2ndLifeText = getChild<LLTextEditor>("about");
  186. mAbout2ndLifeText->setVisible(LLPanelAvatar::sAllowFirstLife);
  187. mShowInSearchCheck = getChild<LLCheckBoxCtrl>("show_in_search_chk");
  188. mShowInSearchCheck->setVisible(LLPanelAvatar::sAllowFirstLife);
  189. mShowInSearchHelpButton = getChild<LLButton>("show_in_search_help_btn");
  190. mShowInSearchHelpButton->setClickedCallback(onClickShowInSearchHelp, this);
  191. mShowInSearchHelpButton->setVisible(LLPanelAvatar::sAllowFirstLife);
  192. mOnlineText = getChild<LLTextBox>("online_yes");
  193. mOnlineText->setVisible(false);
  194. mFindOnMapButton = getChild<LLButton>("find_on_map_btn");
  195. mFindOnMapButton->setClickedCallback(LLPanelAvatar::onClickTrack,
  196. getPanelAvatar());
  197. mOfferTPButton = getChild<LLButton>("offer_tp_btn");
  198. mOfferTPButton->setClickedCallback(LLPanelAvatar::onClickOfferTeleport,
  199. getPanelAvatar());
  200. mRequestTPButton = getChild<LLButton>("request_tp_btn");
  201. mRequestTPButton->setClickedCallback(LLPanelAvatar::onClickRequestTeleport,
  202. getPanelAvatar());
  203. mAddFriendButton = getChild<LLButton>("add_friend_btn");
  204. mAddFriendButton->setClickedCallback(LLPanelAvatar::onClickAddFriend,
  205. getPanelAvatar());
  206. mPayButton = getChild<LLButton>("pay_btn");
  207. mPayButton->setClickedCallback(LLPanelAvatar::onClickPay,
  208. getPanelAvatar());
  209. mIMButton = getChild<LLButton>("im_btn");
  210. mIMButton->setClickedCallback(LLPanelAvatar::onClickIM, getPanelAvatar());
  211. mMuteButton = getChild<LLButton>("mute_btn");
  212. mMuteButton->setClickedCallback(LLPanelAvatar::onClickMute,
  213. getPanelAvatar());
  214. mGroupsListCtrl = getChild<LLScrollListCtrl>("groups");
  215. mGroupsListCtrl->setDoubleClickCallback(onDoubleClickGroup);
  216. mGroupsListCtrl->setCallbackUserData(this);
  217. bool square = gSavedSettings.getBool("ProfilePictureSquare");
  218. m2ndLifePicture = getChild<LLTextureCtrl>("img");
  219. m2ndLifePicture->setFallbackImageName("default_profile_picture.j2c");
  220. m2ndLifePicture->setDisplayRatio(square ? 1.f : 0.f);
  221. LLCheckBoxCtrl* ratiocheckp = getChild<LLCheckBoxCtrl>("ratio_chk");
  222. ratiocheckp->setCommitCallback(onCommitDisplayRatioCheck);
  223. ratiocheckp->setCallbackUserData(this);
  224. ratiocheckp->set(square);
  225. enableControls(getPanelAvatar()->getAvatarID() == gAgentID);
  226. return true;
  227. }
  228. void LLPanelAvatarSecondLife::refresh()
  229. {
  230. updatePartnerName();
  231. static LLCachedControl<bool> use_cap(gSavedSettings, "UseAgentProfileCap");
  232. bool limited = LLPanelAvatar::sAllowFirstLife &&
  233. !(use_cap && gAgent.hasRegionCapability("AgentProfile"));
  234. mAboutCharLimitText->setVisible(limited);
  235. }
  236. void LLPanelAvatarSecondLife::updatePartnerName()
  237. {
  238. bool has_partner = mPartnerID.notNull();
  239. mPartnerInfoButton->setEnabled(has_partner);
  240. if (has_partner && mPartnerNamePending)
  241. {
  242. std::string first, last;
  243. if (gCacheNamep && gCacheNamep->getName(mPartnerID, first, last))
  244. {
  245. childSetTextArg("partner_edit", "[FIRST]", first);
  246. childSetTextArg("partner_edit", "[LAST]", last);
  247. mPartnerNamePending = false;
  248. }
  249. }
  250. }
  251. // Empty the data out of the controls, since we have to wait for new data off
  252. // the network.
  253. void LLPanelAvatarSecondLife::clearControls()
  254. {
  255. m2ndLifePicture->setImageAssetID(LLUUID::null);
  256. mAbout2ndLifeText->setValue("");
  257. mBornText->setValue("");
  258. mAccountInfoText->setValue("");
  259. childSetTextArg("partner_edit", "[FIRST]", LLStringUtil::null);
  260. childSetTextArg("partner_edit", "[LAST]", LLStringUtil::null);
  261. mPartnerID.setNull();
  262. mGroupsListCtrl->deleteAllItems();
  263. }
  264. void LLPanelAvatarSecondLife::enableControls(bool own_avatar)
  265. {
  266. m2ndLifePicture->setEnabled(own_avatar);
  267. mAbout2ndLifeText->setEnabled(own_avatar);
  268. mShowInSearchCheck->setVisible(own_avatar);
  269. mShowInSearchCheck->setEnabled(own_avatar);
  270. mShowInSearchHelpButton->setVisible(own_avatar);
  271. mShowInSearchHelpButton->setEnabled(own_avatar);
  272. }
  273. //static
  274. void LLPanelAvatarSecondLife::onCommitDisplayRatioCheck(LLUICtrl* ctrl,
  275. void* data)
  276. {
  277. LLPanelAvatarSecondLife* self = (LLPanelAvatarSecondLife*)data;
  278. LLCheckBoxCtrl* check = (LLCheckBoxCtrl*)ctrl;
  279. if (self && check)
  280. {
  281. bool checked = check->get();
  282. self->m2ndLifePicture->setDisplayRatio(checked ? 1.f : 0.f);
  283. gSavedSettings.setBool("ProfilePictureSquare", checked);
  284. }
  285. }
  286. //static
  287. void LLPanelAvatarSecondLife::onDoubleClickGroup(void* data)
  288. {
  289. LLPanelAvatarSecondLife* self = (LLPanelAvatarSecondLife*)data;
  290. if (!self) return;
  291. LLScrollListItem* item = self->mGroupsListCtrl->getFirstSelected();
  292. if (item && item->getUUID().notNull())
  293. {
  294. llinfos << "Show group info " << item->getUUID() << llendl;
  295. LLFloaterGroupInfo::showFromUUID(item->getUUID());
  296. }
  297. }
  298. //static
  299. void LLPanelAvatarSecondLife::onClickShowInSearchHelp(void*)
  300. {
  301. gNotifications.add("ClickPublishHelpAvatar");
  302. }
  303. //static
  304. void LLPanelAvatarSecondLife::onClickPartnerHelp(void*)
  305. {
  306. gNotifications.add("ClickPartnerHelpAvatar", LLSD(), LLSD(),
  307. onClickPartnerHelpLoadURL);
  308. }
  309. //static
  310. bool LLPanelAvatarSecondLife::onClickPartnerHelpLoadURL(const LLSD& notification,
  311. const LLSD& response)
  312. {
  313. if (LLNotification::getSelectedOption(notification, response) == 0)
  314. {
  315. LLWeb::loadURL("http://secondlife.com/partner");
  316. }
  317. return false;
  318. }
  319. //static
  320. void LLPanelAvatarSecondLife::onClickPartnerInfo(void* data)
  321. {
  322. LLPanelAvatarSecondLife* self = (LLPanelAvatarSecondLife*)data;
  323. if (self && self->mPartnerID.notNull())
  324. {
  325. LLFloaterAvatarInfo::showFromProfile(self->mPartnerID,
  326. self->getScreenRect());
  327. }
  328. }
  329. //-----------------------------------------------------------------------------
  330. // LLPanelAvatarFirstLife class
  331. //-----------------------------------------------------------------------------
  332. LLPanelAvatarFirstLife::LLPanelAvatarFirstLife(const std::string& name,
  333. const LLRect& rect,
  334. LLPanelAvatar* panel_avatar)
  335. : LLPanelAvatarTab(name, rect, panel_avatar)
  336. {
  337. }
  338. bool LLPanelAvatarFirstLife::postBuild()
  339. {
  340. m1stLifePicture = getChild<LLTextureCtrl>("img");
  341. m1stLifePicture->setFallbackImageName("default_profile_picture.j2c");
  342. mAbout1stLifeText = getChild<LLTextEditor>("about");
  343. enableControls(getPanelAvatar()->getAvatarID() == gAgentID);
  344. return true;
  345. }
  346. void LLPanelAvatarFirstLife::enableControls(bool own_avatar)
  347. {
  348. m1stLifePicture->setEnabled(own_avatar);
  349. mAbout1stLifeText->setEnabled(own_avatar);
  350. }
  351. //-----------------------------------------------------------------------------
  352. // LLPanelAvatarWeb class
  353. //-----------------------------------------------------------------------------
  354. LLPanelAvatarWeb::LLPanelAvatarWeb(const std::string& name, const LLRect& rect,
  355. LLPanelAvatar* panel_avatar)
  356. : LLPanelAvatarTab(name, rect, panel_avatar)
  357. {
  358. }
  359. bool LLPanelAvatarWeb::postBuild()
  360. {
  361. childSetKeystrokeCallback("url_edit", onURLKeystroke, this);
  362. childSetCommitCallback("load", onCommitLoad, this);
  363. mWebProfileBtn = getChild<LLFlyoutButton>("sl_web_profile");
  364. mWebProfileBtn->setCommitCallback(onCommitSLWebProfile);
  365. mWebProfileBtn->setCallbackUserData(this);
  366. bool enabled = !LLFloaterAvatarInfo::getProfileURL("").empty();
  367. mWebProfileBtn->setEnabled(enabled);
  368. childSetAction("web_profile_help", onClickWebProfileHelp, this);
  369. childSetCommitCallback("url_edit", onCommitURL, this);
  370. childSetControlName("auto_load", "AutoLoadWebProfiles");
  371. mWebBrowser = getChild<LLMediaCtrl>("profile_html");
  372. mWebBrowser->addObserver(this);
  373. return true;
  374. }
  375. void LLPanelAvatarWeb::refresh()
  376. {
  377. if (!mNavigateTo.empty())
  378. {
  379. llinfos << "Loading " << mNavigateTo << llendl;
  380. mWebBrowser->navigateTo(mNavigateTo);
  381. mNavigateTo.clear();
  382. }
  383. std::string user_name = getPanelAvatar()->getAvatarUserName();
  384. bool enabled = !LLFloaterAvatarInfo::getProfileURL(user_name).empty();
  385. mWebProfileBtn->setEnabled(enabled);
  386. }
  387. void LLPanelAvatarWeb::enableControls(bool own_avatar)
  388. {
  389. mCanEditURL = own_avatar;
  390. childSetEnabled("url_edit", own_avatar);
  391. }
  392. void LLPanelAvatarWeb::setWebURL(std::string url)
  393. {
  394. bool changed_url = mHome != url;
  395. mHome = url;
  396. bool have_url = !mHome.empty();
  397. childSetText("url_edit", mHome);
  398. childSetEnabled("load", have_url);
  399. if (have_url && gSavedSettings.getBool("AutoLoadWebProfiles"))
  400. {
  401. if (changed_url)
  402. {
  403. load(mHome);
  404. }
  405. }
  406. else
  407. {
  408. childSetVisible("profile_html", false);
  409. childSetVisible("status_text", false);
  410. }
  411. }
  412. //static
  413. void LLPanelAvatarWeb::onCommitURL(LLUICtrl* ctrl, void* data)
  414. {
  415. LLPanelAvatarWeb* self = (LLPanelAvatarWeb*)data;
  416. if (self)
  417. {
  418. self->mHome = self->childGetText("url_edit");
  419. self->load(self->childGetText("url_edit"));
  420. }
  421. }
  422. //static
  423. void LLPanelAvatarWeb::onClickWebProfileHelp(void*)
  424. {
  425. gNotifications.add("ClickWebProfileHelpAvatar");
  426. }
  427. void LLPanelAvatarWeb::load(const std::string& url)
  428. {
  429. bool have_url = !url.empty();
  430. childSetVisible("profile_html", have_url);
  431. childSetVisible("status_text", have_url);
  432. childSetText("status_text", LLStringUtil::null);
  433. if (have_url)
  434. {
  435. if (mCanEditURL)
  436. {
  437. childSetEnabled("url_edit", false);
  438. }
  439. childSetText("url_edit", LLPanelAvatar::sLoading);
  440. mNavigateTo = url;
  441. }
  442. }
  443. //static
  444. void LLPanelAvatarWeb::onURLKeystroke(LLLineEditor* editor, void* data)
  445. {
  446. LLPanelAvatarWeb* self = (LLPanelAvatarWeb*)data;
  447. if (self && editor)
  448. {
  449. const std::string& url = editor->getText();
  450. self->childSetEnabled("load", !url.empty());
  451. }
  452. }
  453. //static
  454. void LLPanelAvatarWeb::onCommitLoad(LLUICtrl* ctrl, void* data)
  455. {
  456. LLPanelAvatarWeb* self = (LLPanelAvatarWeb*)data;
  457. if (!self || !ctrl) return;
  458. std::string valstr = ctrl->getValue().asString();
  459. std::string urlstr = self->childGetText("url_edit");
  460. if (valstr == "builtin")
  461. {
  462. // Open in built-in browser
  463. if (!self->mHome.empty())
  464. {
  465. LLFloaterMediaBrowser::showInstance(urlstr);
  466. }
  467. }
  468. else if (valstr == "open")
  469. {
  470. // Open in user's external browser
  471. if (!urlstr.empty())
  472. {
  473. LLWeb::loadURLExternal(urlstr);
  474. }
  475. }
  476. else if (valstr == "home")
  477. {
  478. // Reload profile owner's home page
  479. if (!self->mHome.empty())
  480. {
  481. self->mWebBrowser->setTrusted(false);
  482. self->load(self->mHome);
  483. }
  484. }
  485. else if (!urlstr.empty())
  486. {
  487. // Load url string into browser panel
  488. self->mWebBrowser->setTrusted(false);
  489. self->load(urlstr);
  490. }
  491. }
  492. //static
  493. void LLPanelAvatarWeb::onCommitSLWebProfile(LLUICtrl* ctrl, void* data)
  494. {
  495. LLPanelAvatarWeb* self = (LLPanelAvatarWeb*)data;
  496. if (!self || !ctrl) return;
  497. std::string user_name = self->getPanelAvatar()->getAvatarUserName();
  498. if (user_name.empty()) return;
  499. std::string urlstr = LLFloaterAvatarInfo::getProfileURL(user_name);
  500. if (urlstr.empty()) return;
  501. std::string valstr = ctrl->getValue().asString();
  502. if (valstr == "sl_builtin")
  503. {
  504. // Open in a trusted built-in browser
  505. LLFloaterMediaBrowser::showInstance(urlstr, true);
  506. }
  507. else if (valstr == "sl_open")
  508. {
  509. // Open in user's external browser
  510. LLWeb::loadURLExternal(urlstr);
  511. }
  512. else
  513. {
  514. // Load SL's web-based avatar profile (trusted)
  515. self->mWebBrowser->setTrusted(true);
  516. self->load(urlstr);
  517. }
  518. }
  519. void LLPanelAvatarWeb::handleMediaEvent(LLPluginClassMedia* self,
  520. EMediaEvent event)
  521. {
  522. switch (event)
  523. {
  524. case MEDIA_EVENT_STATUS_TEXT_CHANGED:
  525. childSetText("status_text", self->getStatusText());
  526. break;
  527. case MEDIA_EVENT_LOCATION_CHANGED:
  528. childSetText("url_edit", self->getLocation());
  529. enableControls(mCanEditURL);
  530. default:
  531. // Having a default case makes the compiler happy.
  532. break;
  533. }
  534. }
  535. //-----------------------------------------------------------------------------
  536. // LLPanelAvatarAdvanced class
  537. //-----------------------------------------------------------------------------
  538. LLPanelAvatarAdvanced::LLPanelAvatarAdvanced(const std::string& name,
  539. const LLRect& rect,
  540. LLPanelAvatar* panel_avatar)
  541. : LLPanelAvatarTab(name, rect, panel_avatar),
  542. mWantToCount(0),
  543. mSkillsCount(0)
  544. {
  545. }
  546. bool LLPanelAvatarAdvanced::postBuild()
  547. {
  548. mWantToEdit = getChild<LLLineEditor>("want_to_edit");
  549. mWantToEdit->setVisible(LLPanelAvatar::sAllowFirstLife);
  550. mSkillsEdit = getChild<LLLineEditor>("skills_edit");
  551. mSkillsEdit->setVisible(LLPanelAvatar::sAllowFirstLife);
  552. const size_t want_to_check_size = LL_ARRAY_SIZE(mWantToCheck);
  553. for (size_t i = 0; i < want_to_check_size; ++i)
  554. {
  555. mWantToCheck[i] = NULL;
  556. }
  557. const size_t skills_check_size = LL_ARRAY_SIZE(mSkillsCheck);
  558. for (size_t i = 0; i < skills_check_size; ++i)
  559. {
  560. mSkillsCheck[i] = NULL;
  561. }
  562. mWantToCount = want_to_check_size < 8 ? want_to_check_size : 8;
  563. for (S32 i = 0; i < mWantToCount; ++i)
  564. {
  565. std::string ctlname = llformat("chk%d", i);
  566. mWantToCheck[i] = getChild<LLCheckBoxCtrl>(ctlname.c_str());
  567. }
  568. mSkillsCount = skills_check_size < 6 ? skills_check_size : 6;
  569. for (S32 i = 0; i < mSkillsCount; ++i)
  570. {
  571. // Find the Skills checkboxes and save off their controls
  572. std::string ctlname = llformat("schk%d", i);
  573. mSkillsCheck[i] = getChild<LLCheckBoxCtrl>(ctlname.c_str());
  574. }
  575. return true;
  576. }
  577. void LLPanelAvatarAdvanced::enableControls(bool own_avatar)
  578. {
  579. for (S32 i = 0; i < mWantToCount; ++i)
  580. {
  581. if (mWantToCheck[i])
  582. {
  583. mWantToCheck[i]->setEnabled(own_avatar);
  584. }
  585. }
  586. for (S32 i = 0; i < mSkillsCount; ++i)
  587. {
  588. if (mSkillsCheck[i])
  589. {
  590. mSkillsCheck[i]->setEnabled(own_avatar);
  591. }
  592. }
  593. if (mWantToEdit && mSkillsEdit)
  594. {
  595. mWantToEdit->setEnabled(own_avatar);
  596. mSkillsEdit->setEnabled(own_avatar);
  597. }
  598. childSetEnabled("languages_edit", own_avatar);
  599. }
  600. void LLPanelAvatarAdvanced::setWantSkills(U32 want_to_mask,
  601. const std::string& want_to_text,
  602. U32 skills_mask,
  603. const std::string& skills_text,
  604. const std::string& languages_text)
  605. {
  606. static LLCachedControl<LLColor4U> color_off(gColors, "LabelDisabledColor");
  607. static LLCachedControl<LLColor4U> color_on(gColors, "LabelTextColor");
  608. LLColor4 enabled_color(color_on);
  609. LLColor4 disabled_color(color_off);
  610. for (S32 i = 0; i < mWantToCount; ++i)
  611. {
  612. bool enabled = want_to_mask & (1 << i);
  613. mWantToCheck[i]->set(enabled);
  614. mWantToCheck[i]->setDisabledColor(enabled ? enabled_color
  615. : disabled_color);
  616. }
  617. for (S32 i = 0; i < mSkillsCount; ++i)
  618. {
  619. bool enabled = skills_mask & (1 << i);
  620. mSkillsCheck[i]->set(enabled);
  621. mSkillsCheck[i]->setDisabledColor(enabled ? enabled_color
  622. : disabled_color);
  623. }
  624. if (mWantToEdit && mSkillsEdit)
  625. {
  626. mWantToEdit->setText(want_to_text);
  627. mSkillsEdit->setText(skills_text);
  628. }
  629. childSetText("languages_edit", languages_text);
  630. }
  631. void LLPanelAvatarAdvanced::getWantSkills(U32& want_to_mask,
  632. std::string& want_to_text,
  633. U32& skills_mask,
  634. std::string& skills_text,
  635. std::string& languages_text)
  636. {
  637. want_to_mask = 0;
  638. for (S32 t = 0; t < mWantToCount; ++t)
  639. {
  640. if (mWantToCheck[t]->get())
  641. {
  642. want_to_mask |= 1 << t;
  643. }
  644. }
  645. skills_mask = 0;
  646. for (S32 t = 0; t < mSkillsCount; ++t)
  647. {
  648. if (mSkillsCheck[t]->get())
  649. {
  650. skills_mask |= 1 << t;
  651. }
  652. }
  653. if (mWantToEdit)
  654. {
  655. want_to_text = mWantToEdit->getText();
  656. }
  657. else
  658. {
  659. want_to_text.clear();
  660. }
  661. if (mSkillsEdit)
  662. {
  663. skills_text = mSkillsEdit->getText();
  664. }
  665. else
  666. {
  667. skills_text.clear();
  668. }
  669. languages_text = childGetText("languages_edit");
  670. }
  671. //-----------------------------------------------------------------------------
  672. // LLPanelAvatarNotes class
  673. //-----------------------------------------------------------------------------
  674. LLPanelAvatarNotes::LLPanelAvatarNotes(const std::string& name,
  675. const LLRect& rect,
  676. LLPanelAvatar* panel_avatar)
  677. : LLPanelAvatarTab(name, rect, panel_avatar)
  678. {
  679. }
  680. bool LLPanelAvatarNotes::postBuild()
  681. {
  682. mNotesText = getChild<LLTextEditor>("notes edit");
  683. mNotesText->setCommitCallback(onCommitNotes);
  684. mNotesText->setCallbackUserData(this);
  685. mNotesText->setCommitOnFocusLost(true);
  686. return true;
  687. }
  688. void LLPanelAvatarNotes::refresh()
  689. {
  690. sendAvatarProfileRequestIfNeeded(APT_NOTES);
  691. }
  692. void LLPanelAvatarNotes::clearControls()
  693. {
  694. mNotesText->setEnabled(false);
  695. mNotesText->setText(LLPanelAvatar::sLoading);
  696. }
  697. //static
  698. void LLPanelAvatarNotes::onCommitNotes(LLUICtrl*, void* userdata)
  699. {
  700. LLPanelAvatarNotes* self = (LLPanelAvatarNotes*)userdata;
  701. if (self)
  702. {
  703. self->getPanelAvatar()->sendAvatarNotesUpdate();
  704. }
  705. }
  706. //-----------------------------------------------------------------------------
  707. // LLPanelAvatarClassified class
  708. //-----------------------------------------------------------------------------
  709. LLPanelAvatarClassified::LLPanelAvatarClassified(const std::string& name,
  710. const LLRect& rect,
  711. LLPanelAvatar* panel_avatar)
  712. : LLPanelAvatarTab(name, rect, panel_avatar),
  713. mClassifiedTab(NULL),
  714. mButtonNew(NULL),
  715. mButtonDelete(NULL),
  716. mLoadingText(NULL)
  717. {
  718. }
  719. bool LLPanelAvatarClassified::postBuild()
  720. {
  721. mClassifiedTab = getChild<LLTabContainer>("classified tab");
  722. mButtonNew = getChild<LLButton>("New...");
  723. mButtonNew->setClickedCallback(onClickNew, this);
  724. mButtonDelete = getChild<LLButton>("Delete...");
  725. mButtonDelete->setClickedCallback(onClickDelete, this);
  726. mLoadingText = getChild<LLTextBox>("loading_text");
  727. return true;
  728. }
  729. void LLPanelAvatarClassified::refresh()
  730. {
  731. bool is_self = getPanelAvatar()->getAvatarID() == gAgentID;
  732. S32 tab_count = mClassifiedTab ? mClassifiedTab->getTabCount() : 0;
  733. bool allow_new = tab_count < MAX_CLASSIFIEDS;
  734. bool allow_delete = tab_count > 0;
  735. bool show_help = tab_count == 0;
  736. // *HACK: Do not allow making new classifieds from inside the directory.
  737. // The logic for save/don't save when closing is too hairy, and the
  738. // directory is conceptually read-only. JC
  739. bool in_directory = false;
  740. LLView* view = this;
  741. while (view)
  742. {
  743. if (view->getName() == "directory")
  744. {
  745. in_directory = true;
  746. break;
  747. }
  748. view = view->getParent();
  749. }
  750. if (mButtonNew)
  751. {
  752. mButtonNew->setEnabled(is_self && !in_directory && allow_new);
  753. mButtonNew->setVisible(!in_directory);
  754. }
  755. if (mButtonDelete)
  756. {
  757. mButtonDelete->setEnabled(is_self && !in_directory && allow_delete);
  758. mButtonDelete->setVisible(!in_directory);
  759. }
  760. if (mClassifiedTab)
  761. {
  762. mClassifiedTab->setVisible(!show_help);
  763. }
  764. sendAvatarProfileRequestIfNeeded(APT_CLASSIFIEDS);
  765. }
  766. bool LLPanelAvatarClassified::canClose()
  767. {
  768. if (!mClassifiedTab) return true;
  769. for (S32 i = 0; i < mClassifiedTab->getTabCount(); ++i)
  770. {
  771. LLPanelClassified* panel =
  772. (LLPanelClassified*)mClassifiedTab->getPanelByIndex(i);
  773. if (panel && !panel->canClose())
  774. {
  775. return false;
  776. }
  777. }
  778. return true;
  779. }
  780. bool LLPanelAvatarClassified::titleIsValid()
  781. {
  782. if (mClassifiedTab)
  783. {
  784. LLPanelClassified* panel =
  785. (LLPanelClassified*)mClassifiedTab->getCurrentPanel();
  786. if (panel && !panel->titleIsValid())
  787. {
  788. return false;
  789. }
  790. }
  791. return true;
  792. }
  793. void LLPanelAvatarClassified::apply()
  794. {
  795. if (!mClassifiedTab) return;
  796. for (S32 i = 0; i < mClassifiedTab->getTabCount(); ++i)
  797. {
  798. LLPanelClassified* panel =
  799. (LLPanelClassified*)mClassifiedTab->getPanelByIndex(i);
  800. if (panel)
  801. {
  802. panel->apply();
  803. }
  804. }
  805. }
  806. void LLPanelAvatarClassified::deleteClassifiedPanels()
  807. {
  808. if (mClassifiedTab)
  809. {
  810. mClassifiedTab->deleteAllTabs();
  811. }
  812. if (mButtonNew)
  813. {
  814. mButtonNew->setVisible(false);
  815. }
  816. if (mButtonDelete)
  817. {
  818. mButtonDelete->setVisible(false);
  819. }
  820. if (mLoadingText)
  821. {
  822. mLoadingText->setVisible(true);
  823. }
  824. }
  825. void LLPanelAvatarClassified::processAvatarClassifiedReply(LLAvatarClassifieds* data)
  826. {
  827. // Note: we do not remove old panels. We need to be able to process
  828. // multiple packets for people who have lots of classifieds. JC
  829. LLUUID id;
  830. std::string classified_name;
  831. for (LLAvatarClassifieds::map_t::iterator it = data->mMap.begin(),
  832. end = data->mMap.end();
  833. it != end; ++it)
  834. {
  835. LLPanelClassified* panelp = new LLPanelClassified(false, false);
  836. panelp->setClassifiedID(it->first);
  837. // This will request data from the server when the classified is first
  838. // drawn
  839. panelp->markForServerRequest();
  840. // The button should automatically truncate long names for us
  841. if (mClassifiedTab)
  842. {
  843. mClassifiedTab->addTabPanel(panelp, it->second);
  844. }
  845. }
  846. // Make sure somebody is highlighted. This works even if there are no tabs
  847. // in the container.
  848. if (mClassifiedTab)
  849. {
  850. mClassifiedTab->selectFirstTab();
  851. }
  852. if (mButtonNew)
  853. {
  854. mButtonNew->setVisible(true);
  855. }
  856. if (mButtonDelete)
  857. {
  858. mButtonDelete->setVisible(true);
  859. }
  860. if (mLoadingText)
  861. {
  862. mLoadingText->setVisible(false);
  863. }
  864. }
  865. // Create a new classified panel. It will automatically handle generating its
  866. // own id when it is time to save.
  867. //static
  868. void LLPanelAvatarClassified::onClickNew(void* data)
  869. {
  870. LLPanelAvatarClassified* self = (LLPanelAvatarClassified*)data;
  871. if (!self) return;
  872. //MK
  873. if (gRLenabled && gRLInterface.mContainsShowloc)
  874. {
  875. return;
  876. }
  877. //mk
  878. gNotifications.add("AddClassified", LLSD(), LLSD(),
  879. boost::bind(&LLPanelAvatarClassified::callbackNew, self,
  880. _1, _2));
  881. }
  882. bool LLPanelAvatarClassified::callbackNew(const LLSD& notification,
  883. const LLSD& response)
  884. {
  885. if (LLNotification::getSelectedOption(notification, response) == 0)
  886. {
  887. LLPanelClassified* panelp = new LLPanelClassified(false, false);
  888. panelp->initNewClassified();
  889. if (mClassifiedTab)
  890. {
  891. mClassifiedTab->addTabPanel(panelp, panelp->getClassifiedName());
  892. mClassifiedTab->selectLastTab();
  893. }
  894. }
  895. return false;
  896. }
  897. //static
  898. void LLPanelAvatarClassified::onClickDelete(void* data)
  899. {
  900. LLPanelAvatarClassified* self = (LLPanelAvatarClassified*)data;
  901. if (!self) return;
  902. LLPanelClassified* panelp = NULL;
  903. if (self->mClassifiedTab)
  904. {
  905. panelp = (LLPanelClassified*)self->mClassifiedTab->getCurrentPanel();
  906. }
  907. if (!panelp) return;
  908. LLSD args;
  909. args["NAME"] = panelp->getClassifiedName();
  910. gNotifications.add("DeleteClassified", args, LLSD(),
  911. boost::bind(&LLPanelAvatarClassified::callbackDelete,
  912. self, _1, _2));
  913. }
  914. bool LLPanelAvatarClassified::callbackDelete(const LLSD& notification,
  915. const LLSD& response)
  916. {
  917. if (LLNotification::getSelectedOption(notification, response) != 0 ||
  918. !mClassifiedTab)
  919. {
  920. return false;
  921. }
  922. LLPanelClassified* panelp =
  923. (LLPanelClassified*)mClassifiedTab->getCurrentPanel();
  924. if (!panelp)
  925. {
  926. return false;
  927. }
  928. LLAvatarProperties::sendClassifiedDelete(panelp->getClassifiedID());
  929. if (mClassifiedTab)
  930. {
  931. mClassifiedTab->removeTabPanel(panelp);
  932. }
  933. delete panelp;
  934. return false;
  935. }
  936. //-----------------------------------------------------------------------------
  937. // LLPanelAvatarPicks class
  938. //-----------------------------------------------------------------------------
  939. LLPanelAvatarPicks::LLPanelAvatarPicks(const std::string& name,
  940. const LLRect& rect,
  941. LLPanelAvatar* panel_avatar)
  942. : LLPanelAvatarTab(name, rect, panel_avatar),
  943. mPicksTab(NULL),
  944. mButtonNew(NULL),
  945. mButtonDelete(NULL),
  946. mLoadingText(NULL)
  947. {
  948. }
  949. bool LLPanelAvatarPicks::postBuild()
  950. {
  951. mPicksTab = getChild<LLTabContainer>("picks tab");
  952. mButtonNew = getChild<LLButton>("New...");
  953. mButtonNew->setClickedCallback(onClickNew, this);
  954. mButtonDelete = getChild<LLButton>("Delete...");
  955. mButtonDelete->setClickedCallback(onClickDelete, this);
  956. mLoadingText = getChild<LLTextBox>("loading_text");
  957. return true;
  958. }
  959. void LLPanelAvatarPicks::refresh()
  960. {
  961. bool is_self = getPanelAvatar()->getAvatarID() == gAgentID;
  962. bool editable = getPanelAvatar()->isEditable();
  963. S32 tab_count = mPicksTab ? mPicksTab->getTabCount() : 0;
  964. if (mButtonNew)
  965. {
  966. S32 max_picks = LLEconomy::getInstance()->getPicksLimit();
  967. mButtonNew->setEnabled(is_self && tab_count < max_picks);
  968. mButtonNew->setVisible(is_self && editable);
  969. }
  970. if (mButtonDelete)
  971. {
  972. mButtonDelete->setEnabled(is_self && tab_count > 0);
  973. mButtonDelete->setVisible(is_self && editable);
  974. }
  975. sendAvatarProfileRequestIfNeeded(APT_PICKS);
  976. }
  977. void LLPanelAvatarPicks::deletePickPanels()
  978. {
  979. if (mPicksTab)
  980. {
  981. mPicksTab->deleteAllTabs();
  982. }
  983. if (mButtonNew)
  984. {
  985. mButtonNew->setVisible(false);
  986. }
  987. if (mButtonDelete)
  988. {
  989. mButtonDelete->setVisible(false);
  990. }
  991. if (mLoadingText)
  992. {
  993. mLoadingText->setVisible(true);
  994. }
  995. }
  996. void LLPanelAvatarPicks::processAvatarPicksReply(LLAvatarPicks* data)
  997. {
  998. // Clear out all the old panels. We will replace them with the correct
  999. // number of new panels.
  1000. deletePickPanels();
  1001. // The database needs to know for which user to look up picks.
  1002. LLUUID avatar_id = data->mAvatarId;
  1003. for (LLAvatarPicks::map_t::iterator it = data->mMap.begin(),
  1004. end = data->mMap.end();
  1005. it != end; ++it)
  1006. {
  1007. LLPanelPick* panelp = new LLPanelPick(false);
  1008. panelp->setPickID(it->first, avatar_id);
  1009. // This will request data from the server when the pick is first drawn
  1010. panelp->markForServerRequest();
  1011. // The button should automatically truncate long names for us
  1012. if (mPicksTab)
  1013. {
  1014. mPicksTab->addTabPanel(panelp, it->second);
  1015. }
  1016. }
  1017. // Make sure somebody is highlighted. This works even if there are no tabs
  1018. // in the container.
  1019. if (mPicksTab)
  1020. {
  1021. mPicksTab->selectFirstTab();
  1022. }
  1023. if (mButtonNew)
  1024. {
  1025. mButtonNew->setVisible(true);
  1026. }
  1027. if (mButtonDelete)
  1028. {
  1029. mButtonDelete->setVisible(true);
  1030. }
  1031. if (mLoadingText)
  1032. {
  1033. mLoadingText->setVisible(false);
  1034. }
  1035. }
  1036. // Create a new pick panel. It will automatically handle generating its own id
  1037. // when it is time to save.
  1038. //static
  1039. void LLPanelAvatarPicks::onClickNew(void* data)
  1040. {
  1041. LLPanelAvatarPicks* self = (LLPanelAvatarPicks*)data;
  1042. if (!self) return;
  1043. //MK
  1044. if (gRLenabled && gRLInterface.mContainsShowloc)
  1045. {
  1046. return;
  1047. }
  1048. //mk
  1049. LLPanelPick* panelp = new LLPanelPick(false);
  1050. panelp->initNewPick();
  1051. if (self->mPicksTab)
  1052. {
  1053. self->mPicksTab->addTabPanel(panelp, panelp->getPickName());
  1054. self->mPicksTab->selectLastTab();
  1055. }
  1056. }
  1057. //static
  1058. void LLPanelAvatarPicks::onClickDelete(void* data)
  1059. {
  1060. LLPanelAvatarPicks* self = (LLPanelAvatarPicks*)data;
  1061. if (!self) return;
  1062. LLPanelPick* panelp = NULL;
  1063. if (self->mPicksTab)
  1064. {
  1065. panelp = (LLPanelPick*)self->mPicksTab->getCurrentPanel();
  1066. }
  1067. if (!panelp) return;
  1068. LLSD args;
  1069. args["PICK"] = panelp->getPickName();
  1070. gNotifications.add("DeleteAvatarPick", args, LLSD(),
  1071. boost::bind(&LLPanelAvatarPicks::callbackDelete, self,
  1072. _1, _2));
  1073. }
  1074. //static
  1075. bool LLPanelAvatarPicks::callbackDelete(const LLSD& notification,
  1076. const LLSD& response)
  1077. {
  1078. if (LLNotification::getSelectedOption(notification, response) != 0)
  1079. {
  1080. return false;
  1081. }
  1082. LLPanelPick* panelp = NULL;
  1083. if (mPicksTab)
  1084. {
  1085. panelp = (LLPanelPick*)mPicksTab->getCurrentPanel();
  1086. }
  1087. if (!panelp)
  1088. {
  1089. return false;
  1090. }
  1091. LLAvatarProperties::sendPickDelete(panelp->getPickCreatorID(),
  1092. panelp->getPickID());
  1093. if (mPicksTab)
  1094. {
  1095. mPicksTab->removeTabPanel(panelp);
  1096. }
  1097. delete panelp;
  1098. return false;
  1099. }
  1100. //-----------------------------------------------------------------------------
  1101. // LLPanelAvatar class
  1102. //-----------------------------------------------------------------------------
  1103. LLPanelAvatar::LLPanelAvatar(const std::string& name, const LLRect& rect,
  1104. bool allow_edit)
  1105. : LLPanel(name, rect, false),
  1106. LLAvatarPropertiesObserver(LLUUID::null, APT_NONE),
  1107. mDropTarget(NULL),
  1108. mHaveProperties(false),
  1109. mHaveInterests(false),
  1110. mHaveNotes(false),
  1111. mAllowEdit(allow_edit)
  1112. {
  1113. LLCallbackMap::map_t factory_map;
  1114. factory_map["2nd Life"] = LLCallbackMap(createPanelAvatarSecondLife, this);
  1115. factory_map["WebProfile"] = LLCallbackMap(createPanelAvatarWeb, this);
  1116. factory_map["Interests"] = LLCallbackMap(createPanelAvatarInterests, this);
  1117. factory_map["Picks"] = LLCallbackMap(createPanelAvatarPicks, this);
  1118. factory_map["Classified"] = LLCallbackMap(createPanelAvatarClassified, this);
  1119. factory_map["1st Life"] = LLCallbackMap(createPanelAvatarFirstLife, this);
  1120. factory_map["My Notes"] = LLCallbackMap(createPanelAvatarNotes, this);
  1121. LLUICtrlFactory::getInstance()->buildPanel(this, "panel_avatar.xml",
  1122. &factory_map);
  1123. selectTab(0);
  1124. }
  1125. bool LLPanelAvatar::postBuild()
  1126. {
  1127. if (sLoading.empty())
  1128. {
  1129. sLoading = getString("loading");
  1130. sClickToEnlarge = getString("click_to_enlarge");
  1131. sShowOnMapNonFriend = getString("ShowOnMapNonFriend");
  1132. sShowOnMapFriendOffline = getString("ShowOnMapFriendOffline");
  1133. sShowOnMapFriendOnline = getString("ShowOnMapFriendOnline");
  1134. sTeleportGod = getString("TeleportGod");
  1135. sTeleportPrelude = getString("TeleportPrelude");
  1136. sTeleportNormal = getString("TeleportNormal");
  1137. }
  1138. mTab = getChild<LLTabContainer>("tab");
  1139. mOKButton = getChild<LLButton>("OK");
  1140. mOKButton->setClickedCallback(onClickOK, this);
  1141. mCancelButton = getChild<LLButton>("Cancel");
  1142. mCancelButton->setClickedCallback(onClickCancel, this);
  1143. mKickButton = getChild<LLButton>("kick_btn");
  1144. mKickButton->setClickedCallback(onClickKick, this);
  1145. mKickButton->setVisible(false);
  1146. mKickButton->setEnabled(false);
  1147. mFreezeButton = getChild<LLButton>("freeze_btn");
  1148. mFreezeButton->setClickedCallback(onClickFreeze, this);
  1149. mFreezeButton->setVisible(false);
  1150. mFreezeButton->setEnabled(false);
  1151. mUnfreezeButton = getChild<LLButton>("unfreeze_btn");
  1152. mUnfreezeButton->setClickedCallback(onClickUnfreeze, this);
  1153. mUnfreezeButton->setVisible(false);
  1154. mUnfreezeButton->setEnabled(false);
  1155. mCSRButton = getChild<LLButton>("csr_btn");
  1156. mCSRButton->setClickedCallback(onClickCSR, this);
  1157. mCSRButton->setVisible(false);
  1158. mCSRButton->setEnabled(false);
  1159. if (!sAllowFirstLife)
  1160. {
  1161. mTab->removeTabPanel(mPanelFirstLife);
  1162. mTab->removeTabPanel(mPanelWeb);
  1163. }
  1164. return true;
  1165. }
  1166. LLPanelAvatar::~LLPanelAvatar()
  1167. {
  1168. LLAvatarProperties::removeObserver(this);
  1169. }
  1170. bool LLPanelAvatar::canClose()
  1171. {
  1172. return mPanelClassified->canClose();
  1173. }
  1174. void LLPanelAvatar::setOnlineStatus(EOnlineStatus online_status)
  1175. {
  1176. bool online = online_status == ONLINE_STATUS_YES;
  1177. // Online status NO could be because they are hidden. If they are a friend,
  1178. // we may know the truth !
  1179. if (!online && mIsFriend && gAvatarTracker.isBuddyOnline(mAvatarID))
  1180. {
  1181. online = true;
  1182. }
  1183. mPanelSecondLife->mOnlineText->setVisible(online);
  1184. // Since setOnlineStatus gets called after setAvatarID, we need to make
  1185. // sure that "Offer Teleport" does not get set to true again for yourself
  1186. if (mAvatarID != gAgentID)
  1187. {
  1188. mPanelSecondLife->mOfferTPButton->setVisible(true);
  1189. mPanelSecondLife->mRequestTPButton->setVisible(true);
  1190. }
  1191. if (gAgent.isGodlike())
  1192. {
  1193. mPanelSecondLife->mOfferTPButton->setEnabled(true);
  1194. mPanelSecondLife->mOfferTPButton->setToolTip(sTeleportGod);
  1195. }
  1196. else if (gAgent.inPrelude())
  1197. {
  1198. mPanelSecondLife->mOfferTPButton->setEnabled(false);
  1199. mPanelSecondLife->mOfferTPButton->setToolTip(sTeleportPrelude);
  1200. }
  1201. else
  1202. {
  1203. mPanelSecondLife->mOfferTPButton->setEnabled(true);
  1204. mPanelSecondLife->mOfferTPButton->setToolTip(sTeleportNormal);
  1205. }
  1206. if (!mIsFriend)
  1207. {
  1208. mPanelSecondLife->mFindOnMapButton->setToolTip(sShowOnMapNonFriend);
  1209. }
  1210. else if (!online)
  1211. {
  1212. mPanelSecondLife->mFindOnMapButton->setToolTip(sShowOnMapFriendOffline);
  1213. }
  1214. else
  1215. {
  1216. mPanelSecondLife->mFindOnMapButton->setToolTip(sShowOnMapFriendOnline);
  1217. }
  1218. }
  1219. void LLPanelAvatar::setAvatarID(const LLUUID& avatar_id,
  1220. const std::string& name,
  1221. EOnlineStatus online_status)
  1222. {
  1223. if (avatar_id.isNull()) return;
  1224. mAvatarID = avatar_id;
  1225. // Add the observer for data coming from the server for this avatar
  1226. setObservedAvatarId(avatar_id);
  1227. setObservedUpdateType(APT_ALL);
  1228. LLAvatarProperties::addObserver(this);
  1229. // Determine if they are a friend
  1230. mIsFriend = LLAvatarTracker::isAgentFriend(mAvatarID);
  1231. // setOnlineStatus() uses mIsFriend
  1232. setOnlineStatus(online_status);
  1233. bool own_avatar = mAvatarID == gAgentID;
  1234. mPanelSecondLife->enableControls(own_avatar && mAllowEdit);
  1235. mPanelAdvanced->enableControls(own_avatar && mAllowEdit);
  1236. // Teens do not have this.
  1237. if (sAllowFirstLife)
  1238. {
  1239. mPanelFirstLife->enableControls(own_avatar && mAllowEdit);
  1240. mPanelWeb->enableControls(own_avatar && mAllowEdit);
  1241. }
  1242. LLView* target_view = getChild<LLView>("drop_target_rect");
  1243. if (target_view)
  1244. {
  1245. if (mDropTarget)
  1246. {
  1247. delete mDropTarget;
  1248. }
  1249. mDropTarget = new LLDropTarget("drop target", target_view->getRect(),
  1250. mAvatarID);
  1251. addChild(mDropTarget);
  1252. mDropTarget->setAgentID(mAvatarID);
  1253. }
  1254. std::string avname = name;
  1255. if (name.empty())
  1256. {
  1257. mPanelSecondLife->mLegacyName->setNameID(avatar_id, false);
  1258. }
  1259. else
  1260. {
  1261. mPanelSecondLife->mLegacyName->setText(avname);
  1262. }
  1263. mPanelSecondLife->mLegacyName->setVisible(true);
  1264. if (LLAvatarNameCache::useDisplayNames())
  1265. {
  1266. LLAvatarName avatar_name;
  1267. if (LLAvatarNameCache::get(avatar_id, &avatar_name))
  1268. {
  1269. // Always show "Display Name [Legacy Name]" for security reasons
  1270. avname = avatar_name.getNames();
  1271. mAvatarUserName = avatar_name.mUsername;
  1272. }
  1273. else
  1274. {
  1275. avname = mPanelSecondLife->mLegacyName->getText();
  1276. LLAvatarNameCache::get(avatar_id,
  1277. boost::bind(&LLPanelAvatar::completeNameCallback,
  1278. _1, _2, getHandle()));
  1279. }
  1280. mPanelSecondLife->mCompleteName->setText(avname);
  1281. mPanelSecondLife->mCompleteName->setVisible(true);
  1282. mPanelSecondLife->mLegacyName->setVisible(false);
  1283. }
  1284. else
  1285. {
  1286. mPanelSecondLife->mCompleteName->setVisible(false);
  1287. }
  1288. // We cannot set a tooltip on a text input box ("name" or "complete_name"),
  1289. // so we set it on the profile picture... This can be helpful with very
  1290. // long names (which would *appear* truncated in the textbox; even if it's
  1291. // still possible to pan through the name with the mouse).
  1292. std::string tooltip = avname;
  1293. if (!own_avatar)
  1294. {
  1295. tooltip += "\n" + sClickToEnlarge;
  1296. }
  1297. mPanelSecondLife->m2ndLifePicture->setToolTip(tooltip);
  1298. // Clear out the old data
  1299. mPanelSecondLife->clearControls();
  1300. mPanelPicks->deletePickPanels();
  1301. mPanelPicks->resetDataRequested();
  1302. mPanelClassified->deleteClassifiedPanels();
  1303. mPanelClassified->resetDataRequested();
  1304. mHaveNotes = false;
  1305. mLastNotes.clear();
  1306. mPanelNotes->clearControls();
  1307. mPanelNotes->resetDataRequested();
  1308. // Send a properties request for the new avatar
  1309. LLAvatarProperties::sendGenericRequest(mAvatarID, APT_AVATAR_INFO);
  1310. bool is_god = gAgent.isGodlike();
  1311. if (own_avatar)
  1312. {
  1313. if (mAllowEdit)
  1314. {
  1315. // OK button disabled until properties data arrives
  1316. mOKButton->setVisible(true);
  1317. mOKButton->setEnabled(false);
  1318. mCancelButton->setVisible(true);
  1319. mCancelButton->setEnabled(true);
  1320. }
  1321. else
  1322. {
  1323. mOKButton->setVisible(false);
  1324. mOKButton->setEnabled(false);
  1325. mCancelButton->setVisible(false);
  1326. mCancelButton->setEnabled(false);
  1327. }
  1328. mPanelSecondLife->mFindOnMapButton->setVisible(false);
  1329. mPanelSecondLife->mFindOnMapButton->setEnabled(false);
  1330. mPanelSecondLife->mOfferTPButton->setVisible(false);
  1331. mPanelSecondLife->mOfferTPButton->setEnabled(false);
  1332. mPanelSecondLife->mRequestTPButton->setVisible(false);
  1333. mPanelSecondLife->mRequestTPButton->setEnabled(false);
  1334. mPanelSecondLife->mAddFriendButton->setVisible(false);
  1335. mPanelSecondLife->mAddFriendButton->setEnabled(false);
  1336. mPanelSecondLife->mPayButton->setVisible(false);
  1337. mPanelSecondLife->mPayButton->setEnabled(false);
  1338. mPanelSecondLife->mIMButton->setVisible(false);
  1339. mPanelSecondLife->mIMButton->setEnabled(false);
  1340. mPanelSecondLife->mMuteButton->setVisible(false);
  1341. mPanelSecondLife->mMuteButton->setEnabled(false);
  1342. if (mDropTarget)
  1343. {
  1344. mDropTarget->setVisible(false);
  1345. mDropTarget->setEnabled(false);
  1346. }
  1347. }
  1348. else
  1349. {
  1350. mOKButton->setVisible(false);
  1351. mOKButton->setEnabled(false);
  1352. mCancelButton->setVisible(false);
  1353. mCancelButton->setEnabled(false);
  1354. mPanelSecondLife->mFindOnMapButton->setVisible(true);
  1355. // Note: we do not always know online status, so always allow gods to
  1356. // try to track
  1357. bool can_map = LLAvatarTracker::isAgentMappable(mAvatarID);
  1358. mPanelSecondLife->mFindOnMapButton->setEnabled(can_map || is_god);
  1359. if (!mIsFriend)
  1360. {
  1361. mPanelSecondLife->mFindOnMapButton->setToolTip(sShowOnMapNonFriend);
  1362. }
  1363. else if (ONLINE_STATUS_YES != online_status)
  1364. {
  1365. mPanelSecondLife->mFindOnMapButton->setToolTip(sShowOnMapFriendOffline);
  1366. }
  1367. else
  1368. {
  1369. mPanelSecondLife->mFindOnMapButton->setToolTip(sShowOnMapFriendOnline);
  1370. }
  1371. mPanelSecondLife->mAddFriendButton->setVisible(true);
  1372. mPanelSecondLife->mAddFriendButton->setEnabled(!mIsFriend);
  1373. mPanelSecondLife->mPayButton->setVisible(true);
  1374. mPanelSecondLife->mPayButton->setEnabled(false);
  1375. mPanelSecondLife->mIMButton->setVisible(true);
  1376. mPanelSecondLife->mIMButton->setEnabled(false);
  1377. mPanelSecondLife->mMuteButton->setVisible(true);
  1378. mPanelSecondLife->mMuteButton->setEnabled(false);
  1379. if (mDropTarget)
  1380. {
  1381. mDropTarget->setVisible(true);
  1382. mDropTarget->setEnabled(false);
  1383. }
  1384. }
  1385. childSetText("avatar_key", mAvatarID.asString());
  1386. mKickButton->setVisible(is_god);
  1387. mKickButton->setEnabled(is_god);
  1388. mFreezeButton->setVisible(is_god);
  1389. mFreezeButton->setEnabled(is_god);
  1390. mUnfreezeButton->setVisible(is_god);
  1391. mUnfreezeButton->setEnabled(is_god);
  1392. mCSRButton->setVisible(is_god);
  1393. mCSRButton->setEnabled(is_god && gIsInSecondLife);
  1394. }
  1395. //static
  1396. void LLPanelAvatar::completeNameCallback(const LLUUID& agent_id,
  1397. const LLAvatarName& avatar_name,
  1398. LLHandle<LLPanel> handle)
  1399. {
  1400. // Check that the panel was not closed and we are still using display names
  1401. if (handle.isDead() || !LLAvatarNameCache::useDisplayNames())
  1402. {
  1403. return;
  1404. }
  1405. LLPanelAvatar* self = (LLPanelAvatar*)handle.get();
  1406. // Check that the profile still refers to the same avatar...
  1407. if (self->mAvatarID != agent_id)
  1408. {
  1409. return;
  1410. }
  1411. self->mAvatarUserName = avatar_name.mUsername;
  1412. // Always show "Display Name [Legacy Name]" for security reasons
  1413. std::string avname = avatar_name.getNames();
  1414. self->mPanelSecondLife->mCompleteName->setText(avname);
  1415. std::string tooltip = avname;
  1416. if (agent_id != gAgentID)
  1417. {
  1418. tooltip += "\n" + sClickToEnlarge;
  1419. }
  1420. self->mPanelSecondLife->m2ndLifePicture->setToolTip(tooltip);
  1421. }
  1422. void LLPanelAvatar::listAgentGroups()
  1423. {
  1424. // Only get these updates asynchronously via the group floater, which works
  1425. // on the agent only
  1426. if (mAvatarID != gAgentID)
  1427. {
  1428. return;
  1429. }
  1430. LLScrollListCtrl* group_list = mPanelSecondLife->mGroupsListCtrl;
  1431. group_list->deleteAllItems();
  1432. std::string hidden_group = getString("hidden_group");
  1433. for (S32 i = 0, count = gAgent.mGroups.size(); i < count; ++i)
  1434. {
  1435. const LLGroupData& group_data = gAgent.mGroups[i];
  1436. LLSD row;
  1437. row["id"] = group_data.mID;
  1438. LLSD& col = row["columns"][0];
  1439. col["value"] = group_data.mName;
  1440. col["font"] = "SANSSERIF_SMALL";
  1441. bool hidden = !group_data.mListInProfile;
  1442. if (hidden)
  1443. {
  1444. col["font-style"] = "ITALIC";
  1445. }
  1446. LLScrollListItem* itemp = group_list->addElement(row);
  1447. if (hidden && itemp)
  1448. {
  1449. itemp->setToolTip(hidden_group);
  1450. }
  1451. }
  1452. group_list->sortByColumnIndex(0, true);
  1453. }
  1454. //virtual
  1455. void LLPanelAvatar::processProperties(S32 type, void* userdata)
  1456. {
  1457. if (type == APT_AVATAR_INFO)
  1458. {
  1459. LLAvatarInfo* data = (LLAvatarInfo*)userdata;
  1460. if (data->mAvatarId != mAvatarID) // This should not happen...
  1461. {
  1462. return;
  1463. }
  1464. mPanelSecondLife->mIMButton->setEnabled(true);
  1465. mPanelSecondLife->mPayButton->setEnabled(true);
  1466. mPanelSecondLife->mMuteButton->setEnabled(true);
  1467. if (mDropTarget)
  1468. {
  1469. mDropTarget->setEnabled(true);
  1470. }
  1471. std::string& caption_text = data->mCaptionText;
  1472. if (caption_text.empty())
  1473. {
  1474. LLStringUtil::format_map_t args;
  1475. caption_text = mPanelSecondLife->getString("CaptionTextAcctInfo");
  1476. static const char* ACCT_TYPE[] =
  1477. {
  1478. "AcctTypeResident",
  1479. "AcctTypeTrial",
  1480. "AcctTypeCharterMember",
  1481. "AcctTypeEmployee"
  1482. };
  1483. constexpr S32 ACCT_TYPE_SIZE = LL_ARRAY_SIZE(ACCT_TYPE);
  1484. U8 caption_index = llmin(data->mCaptionIndex,
  1485. (U8)(ACCT_TYPE_SIZE - 1));
  1486. args["[ACCTTYPE]"] =
  1487. mPanelSecondLife->getString(ACCT_TYPE[caption_index]);
  1488. std::string payment_text = " ";
  1489. constexpr S32 DEFAULT_CAPTION_LINDEN_INDEX = 3;
  1490. if (caption_index != DEFAULT_CAPTION_LINDEN_INDEX)
  1491. {
  1492. if (data->mFlags & AVATAR_TRANSACTED)
  1493. {
  1494. payment_text = "PaymentInfoUsed";
  1495. }
  1496. else if (data->mFlags & AVATAR_IDENTIFIED)
  1497. {
  1498. payment_text = "PaymentInfoOnFile";
  1499. }
  1500. else
  1501. {
  1502. payment_text = "NoPaymentInfoOnFile";
  1503. }
  1504. args["[PAYMENTINFO]"] =
  1505. mPanelSecondLife->getString(payment_text);
  1506. }
  1507. else
  1508. {
  1509. args["[PAYMENTINFO]"] = " ";
  1510. }
  1511. LLStringUtil::format(caption_text, args);
  1512. }
  1513. mPanelSecondLife->mAccountInfoText->setValue(caption_text);
  1514. mPanelSecondLife->mBornText->setValue(data->mBirthDate);
  1515. setOnlineStatus(data->mFlags & AVATAR_ONLINE ? ONLINE_STATUS_YES
  1516. : ONLINE_STATUS_NO);
  1517. mPanelSecondLife->m2ndLifePicture->setImageAssetID(data->mImageId);
  1518. mPanelSecondLife->setPartnerID(data->mPartnerId);
  1519. mPanelSecondLife->updatePartnerName();
  1520. // Do not overwrite the About texts when we received them already via
  1521. // the capability, since the capability transmits way longer texts...
  1522. if (data->mReceivedViaCap || !mHaveProperties)
  1523. {
  1524. LLTextEditor* editp = mPanelSecondLife->mAbout2ndLifeText;
  1525. editp->clear();
  1526. editp->setParseHTML(true);
  1527. if (mAvatarID == gAgentID)
  1528. {
  1529. editp->setText(data->mAbout);
  1530. }
  1531. else
  1532. {
  1533. editp->appendColoredText(data->mAbout, false, false,
  1534. editp->getReadOnlyFgColor());
  1535. }
  1536. if (sAllowFirstLife) // Teens do not get this
  1537. {
  1538. editp = mPanelFirstLife->mAbout1stLifeText;
  1539. editp->clear();
  1540. editp->setParseHTML(true);
  1541. if (mAvatarID == gAgentID)
  1542. {
  1543. editp->setText(data->mFLAbout);
  1544. }
  1545. else
  1546. {
  1547. editp->appendColoredText(data->mFLAbout, false, false,
  1548. editp->getReadOnlyFgColor());
  1549. }
  1550. }
  1551. }
  1552. if (sAllowFirstLife) // Teens do not get this
  1553. {
  1554. // The capability does not provide the Web URL... HB
  1555. if (!data->mReceivedViaCap)
  1556. {
  1557. mPanelWeb->setWebURL(data->mProfileUrl);
  1558. }
  1559. LLTextureCtrl* image_ctrl = mPanelFirstLife->m1stLifePicture;
  1560. image_ctrl->setImageAssetID(data->mFLImageId);
  1561. if (mAvatarID == gAgentID || data->mFLImageId.isNull())
  1562. {
  1563. image_ctrl->setToolTip("");
  1564. }
  1565. else
  1566. {
  1567. image_ctrl->setToolTip(sClickToEnlarge);
  1568. }
  1569. }
  1570. bool allow_publish = (data->mFlags & AVATAR_ALLOW_PUBLISH) != 0;
  1571. mPanelSecondLife->mShowInSearchCheck->setValue(allow_publish);
  1572. mHaveProperties = true;
  1573. enableOKIfReady();
  1574. // If we do not have the interests, we need to do an UDP request...
  1575. // Sadly, it is not possible to ask only for interests data via an UDP
  1576. // message, so we must re-request the whole shebang (main properties)
  1577. // to get them (as a different UDP reply message). You could ask: "but
  1578. // why bothering at all with the capability, then ?", and the answer is
  1579. // that the latter is able to cope with About texts of more than 500
  1580. // characters, which the UDP messages cannot cope with... HB
  1581. if (data->mReceivedViaCap && !mHaveInterests)
  1582. {
  1583. LLAvatarProperties::sendAvatarPropertiesRequest(mAvatarID);
  1584. }
  1585. }
  1586. else if (type == APT_GROUPS)
  1587. {
  1588. LLAvatarGroups* groups = (LLAvatarGroups*)userdata;
  1589. if (groups->mAvatarId != mAvatarID) // This should always be true
  1590. {
  1591. return;
  1592. }
  1593. if (mAvatarID == gAgentID && !gAgent.mGroups.empty())
  1594. {
  1595. // Use our agent's group list info instead; this also takes care of
  1596. // displaying hidden groups in italics and with an explanatory tool
  1597. // tip... HB
  1598. listAgentGroups();
  1599. return;
  1600. }
  1601. LLScrollListCtrl* group_list = mPanelSecondLife->mGroupsListCtrl;
  1602. if (groups->mGroups.empty())
  1603. {
  1604. group_list->deleteAllItems();
  1605. // *TODO: Translate
  1606. group_list->addCommentText("None");
  1607. return;
  1608. }
  1609. #if 0 // Could cause missing groups in the list (see below), especially with
  1610. // the new, larger groups number limits. HB
  1611. group_list->deleteAllItems();
  1612. #endif
  1613. for (LLAvatarGroups::list_t::iterator it = groups->mGroups.begin(),
  1614. end = groups->mGroups.end();
  1615. it != end; ++it)
  1616. {
  1617. const LLGroupData& data = *it;
  1618. const LLUUID& group_id = data.mID;
  1619. #if 1 // An alternative to deleteAllItems() above, in case we would get
  1620. // several processAvatarGroupsReply() for the same avatar (i.e. if
  1621. // the groups list cannot be transmitted as a single message for
  1622. // being too big)...
  1623. // Remove any existing entry.
  1624. S32 index = group_list->getItemIndex(group_id);
  1625. if (index >= 0)
  1626. {
  1627. group_list->deleteSingleItem(index);
  1628. }
  1629. #endif
  1630. LLSD row;
  1631. row["id"] = group_id;
  1632. LLSD& col = row["columns"][0];
  1633. col["value"] = data.mName;
  1634. col["font"] = "SANSSERIF_SMALL";
  1635. group_list->addElement(row);
  1636. }
  1637. group_list->sortByColumnIndex(0, true);
  1638. }
  1639. else if (type == APT_INTERESTS)
  1640. {
  1641. LLAvatarInterests* data = (LLAvatarInterests*)userdata;
  1642. if (data->mAvatarId != mAvatarID) // This should always be true
  1643. {
  1644. return;
  1645. }
  1646. mHaveInterests = true;
  1647. mPanelAdvanced->setWantSkills(data->mWantsMask, data->mWantsText,
  1648. data->mSkillsMask, data->mSkillsText,
  1649. data->mLanguages);
  1650. }
  1651. else if (type == APT_PICKS)
  1652. {
  1653. LLAvatarPicks* data = (LLAvatarPicks*)userdata;
  1654. if (data->mAvatarId == mAvatarID) // This should always be true
  1655. {
  1656. mPanelPicks->processAvatarPicksReply(data);
  1657. }
  1658. }
  1659. else if (type == APT_CLASSIFIEDS)
  1660. {
  1661. LLAvatarClassifieds* data = (LLAvatarClassifieds*)userdata;
  1662. if (data->mAvatarId == mAvatarID) // This should always be true
  1663. {
  1664. mPanelClassified->processAvatarClassifiedReply(data);
  1665. }
  1666. }
  1667. else if (type == APT_NOTES)
  1668. {
  1669. LLAvatarNotes* data = (LLAvatarNotes*)userdata;
  1670. if (data->mAvatarId == mAvatarID) // This should always be true
  1671. {
  1672. mHaveNotes = true;
  1673. mLastNotes = data->mNotes;
  1674. mPanelNotes->mNotesText->setText(mLastNotes);
  1675. mPanelNotes->mNotesText->setEnabled(true);
  1676. }
  1677. }
  1678. }
  1679. //static
  1680. void LLPanelAvatar::onClickIM(void* userdata)
  1681. {
  1682. LLPanelAvatar* self = (LLPanelAvatar*)userdata;
  1683. if (self)
  1684. {
  1685. LLAvatarActions::startIM(self->mAvatarID);
  1686. }
  1687. }
  1688. //static
  1689. void LLPanelAvatar::onClickTrack(void* userdata)
  1690. {
  1691. LLPanelAvatar* self = (LLPanelAvatar*)userdata;
  1692. if (gFloaterWorldMapp && self)
  1693. {
  1694. std::string name = self->mPanelSecondLife->mLegacyName->getText();
  1695. gFloaterWorldMapp->trackAvatar(self->mAvatarID, name);
  1696. LLFloaterWorldMap::show(NULL, true);
  1697. }
  1698. }
  1699. //static
  1700. void LLPanelAvatar::onClickAddFriend(void* userdata)
  1701. {
  1702. LLPanelAvatar* self = (LLPanelAvatar*) userdata;
  1703. if (self)
  1704. {
  1705. std::string name = self->mPanelSecondLife->mLegacyName->getText();
  1706. LLAvatarActions::requestFriendshipDialog(self->getAvatarID(), name);
  1707. }
  1708. }
  1709. void LLPanelAvatar::onClickMute(void* userdata)
  1710. {
  1711. LLPanelAvatar* self = (LLPanelAvatar*) userdata;
  1712. if (!self) return;
  1713. LLUUID avatar_id = self->getAvatarID();
  1714. std::string avatar_name = self->mPanelSecondLife->mLegacyName->getText();
  1715. if (LLMuteList::isMuted(avatar_id))
  1716. {
  1717. LLFloaterMute::selectMute(avatar_id);
  1718. }
  1719. else
  1720. {
  1721. LLMute mute(avatar_id, avatar_name, LLMute::AGENT);
  1722. if (LLMuteList::add(mute))
  1723. {
  1724. LLFloaterMute::selectMute(mute.mID);
  1725. }
  1726. }
  1727. }
  1728. //static
  1729. void LLPanelAvatar::onClickOfferTeleport(void* userdata)
  1730. {
  1731. LLPanelAvatar* self = (LLPanelAvatar*)userdata;
  1732. if (self)
  1733. {
  1734. LLAvatarActions::offerTeleport(self->mAvatarID);
  1735. }
  1736. }
  1737. //static
  1738. void LLPanelAvatar::onClickRequestTeleport(void* userdata)
  1739. {
  1740. LLPanelAvatar* self = (LLPanelAvatar*)userdata;
  1741. if (self)
  1742. {
  1743. LLAvatarActions::teleportRequest(self->mAvatarID);
  1744. }
  1745. }
  1746. //static
  1747. void LLPanelAvatar::onClickPay(void* userdata)
  1748. {
  1749. LLPanelAvatar* self = (LLPanelAvatar*) userdata;
  1750. if (self)
  1751. {
  1752. LLAvatarActions::pay(self->mAvatarID);
  1753. }
  1754. }
  1755. //static
  1756. void LLPanelAvatar::onClickOK(void* userdata)
  1757. {
  1758. LLPanelAvatar* self = (LLPanelAvatar*)userdata;
  1759. // JC: Only save the data if we actually got the original properties.
  1760. // Otherwise we might save blanks into the database.
  1761. if (self && self->mHaveProperties)
  1762. {
  1763. self->sendAvatarPropertiesUpdate();
  1764. LLTabContainer* tabs = self->getChild<LLTabContainer>("tab");
  1765. if (tabs->getCurrentPanel() != self->mPanelClassified)
  1766. {
  1767. self->mPanelClassified->apply();
  1768. LLFloaterAvatarInfo* infop =
  1769. LLFloaterAvatarInfo::getInstance(self->mAvatarID);
  1770. if (infop)
  1771. {
  1772. infop->close();
  1773. }
  1774. }
  1775. else if (self->mPanelClassified->titleIsValid())
  1776. {
  1777. self->mPanelClassified->apply();
  1778. LLFloaterAvatarInfo* infop =
  1779. LLFloaterAvatarInfo::getInstance(self->mAvatarID);
  1780. if (infop)
  1781. {
  1782. infop->close();
  1783. }
  1784. }
  1785. }
  1786. }
  1787. //static
  1788. void LLPanelAvatar::onClickCancel(void* userdata)
  1789. {
  1790. LLPanelAvatar* self = (LLPanelAvatar*)userdata;
  1791. if (!self)
  1792. {
  1793. return;
  1794. }
  1795. LLFloaterAvatarInfo* infop;
  1796. if ((infop = LLFloaterAvatarInfo::getInstance(self->mAvatarID)))
  1797. {
  1798. infop->close();
  1799. return;
  1800. }
  1801. // We are in the Search directory and are cancelling an edit to our own
  1802. // profile, so reset.
  1803. LLAvatarProperties::sendGenericRequest(self->mAvatarID, APT_AVATAR_INFO);
  1804. }
  1805. void LLPanelAvatar::sendAvatarNotesUpdate()
  1806. {
  1807. const std::string& notes = mPanelNotes->mNotesText->getText();
  1808. if (!mHaveNotes || notes == mLastNotes || notes == sLoading)
  1809. {
  1810. // No note from server and no user updates
  1811. return;
  1812. }
  1813. LLAvatarProperties::sendAvatarNotesUpdate(mAvatarID, notes);
  1814. }
  1815. // Do not enable the OK button until you actually have the data. Otherwise you
  1816. // will write blanks back into the database.
  1817. void LLPanelAvatar::enableOKIfReady()
  1818. {
  1819. mOKButton->setEnabled(mHaveProperties && mOKButton->getVisible());
  1820. }
  1821. void LLPanelAvatar::sendAvatarPropertiesUpdate()
  1822. {
  1823. LLAvatarInfo avdata;
  1824. avdata.mAbout =
  1825. mPanelSecondLife->mAbout2ndLifeText->getValue().asString();
  1826. avdata.mImageId = mPanelSecondLife->m2ndLifePicture->getImageAssetID();
  1827. if (sAllowFirstLife)
  1828. {
  1829. avdata.mAllowPublish =
  1830. mPanelSecondLife->mShowInSearchCheck->getValue();
  1831. avdata.mProfileUrl = mPanelWeb->getWebURL();
  1832. avdata.mFLAbout =
  1833. mPanelFirstLife->mAbout1stLifeText->getValue().asString();
  1834. avdata.mFLImageId =
  1835. mPanelFirstLife->m1stLifePicture->getImageAssetID();
  1836. }
  1837. else
  1838. {
  1839. avdata.mAllowPublish = false;
  1840. }
  1841. LLAvatarProperties::sendAvatarPropertiesUpdate(avdata);
  1842. LLAvatarInterests interests;
  1843. mPanelAdvanced->getWantSkills(interests.mWantsMask, interests.mWantsText,
  1844. interests.mSkillsMask,
  1845. interests.mSkillsText, interests.mLanguages);
  1846. LLAvatarProperties::sendInterestsInfoUpdate(interests);
  1847. }
  1848. void LLPanelAvatar::selectTab(S32 tabnum)
  1849. {
  1850. mTab->selectTab(tabnum);
  1851. }
  1852. void LLPanelAvatar::selectTabByName(std::string tab_name)
  1853. {
  1854. if (tab_name.empty())
  1855. {
  1856. mTab->selectFirstTab();
  1857. }
  1858. else
  1859. {
  1860. mTab->selectTabByName(tab_name);
  1861. }
  1862. }
  1863. //static
  1864. void LLPanelAvatar::onClickKick(void* userdata)
  1865. {
  1866. LLPanelAvatar* self = (LLPanelAvatar*)userdata;
  1867. if (self)
  1868. {
  1869. LLAvatarActions::kick(self->mAvatarID);
  1870. }
  1871. }
  1872. //static
  1873. void LLPanelAvatar::onClickFreeze(void* userdata)
  1874. {
  1875. LLPanelAvatar* self = (LLPanelAvatar*)userdata;
  1876. if (self)
  1877. {
  1878. LLAvatarActions::freeze(self->mAvatarID, true);
  1879. }
  1880. }
  1881. //static
  1882. void LLPanelAvatar::onClickUnfreeze(void* userdata)
  1883. {
  1884. LLPanelAvatar* self = (LLPanelAvatar*)userdata;
  1885. if (self)
  1886. {
  1887. LLAvatarActions::freeze(self->mAvatarID, false);
  1888. }
  1889. }
  1890. //static
  1891. void LLPanelAvatar::onClickCSR(void* userdata)
  1892. {
  1893. LLPanelAvatar* self = (LLPanelAvatar*)userdata;
  1894. if (!self || !self->mPanelSecondLife) return;
  1895. std::string name = self->mPanelSecondLife->mLegacyName->getText();
  1896. if (name.empty()) return;
  1897. std::string url = "http://csr.lindenlab.com/agent/";
  1898. // Slow and stupid, but it is late
  1899. S32 len = name.length();
  1900. for (S32 i = 0; i < len; ++i)
  1901. {
  1902. if (name[i] == ' ')
  1903. {
  1904. url += "%20";
  1905. }
  1906. else
  1907. {
  1908. url += name[i];
  1909. }
  1910. }
  1911. LLWeb::loadURL(url);
  1912. }
  1913. void* LLPanelAvatar::createPanelAvatarSecondLife(void* data)
  1914. {
  1915. LLPanelAvatar* self = (LLPanelAvatar*)data;
  1916. self->mPanelSecondLife = new LLPanelAvatarSecondLife("2nd Life", LLRect(),
  1917. self);
  1918. return self->mPanelSecondLife;
  1919. }
  1920. void* LLPanelAvatar::createPanelAvatarWeb(void* data)
  1921. {
  1922. LLPanelAvatar* self = (LLPanelAvatar*)data;
  1923. self->mPanelWeb = new LLPanelAvatarWeb("Web", LLRect(), self);
  1924. return self->mPanelWeb;
  1925. }
  1926. void* LLPanelAvatar::createPanelAvatarInterests(void* data)
  1927. {
  1928. LLPanelAvatar* self = (LLPanelAvatar*)data;
  1929. self->mPanelAdvanced = new LLPanelAvatarAdvanced("Interests", LLRect(),
  1930. self);
  1931. return self->mPanelAdvanced;
  1932. }
  1933. void* LLPanelAvatar::createPanelAvatarPicks(void* data)
  1934. {
  1935. LLPanelAvatar* self = (LLPanelAvatar*)data;
  1936. self->mPanelPicks = new LLPanelAvatarPicks("Picks", LLRect(), self);
  1937. return self->mPanelPicks;
  1938. }
  1939. void* LLPanelAvatar::createPanelAvatarClassified(void* data)
  1940. {
  1941. LLPanelAvatar* self = (LLPanelAvatar*)data;
  1942. self->mPanelClassified = new LLPanelAvatarClassified("Classified",
  1943. LLRect(), self);
  1944. return self->mPanelClassified;
  1945. }
  1946. void* LLPanelAvatar::createPanelAvatarFirstLife(void* data)
  1947. {
  1948. LLPanelAvatar* self = (LLPanelAvatar*)data;
  1949. self->mPanelFirstLife = new LLPanelAvatarFirstLife("1st Life", LLRect(),
  1950. self);
  1951. return self->mPanelFirstLife;
  1952. }
  1953. void* LLPanelAvatar::createPanelAvatarNotes(void* data)
  1954. {
  1955. LLPanelAvatar* self = (LLPanelAvatar*)data;
  1956. self->mPanelNotes = new LLPanelAvatarNotes("My Notes", LLRect(), self);
  1957. return self->mPanelNotes;
  1958. }