llgrouplist.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:12k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llgrouplist.cpp
  3.  * @brief List of the groups the agent belongs to.
  4.  *
  5.  * $LicenseInfo:firstyear=2009&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2009-2010, 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 "llgrouplist.h"
  34. // libs
  35. #include "llbutton.h"
  36. #include "lliconctrl.h"
  37. #include "llmenugl.h"
  38. #include "lltextbox.h"
  39. #include "lltrans.h"
  40. // newview
  41. #include "llagent.h"
  42. #include "llgroupactions.h"
  43. #include "llfloaterreg.h"
  44. #include "lltextutil.h"
  45. #include "llviewercontrol.h" // for gSavedSettings
  46. #include "llviewermenu.h" // for gMenuHolder
  47. #include "llvoiceclient.h"
  48. static LLDefaultChildRegistry::Register<LLGroupList> r("group_list");
  49. S32 LLGroupListItem::sIconWidth = 0;
  50. class LLGroupComparator : public LLFlatListView::ItemComparator
  51. {
  52. public:
  53. /** Returns true if item1 < item2, false otherwise */
  54. /*virtual*/ bool compare(const LLPanel* item1, const LLPanel* item2) const
  55. {
  56. std::string name1 = static_cast<const LLGroupListItem*>(item1)->getGroupName();
  57. std::string name2 = static_cast<const LLGroupListItem*>(item2)->getGroupName();
  58. LLStringUtil::toUpper(name1);
  59. LLStringUtil::toUpper(name2);
  60. return name1 < name2;
  61. }
  62. };
  63. static const LLGroupComparator GROUP_COMPARATOR;
  64. LLGroupList::Params::Params()
  65. : no_groups_msg("no_groups_msg")
  66. , no_filtered_groups_msg("no_filtered_groups_msg")
  67. {
  68. }
  69. LLGroupList::LLGroupList(const Params& p)
  70. : LLFlatListView(p)
  71. , mDirty(true) // to force initial update
  72. , mNoFilteredGroupsMsg(p.no_filtered_groups_msg)
  73. , mNoGroupsMsg(p.no_groups_msg)
  74. {
  75. // Listen for agent group changes.
  76. gAgent.addListener(this, "new group");
  77. mShowIcons = gSavedSettings.getBOOL("GroupListShowIcons");
  78. setCommitOnSelectionChange(true);
  79. // Set default sort order.
  80. setComparator(&GROUP_COMPARATOR);
  81. // Set up context menu.
  82. LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
  83. LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
  84. registrar.add("People.Groups.Action", boost::bind(&LLGroupList::onContextMenuItemClick, this, _2));
  85. enable_registrar.add("People.Groups.Enable", boost::bind(&LLGroupList::onContextMenuItemEnable, this, _2));
  86. LLMenuGL* context_menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_people_groups.xml",
  87. gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
  88. if(context_menu)
  89. mContextMenuHandle = context_menu->getHandle();
  90. }
  91. LLGroupList::~LLGroupList()
  92. {
  93. gAgent.removeListener(this);
  94. LLView::deleteViewByHandle(mContextMenuHandle);
  95. }
  96. // virtual
  97. void LLGroupList::draw()
  98. {
  99. if (mDirty)
  100. refresh();
  101. LLFlatListView::draw();
  102. }
  103. // virtual
  104. BOOL LLGroupList::handleRightMouseDown(S32 x, S32 y, MASK mask)
  105. {
  106. BOOL handled = LLUICtrl::handleRightMouseDown(x, y, mask);
  107. LLMenuGL* context_menu = (LLMenuGL*)mContextMenuHandle.get();
  108. if (context_menu)
  109. {
  110. context_menu->buildDrawLabels();
  111. context_menu->updateParent(LLMenuGL::sMenuContainer);
  112. LLMenuGL::showPopup(this, context_menu, x, y);
  113. }
  114. return handled;
  115. }
  116. void LLGroupList::setNameFilter(const std::string& filter)
  117. {
  118. if (mNameFilter != filter)
  119. {
  120. mNameFilter = filter;
  121. setDirty();
  122. }
  123. }
  124. static bool findInsensitive(std::string haystack, const std::string& needle_upper)
  125. {
  126.     LLStringUtil::toUpper(haystack);
  127.     return haystack.find(needle_upper) != std::string::npos;
  128. }
  129. void LLGroupList::refresh()
  130. {
  131. const LLUUID&  highlight_id = gAgent.getGroupID();
  132. S32 count = gAgent.mGroups.count();
  133. LLUUID id;
  134. bool have_filter = !mNameFilter.empty();
  135. // set no items message depend on filter state & total count of groups
  136. if (have_filter)
  137. {
  138. // groups were filtered
  139. setNoItemsCommentText(mNoFilteredGroupsMsg);
  140. }
  141. else if (0 == count)
  142. {
  143. // user is not a member of any group
  144. setNoItemsCommentText(mNoGroupsMsg);
  145. }
  146. clear();
  147. for(S32 i = 0; i < count; ++i)
  148. {
  149. id = gAgent.mGroups.get(i).mID;
  150. const LLGroupData& group_data = gAgent.mGroups.get(i);
  151. if (have_filter && !findInsensitive(group_data.mName, mNameFilter))
  152. continue;
  153. addNewItem(id, group_data.mName, group_data.mInsigniaID, ADD_BOTTOM);
  154. }
  155. // Sort the list.
  156. sort();
  157. // Add "none" to list at top if filter not set (what's the point of filtering "none"?).
  158. // but only if some real groups exists. EXT-4838
  159. if (!have_filter && count > 0)
  160. {
  161. std::string loc_none = LLTrans::getString("GroupsNone");
  162. addNewItem(LLUUID::null, loc_none, LLUUID::null, ADD_TOP);
  163. }
  164. selectItemByUUID(highlight_id);
  165. setDirty(false);
  166. onCommit();
  167. }
  168. void LLGroupList::toggleIcons()
  169. {
  170. // Save the new value for new items to use.
  171. mShowIcons = !mShowIcons;
  172. gSavedSettings.setBOOL("GroupListShowIcons", mShowIcons);
  173. // Show/hide icons for all existing items.
  174. std::vector<LLPanel*> items;
  175. getItems(items);
  176. for( std::vector<LLPanel*>::const_iterator it = items.begin(); it != items.end(); it++)
  177. {
  178. static_cast<LLGroupListItem*>(*it)->setGroupIconVisible(mShowIcons);
  179. }
  180. }
  181. //////////////////////////////////////////////////////////////////////////
  182. // PRIVATE Section
  183. //////////////////////////////////////////////////////////////////////////
  184. void LLGroupList::addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, EAddPosition pos)
  185. {
  186. LLGroupListItem* item = new LLGroupListItem();
  187. item->setGroupID(id);
  188. item->setName(name, mNameFilter);
  189. item->setGroupIconID(icon_id);
  190. item->childSetVisible("info_btn", false);
  191. item->childSetVisible("profile_btn", false);
  192. item->setGroupIconVisible(mShowIcons);
  193. addItem(item, id, pos);
  194. // setCommentVisible(false);
  195. }
  196. // virtual
  197. bool LLGroupList::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
  198. {
  199. // Why is "new group" sufficient?
  200. if (event->desc() == "new group")
  201. {
  202. setDirty();
  203. return true;
  204. }
  205. return false;
  206. }
  207. bool LLGroupList::onContextMenuItemClick(const LLSD& userdata)
  208. {
  209. std::string action = userdata.asString();
  210. LLUUID selected_group = getSelectedUUID();
  211. if (action == "view_info")
  212. {
  213. LLGroupActions::show(selected_group);
  214. }
  215. else if (action == "chat")
  216. {
  217. LLGroupActions::startIM(selected_group);
  218. }
  219. else if (action == "call")
  220. {
  221. LLGroupActions::startCall(selected_group);
  222. }
  223. else if (action == "activate")
  224. {
  225. LLGroupActions::activate(selected_group);
  226. }
  227. else if (action == "leave")
  228. {
  229. LLGroupActions::leave(selected_group);
  230. }
  231. return true;
  232. }
  233. bool LLGroupList::onContextMenuItemEnable(const LLSD& userdata)
  234. {
  235. LLUUID selected_group_id = getSelectedUUID();
  236. bool real_group_selected = selected_group_id.notNull(); // a "real" (not "none") group is selected
  237. // each group including "none" can be activated
  238. if (userdata.asString() == "activate")
  239. return gAgent.getGroupID() != selected_group_id;
  240. if (userdata.asString() == "call")
  241. return real_group_selected && LLVoiceClient::voiceEnabled()&&gVoiceClient->voiceWorking();
  242. return real_group_selected;
  243. }
  244. /************************************************************************/
  245. /*          LLGroupListItem implementation                              */
  246. /************************************************************************/
  247. LLGroupListItem::LLGroupListItem()
  248. : LLPanel(),
  249. mGroupIcon(NULL),
  250. mGroupNameBox(NULL),
  251. mInfoBtn(NULL),
  252. mGroupID(LLUUID::null)
  253. {
  254. LLUICtrlFactory::getInstance()->buildPanel(this, "panel_group_list_item.xml");
  255. // Remember group icon width including its padding from the name text box,
  256. // so that we can hide and show the icon again later.
  257. if (!sIconWidth)
  258. {
  259. sIconWidth = mGroupNameBox->getRect().mLeft - mGroupIcon->getRect().mLeft;
  260. }
  261. }
  262. LLGroupListItem::~LLGroupListItem()
  263. {
  264. LLGroupMgr::getInstance()->removeObserver(this);
  265. }
  266. //virtual
  267. BOOL  LLGroupListItem::postBuild()
  268. {
  269. mGroupIcon = getChild<LLIconCtrl>("group_icon");
  270. mGroupNameBox = getChild<LLTextBox>("group_name");
  271. mInfoBtn = getChild<LLButton>("info_btn");
  272. mInfoBtn->setClickedCallback(boost::bind(&LLGroupListItem::onInfoBtnClick, this));
  273. childSetAction("profile_btn", boost::bind(&LLGroupListItem::onProfileBtnClick, this));
  274. return TRUE;
  275. }
  276. //virtual
  277. void LLGroupListItem::setValue( const LLSD& value )
  278. {
  279. if (!value.isMap()) return;
  280. if (!value.has("selected")) return;
  281. childSetVisible("selected_icon", value["selected"]);
  282. }
  283. void LLGroupListItem::onMouseEnter(S32 x, S32 y, MASK mask)
  284. {
  285. childSetVisible("hovered_icon", true);
  286. if (mGroupID.notNull()) // don't show the info button for the "none" group
  287. {
  288. mInfoBtn->setVisible(true);
  289. childSetVisible("profile_btn", true);
  290. }
  291. LLPanel::onMouseEnter(x, y, mask);
  292. }
  293. void LLGroupListItem::onMouseLeave(S32 x, S32 y, MASK mask)
  294. {
  295. childSetVisible("hovered_icon", false);
  296. mInfoBtn->setVisible(false);
  297. childSetVisible("profile_btn", false);
  298. LLPanel::onMouseLeave(x, y, mask);
  299. }
  300. void LLGroupListItem::setName(const std::string& name, const std::string& highlight)
  301. {
  302. mGroupName = name;
  303. LLTextUtil::textboxSetHighlightedVal(mGroupNameBox, mGroupNameStyle, name, highlight);
  304. mGroupNameBox->setToolTip(name);
  305. }
  306. void LLGroupListItem::setGroupID(const LLUUID& group_id)
  307. {
  308. LLGroupMgr::getInstance()->removeObserver(this);
  309. mID = group_id;
  310. mGroupID = group_id;
  311. setActive(group_id == gAgent.getGroupID());
  312. LLGroupMgr::getInstance()->addObserver(this);
  313. }
  314. void LLGroupListItem::setGroupIconID(const LLUUID& group_icon_id)
  315. {
  316. if (group_icon_id.notNull())
  317. {
  318. mGroupIcon->setValue(group_icon_id);
  319. }
  320. }
  321. void LLGroupListItem::setGroupIconVisible(bool visible)
  322. {
  323. // Already done? Then do nothing.
  324. if (mGroupIcon->getVisible() == (BOOL)visible)
  325. return;
  326. // Show/hide the group icon.
  327. mGroupIcon->setVisible(visible);
  328. // Move the group name horizontally by icon size + its distance from the group name.
  329. LLRect name_rect = mGroupNameBox->getRect();
  330. name_rect.mLeft += visible ? sIconWidth : -sIconWidth;
  331. mGroupNameBox->setRect(name_rect);
  332. }
  333. //////////////////////////////////////////////////////////////////////////
  334. // Private Section
  335. //////////////////////////////////////////////////////////////////////////
  336. void LLGroupListItem::setActive(bool active)
  337. {
  338. // *BUG: setName() overrides the style params.
  339. // Active group should be bold.
  340. LLFontDescriptor new_desc(mGroupNameBox->getDefaultFont()->getFontDesc());
  341. // *NOTE dzaporozhan
  342. // On Windows LLFontGL::NORMAL will not remove LLFontGL::BOLD if font 
  343. // is predefined as bold (SansSerifSmallBold, for example)
  344. new_desc.setStyle(active ? LLFontGL::BOLD : LLFontGL::NORMAL);
  345. LLFontGL* new_font = LLFontGL::getFont(new_desc);
  346. mGroupNameStyle.font = new_font;
  347. // *NOTE: You cannot set the style on a text box anymore, you must
  348. // rebuild the text.  This will cause problems if the text contains
  349. // hyperlinks, as their styles will be wrong.
  350. mGroupNameBox->setText(mGroupName, mGroupNameStyle);
  351. }
  352. void LLGroupListItem::onInfoBtnClick()
  353. {
  354. LLFloaterReg::showInstance("inspect_group", LLSD().with("group_id", mGroupID));
  355. }
  356. void LLGroupListItem::onProfileBtnClick()
  357. {
  358. LLGroupActions::show(mGroupID);
  359. }
  360. void LLGroupListItem::changed(LLGroupChange gc)
  361. {
  362. LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(mID);
  363. if(group_data)
  364. setGroupIconID(group_data->mInsigniaID);
  365. }
  366. //EOF