/indra/newview/llnearbychat.cpp

https://bitbucket.org/lindenlab/viewer-beta/ · C++ · 338 lines · 231 code · 63 blank · 44 comment · 38 complexity · 14dd42f5a19b9918afd5b5dfbdee12d9 MD5 · raw file

  1. /**
  2. * @file LLNearbyChat.cpp
  3. * @brief Nearby chat history scrolling panel 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 "llnearbychat.h"
  28. #include "llviewercontrol.h"
  29. #include "llviewerwindow.h"
  30. #include "llrootview.h"
  31. //#include "llchatitemscontainerctrl.h"
  32. #include "lliconctrl.h"
  33. #include "llfloatersidepanelcontainer.h"
  34. #include "llfocusmgr.h"
  35. #include "lllogchat.h"
  36. #include "llresizebar.h"
  37. #include "llresizehandle.h"
  38. #include "llmenugl.h"
  39. #include "llviewermenu.h"//for gMenuHolder
  40. #include "llnearbychathandler.h"
  41. #include "llchannelmanager.h"
  42. #include "llagent.h" // gAgent
  43. #include "llchathistory.h"
  44. #include "llstylemap.h"
  45. #include "llavatarnamecache.h"
  46. #include "lldraghandle.h"
  47. #include "llnearbychatbar.h"
  48. #include "llfloaterreg.h"
  49. #include "lltrans.h"
  50. static const S32 RESIZE_BAR_THICKNESS = 3;
  51. static LLRegisterPanelClassWrapper<LLNearbyChat> t_panel_nearby_chat("panel_nearby_chat");
  52. LLNearbyChat::LLNearbyChat(const LLNearbyChat::Params& p)
  53. : LLPanel(p),
  54. mChatHistory(NULL)
  55. {
  56. }
  57. BOOL LLNearbyChat::postBuild()
  58. {
  59. //menu
  60. LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
  61. LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
  62. enable_registrar.add("NearbyChat.Check", boost::bind(&LLNearbyChat::onNearbyChatCheckContextMenuItem, this, _2));
  63. registrar.add("NearbyChat.Action", boost::bind(&LLNearbyChat::onNearbyChatContextMenuItemClicked, this, _2));
  64. LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_nearby_chat.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
  65. if(menu)
  66. mPopupMenuHandle = menu->getHandle();
  67. gSavedSettings.declareS32("nearbychat_showicons_and_names",2,"NearByChat header settings",true);
  68. mChatHistory = getChild<LLChatHistory>("chat_history");
  69. if(!LLPanel::postBuild())
  70. return false;
  71. return true;
  72. }
  73. std::string appendTime()
  74. {
  75. time_t utc_time;
  76. utc_time = time_corrected();
  77. std::string timeStr ="["+ LLTrans::getString("TimeHour")+"]:["
  78. +LLTrans::getString("TimeMin")+"]";
  79. LLSD substitution;
  80. substitution["datetime"] = (S32) utc_time;
  81. LLStringUtil::format (timeStr, substitution);
  82. return timeStr;
  83. }
  84. void LLNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args)
  85. {
  86. LLChat& tmp_chat = const_cast<LLChat&>(chat);
  87. if(tmp_chat.mTimeStr.empty())
  88. tmp_chat.mTimeStr = appendTime();
  89. bool use_plain_text_chat_history = gSavedSettings.getBOOL("PlainTextChatHistory");
  90. if (!chat.mMuted)
  91. {
  92. tmp_chat.mFromName = chat.mFromName;
  93. LLSD chat_args = args;
  94. chat_args["use_plain_text_chat_history"] = use_plain_text_chat_history;
  95. mChatHistory->appendMessage(chat, chat_args);
  96. }
  97. if(archive)
  98. {
  99. mMessageArchive.push_back(chat);
  100. if(mMessageArchive.size()>200)
  101. mMessageArchive.erase(mMessageArchive.begin());
  102. }
  103. if (args["do_not_log"].asBoolean())
  104. {
  105. return;
  106. }
  107. if (gSavedPerAccountSettings.getBOOL("LogNearbyChat"))
  108. {
  109. std::string from_name = chat.mFromName;
  110. if (chat.mSourceType == CHAT_SOURCE_AGENT)
  111. {
  112. // if the chat is coming from an agent, log the complete name
  113. LLAvatarName av_name;
  114. LLAvatarNameCache::get(chat.mFromID, &av_name);
  115. if (!av_name.mIsDisplayNameDefault)
  116. {
  117. from_name = av_name.getCompleteName();
  118. }
  119. }
  120. LLLogChat::saveHistory("chat", from_name, chat.mFromID, chat.mText);
  121. }
  122. }
  123. void LLNearbyChat::onNearbySpeakers()
  124. {
  125. LLSD param;
  126. param["people_panel_tab_name"] = "nearby_panel";
  127. LLFloaterSidePanelContainer::showPanel("people", "panel_people", param);
  128. }
  129. void LLNearbyChat::onNearbyChatContextMenuItemClicked(const LLSD& userdata)
  130. {
  131. }
  132. bool LLNearbyChat::onNearbyChatCheckContextMenuItem(const LLSD& userdata)
  133. {
  134. std::string str = userdata.asString();
  135. if(str == "nearby_people")
  136. onNearbySpeakers();
  137. return false;
  138. }
  139. void LLNearbyChat::removeScreenChat()
  140. {
  141. LLNotificationsUI::LLScreenChannelBase* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
  142. if(chat_channel)
  143. {
  144. chat_channel->removeToastsFromChannel();
  145. }
  146. }
  147. void LLNearbyChat::setVisible(BOOL visible)
  148. {
  149. if(visible)
  150. {
  151. removeScreenChat();
  152. }
  153. LLPanel::setVisible(visible);
  154. }
  155. void LLNearbyChat::getAllowedRect(LLRect& rect)
  156. {
  157. rect = gViewerWindow->getWorldViewRectScaled();
  158. }
  159. void LLNearbyChat::updateChatHistoryStyle()
  160. {
  161. mChatHistory->clear();
  162. LLSD do_not_log;
  163. do_not_log["do_not_log"] = true;
  164. for(std::vector<LLChat>::iterator it = mMessageArchive.begin();it!=mMessageArchive.end();++it)
  165. {
  166. // Update the messages without re-writing them to a log file.
  167. addMessage(*it,false, do_not_log);
  168. }
  169. }
  170. //static
  171. void LLNearbyChat::processChatHistoryStyleUpdate(const LLSD& newvalue)
  172. {
  173. LLFloater* chat_bar = LLFloaterReg::getInstance("chat_bar");
  174. LLNearbyChat* nearby_chat = chat_bar->findChild<LLNearbyChat>("nearby_chat");
  175. if(nearby_chat)
  176. nearby_chat->updateChatHistoryStyle();
  177. }
  178. bool isWordsName(const std::string& name)
  179. {
  180. // checking to see if it's display name plus username in parentheses
  181. S32 open_paren = name.find(" (", 0);
  182. S32 close_paren = name.find(')', 0);
  183. if (open_paren != std::string::npos &&
  184. close_paren == name.length()-1)
  185. {
  186. return true;
  187. }
  188. else
  189. {
  190. //checking for a single space
  191. S32 pos = name.find(' ', 0);
  192. return std::string::npos != pos && name.rfind(' ', name.length()) == pos && 0 != pos && name.length()-1 != pos;
  193. }
  194. }
  195. void LLNearbyChat::loadHistory()
  196. {
  197. LLSD do_not_log;
  198. do_not_log["do_not_log"] = true;
  199. std::list<LLSD> history;
  200. LLLogChat::loadAllHistory("chat", history);
  201. std::list<LLSD>::const_iterator it = history.begin();
  202. while (it != history.end())
  203. {
  204. const LLSD& msg = *it;
  205. std::string from = msg[IM_FROM];
  206. LLUUID from_id;
  207. if (msg[IM_FROM_ID].isDefined())
  208. {
  209. from_id = msg[IM_FROM_ID].asUUID();
  210. }
  211. else
  212. {
  213. std::string legacy_name = gCacheName->buildLegacyName(from);
  214. gCacheName->getUUID(legacy_name, from_id);
  215. }
  216. LLChat chat;
  217. chat.mFromName = from;
  218. chat.mFromID = from_id;
  219. chat.mText = msg[IM_TEXT].asString();
  220. chat.mTimeStr = msg[IM_TIME].asString();
  221. chat.mChatStyle = CHAT_STYLE_HISTORY;
  222. chat.mSourceType = CHAT_SOURCE_AGENT;
  223. if (from_id.isNull() && SYSTEM_FROM == from)
  224. {
  225. chat.mSourceType = CHAT_SOURCE_SYSTEM;
  226. }
  227. else if (from_id.isNull())
  228. {
  229. chat.mSourceType = isWordsName(from) ? CHAT_SOURCE_UNKNOWN : CHAT_SOURCE_OBJECT;
  230. }
  231. addMessage(chat, true, do_not_log);
  232. it++;
  233. }
  234. }
  235. //static
  236. LLNearbyChat* LLNearbyChat::getInstance()
  237. {
  238. LLFloater* chat_bar = LLFloaterReg::getInstance("chat_bar");
  239. return chat_bar->findChild<LLNearbyChat>("nearby_chat");
  240. }
  241. ////////////////////////////////////////////////////////////////////////////////
  242. //
  243. void LLNearbyChat::onFocusReceived()
  244. {
  245. setBackgroundOpaque(true);
  246. LLPanel::onFocusReceived();
  247. }
  248. ////////////////////////////////////////////////////////////////////////////////
  249. //
  250. void LLNearbyChat::onFocusLost()
  251. {
  252. setBackgroundOpaque(false);
  253. LLPanel::onFocusLost();
  254. }
  255. BOOL LLNearbyChat::handleMouseDown(S32 x, S32 y, MASK mask)
  256. {
  257. //fix for EXT-6625
  258. //highlight NearbyChat history whenever mouseclick happen in NearbyChat
  259. //setting focus to eidtor will force onFocusLost() call that in its turn will change
  260. //background opaque. This all happenn since NearByChat is "chrome" and didn't process focus change.
  261. if(mChatHistory)
  262. mChatHistory->setFocus(TRUE);
  263. return LLPanel::handleMouseDown(x, y, mask);
  264. }
  265. void LLNearbyChat::draw()
  266. {
  267. // *HACK: Update transparency type depending on whether our children have focus.
  268. // This is needed because this floater is chrome and thus cannot accept focus, so
  269. // the transparency type setting code from LLFloater::setFocus() isn't reached.
  270. if (getTransparencyType() != TT_DEFAULT)
  271. {
  272. setTransparencyType(hasFocus() ? TT_ACTIVE : TT_INACTIVE);
  273. }
  274. LLPanel::draw();
  275. }