PageRenderTime 44ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/newview/llavatariconctrl.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 310 lines | 214 code | 50 blank | 46 comment | 37 complexity | 2092eb35d110bc4875c5c350c4f1f8b0 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llavatariconctrl.cpp
  3. * @brief LLAvatarIconCtrl class implementation
  4. *
  5. * $LicenseInfo:firstyear=2009&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #include "llviewerprecompiledheaders.h"
  27. #include "llavatariconctrl.h"
  28. // viewer includes
  29. #include "llagent.h"
  30. #include "llavatarconstants.h"
  31. #include "llcallingcard.h" // for LLAvatarTracker
  32. #include "llavataractions.h"
  33. #include "llmenugl.h"
  34. #include "lluictrlfactory.h"
  35. #include "llagentdata.h"
  36. #include "llimfloater.h"
  37. // library includes
  38. #include "llavatarnamecache.h"
  39. #define MENU_ITEM_VIEW_PROFILE 0
  40. #define MENU_ITEM_SEND_IM 1
  41. static LLDefaultChildRegistry::Register<LLAvatarIconCtrl> r("avatar_icon");
  42. bool LLAvatarIconIDCache::LLAvatarIconIDCacheItem::expired()
  43. {
  44. const F64 SEC_PER_DAY_PLUS_HOUR = (24.0 + 1.0) * 60.0 * 60.0;
  45. F64 delta = LLDate::now().secondsSinceEpoch() - cached_time.secondsSinceEpoch();
  46. if (delta > SEC_PER_DAY_PLUS_HOUR)
  47. return true;
  48. return false;
  49. }
  50. void LLAvatarIconIDCache::load ()
  51. {
  52. llinfos << "Loading avatar icon id cache." << llendl;
  53. // build filename for each user
  54. std::string resolved_filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, mFilename);
  55. llifstream file(resolved_filename);
  56. if (!file.is_open())
  57. return;
  58. // add each line in the file to the list
  59. int uuid_len = UUID_STR_LENGTH-1;
  60. std::string line;
  61. while (std::getline(file, line))
  62. {
  63. LLUUID avatar_id;
  64. LLUUID icon_id;
  65. LLDate date;
  66. if (line.length()<=uuid_len*2)
  67. continue; // short line, bail out to prevent substr calls throwing exception.
  68. std::string avatar_id_str = line.substr(0,uuid_len);
  69. std::string icon_id_str = line.substr(uuid_len,uuid_len);
  70. std::string date_str = line.substr(uuid_len*2, line.length()-uuid_len*2);
  71. if(!avatar_id.set(avatar_id_str) || !icon_id.set(icon_id_str) || !date.fromString(date_str))
  72. continue;
  73. LLAvatarIconIDCacheItem item = {icon_id,date};
  74. mCache[avatar_id] = item;
  75. }
  76. file.close();
  77. }
  78. void LLAvatarIconIDCache::save ()
  79. {
  80. std::string resolved_filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, mFilename);
  81. // open a file for writing
  82. llofstream file (resolved_filename);
  83. if (!file.is_open())
  84. {
  85. llwarns << "can't open avatar icons cache file\"" << mFilename << "\" for writing" << llendl;
  86. return;
  87. }
  88. for(std::map<LLUUID,LLAvatarIconIDCacheItem>::iterator it = mCache.begin();it!=mCache.end();++it)
  89. {
  90. if(!it->second.expired())
  91. {
  92. file << it->first << it->second.icon_id << it->second.cached_time << std::endl;
  93. }
  94. }
  95. file.close();
  96. }
  97. LLUUID* LLAvatarIconIDCache::get (const LLUUID& avatar_id)
  98. {
  99. std::map<LLUUID,LLAvatarIconIDCacheItem>::iterator it = mCache.find(avatar_id);
  100. if(it==mCache.end())
  101. return 0;
  102. if(it->second.expired())
  103. return 0;
  104. return &it->second.icon_id;
  105. }
  106. void LLAvatarIconIDCache::add (const LLUUID& avatar_id,const LLUUID& icon_id)
  107. {
  108. LLAvatarIconIDCacheItem item = {icon_id,LLDate::now()};
  109. mCache[avatar_id] = item;
  110. }
  111. void LLAvatarIconIDCache::remove (const LLUUID& avatar_id)
  112. {
  113. mCache.erase(avatar_id);
  114. }
  115. LLAvatarIconCtrl::Params::Params()
  116. : avatar_id("avatar_id"),
  117. draw_tooltip("draw_tooltip", true),
  118. default_icon_name("default_icon_name")
  119. {
  120. }
  121. LLAvatarIconCtrl::LLAvatarIconCtrl(const LLAvatarIconCtrl::Params& p)
  122. : LLIconCtrl(p),
  123. mDrawTooltip(p.draw_tooltip),
  124. mDefaultIconName(p.default_icon_name)
  125. {
  126. mPriority = LLViewerFetchedTexture::BOOST_ICON;
  127. LLRect rect = p.rect;
  128. mDrawWidth = llmax(32, rect.getWidth()) ;
  129. mDrawHeight = llmax(32, rect.getHeight()) ;
  130. static LLUICachedControl<S32> llavatariconctrl_symbol_hpad("UIAvatariconctrlSymbolHPad", 2);
  131. static LLUICachedControl<S32> llavatariconctrl_symbol_vpad("UIAvatariconctrlSymbolVPad", 2);
  132. static LLUICachedControl<S32> llavatariconctrl_symbol_size("UIAvatariconctrlSymbolSize", 5);
  133. static LLUICachedControl<std::string> llavatariconctrl_symbol_pos("UIAvatariconctrlSymbolPosition", "BottomRight");
  134. // BottomRight is the default position
  135. S32 left = rect.getWidth() - llavatariconctrl_symbol_size - llavatariconctrl_symbol_hpad;
  136. S32 bottom = llavatariconctrl_symbol_vpad;
  137. if ("BottomLeft" == (std::string)llavatariconctrl_symbol_pos)
  138. {
  139. left = llavatariconctrl_symbol_hpad;
  140. bottom = llavatariconctrl_symbol_vpad;
  141. }
  142. else if ("TopLeft" == (std::string)llavatariconctrl_symbol_pos)
  143. {
  144. left = llavatariconctrl_symbol_hpad;
  145. bottom = rect.getHeight() - llavatariconctrl_symbol_size - llavatariconctrl_symbol_vpad;
  146. }
  147. else if ("TopRight" == (std::string)llavatariconctrl_symbol_pos)
  148. {
  149. left = rect.getWidth() - llavatariconctrl_symbol_size - llavatariconctrl_symbol_hpad;
  150. bottom = rect.getHeight() - llavatariconctrl_symbol_size - llavatariconctrl_symbol_vpad;
  151. }
  152. rect.setOriginAndSize(left, bottom, llavatariconctrl_symbol_size, llavatariconctrl_symbol_size);
  153. if (p.avatar_id.isProvided())
  154. {
  155. LLSD value(p.avatar_id);
  156. setValue(value);
  157. }
  158. else
  159. {
  160. LLIconCtrl::setValue(mDefaultIconName);
  161. }
  162. }
  163. LLAvatarIconCtrl::~LLAvatarIconCtrl()
  164. {
  165. if (mAvatarId.notNull())
  166. {
  167. LLAvatarPropertiesProcessor::getInstance()->removeObserver(mAvatarId, this);
  168. // Name callbacks will be automatically disconnected since LLUICtrl is trackable
  169. }
  170. }
  171. //virtual
  172. void LLAvatarIconCtrl::setValue(const LLSD& value)
  173. {
  174. if (value.isUUID())
  175. {
  176. LLAvatarPropertiesProcessor* app =
  177. LLAvatarPropertiesProcessor::getInstance();
  178. if (mAvatarId.notNull())
  179. {
  180. app->removeObserver(mAvatarId, this);
  181. }
  182. if (mAvatarId != value.asUUID())
  183. {
  184. mAvatarId = value.asUUID();
  185. // *BUG: This will return stale icons if a user changes their
  186. // profile picture. However, otherwise we send too many upstream
  187. // AvatarPropertiesRequest messages.
  188. // to get fresh avatar icon use
  189. // LLAvatarIconIDCache::getInstance()->remove(avatar_id);
  190. // Check if cache already contains image_id for that avatar
  191. if (!updateFromCache())
  192. {
  193. // *TODO: Consider getting avatar icon/badge directly from
  194. // People API, rather than sending AvatarPropertyRequest
  195. // messages. People API already hits the user table.
  196. LLIconCtrl::setValue(mDefaultIconName);
  197. app->addObserver(mAvatarId, this);
  198. app->sendAvatarPropertiesRequest(mAvatarId);
  199. }
  200. }
  201. }
  202. else
  203. {
  204. LLIconCtrl::setValue(value);
  205. }
  206. LLAvatarNameCache::get(mAvatarId,
  207. boost::bind(&LLAvatarIconCtrl::onAvatarNameCache,
  208. this, _1, _2));
  209. }
  210. bool LLAvatarIconCtrl::updateFromCache()
  211. {
  212. LLUUID* icon_id_ptr = LLAvatarIconIDCache::getInstance()->get(mAvatarId);
  213. if(!icon_id_ptr)
  214. return false;
  215. const LLUUID& icon_id = *icon_id_ptr;
  216. // Update the avatar
  217. if (icon_id.notNull())
  218. {
  219. LLIconCtrl::setValue(icon_id);
  220. }
  221. else
  222. {
  223. LLIconCtrl::setValue(mDefaultIconName);
  224. }
  225. return true;
  226. }
  227. //virtual
  228. void LLAvatarIconCtrl::processProperties(void* data, EAvatarProcessorType type)
  229. {
  230. if (APT_PROPERTIES == type)
  231. {
  232. LLAvatarData* avatar_data = static_cast<LLAvatarData*>(data);
  233. if (avatar_data)
  234. {
  235. if (avatar_data->avatar_id != mAvatarId)
  236. {
  237. return;
  238. }
  239. LLAvatarIconIDCache::getInstance()->add(mAvatarId,avatar_data->image_id);
  240. updateFromCache();
  241. }
  242. }
  243. }
  244. void LLAvatarIconCtrl::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
  245. {
  246. if (agent_id == mAvatarId)
  247. {
  248. // Most avatar icon controls are next to a UI element that shows
  249. // a display name, so only show username.
  250. mFullName = av_name.mUsername;
  251. if (mDrawTooltip)
  252. {
  253. setToolTip(mFullName);
  254. }
  255. else
  256. {
  257. setToolTip(std::string());
  258. }
  259. }
  260. }