NotifyList.cpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. /*
  2. * The contents of this file are subject to the Mozilla Public
  3. * License Version 1.1 (the "License"); you may not use this file
  4. * except in compliance with the License. You may obtain a copy of
  5. * the License at http://www.mozilla.org/MPL/
  6. *
  7. * Software distributed under the License is distributed on an "AS
  8. * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9. * implied. See the License for the specific language governing
  10. * rights and limitations under the License.
  11. *
  12. * The Original Code is Vision.
  13. *
  14. * The Initial Developer of the Original Code is The Vision Team.
  15. * Portions created by The Vision Team are
  16. * Copyright (C) 1999, 2000, 2001 The Vision Team. All Rights
  17. * Reserved.
  18. *
  19. * Contributor(s): Rene Gollent
  20. * Alan Ellis <alan@cgsoftware.org>
  21. *
  22. */
  23. #include <MenuItem.h>
  24. #include <PopUpMenu.h>
  25. #include "ClientWindow.h"
  26. #include "ClientWindowDock.h"
  27. #include "NotifyList.h"
  28. #include "Theme.h"
  29. #include "Utilities.h"
  30. #include "Vision.h"
  31. #include "WindowList.h"
  32. NotifyList::NotifyList (BRect _frame)
  33. : BListView (_frame,
  34. "NotifyList",
  35. B_SINGLE_SELECTION_LIST,
  36. B_FOLLOW_ALL ),
  37. fActiveTheme (vision_app->ActiveTheme()),
  38. fLastButton (0),
  39. fClickCount (0),
  40. fLastClick (0,0),
  41. fLastClickTime (0),
  42. fMyPopUp (NULL)
  43. {
  44. fActiveTheme->ReadLock();
  45. SetFont (&fActiveTheme->FontAt (F_WINLIST));
  46. SetViewColor (fActiveTheme->ForegroundAt (C_NOTIFYLIST_BACKGROUND));
  47. fActiveTheme->ReadUnlock();
  48. }
  49. NotifyList::~NotifyList (void)
  50. {
  51. while (CountItems() > 0)
  52. delete RemoveItem ((int32)0);
  53. delete fMyPopUp;
  54. }
  55. void
  56. NotifyList::UpdateList(BObjectList<NotifyListItem> *newList)
  57. {
  58. while (CountItems() > 0)
  59. delete RemoveItem ((int32)0);
  60. BList updateList;
  61. // make private copy of list items otherwise things go bad
  62. for (int32 i = 0; i < newList->CountItems(); i++)
  63. updateList.AddItem (new NotifyListItem (*newList->ItemAt(i)));
  64. AddList(&updateList);
  65. }
  66. void
  67. NotifyList::AttachedToWindow (void)
  68. {
  69. fActiveTheme->AddView(this);
  70. BListView::AttachedToWindow ();
  71. }
  72. void
  73. NotifyList::DetachedFromWindow (void)
  74. {
  75. fActiveTheme->RemoveView(this);
  76. BListView::DetachedFromWindow ();
  77. }
  78. void
  79. NotifyList::MouseDown (BPoint myPoint)
  80. {
  81. BMessage *msg (Window()->CurrentMessage());
  82. int32 selected (IndexOf (myPoint));
  83. if (selected >= 0)
  84. {
  85. BMessage *inputMsg (Window()->CurrentMessage());
  86. int32 mousebuttons (0),
  87. keymodifiers (0);
  88. NotifyListItem *item ((NotifyListItem *)ItemAt(selected));
  89. if (!item)
  90. return;
  91. inputMsg->FindInt32 ("buttons", &mousebuttons);
  92. inputMsg->FindInt32 ("modifiers", &keymodifiers);
  93. bigtime_t sysTime;
  94. msg->FindInt64 ("when", &sysTime);
  95. uint16 clicks = CheckClickCount (myPoint, fLastClick, sysTime, fLastClickTime, fClickCount) % 3;
  96. // slight kludge to make sure the expand/collapse triangles behave how they should
  97. // -- needed since OutlineListView's Expand/Collapse-related functions are not virtual
  98. if (mousebuttons == B_PRIMARY_MOUSE_BUTTON)
  99. {
  100. if (((clicks % 2) == 0) && item->GetState())
  101. {
  102. // react to double click by creating a new messageagent or selecting
  103. // an existing one (use /query logic in parsecmd)
  104. BString data (item->Text());
  105. data.Prepend ("/QUERY ");
  106. BMessage submitMsg (M_SUBMIT);
  107. submitMsg.AddString ("input", data.String());
  108. submitMsg.AddBool ("history", false);
  109. // don't clear in case user has something typed in text control
  110. submitMsg.AddBool ("clear", false);
  111. WindowListItem *winItem ((WindowListItem *)vision_app->pClientWin()->pWindowList()->ItemAt(
  112. vision_app->pClientWin()->pWindowList()->CurrentSelection()));
  113. if (winItem)
  114. {
  115. BMessenger msgr (winItem->pAgent());
  116. if (msgr.IsValid())
  117. msgr.SendMessage(&submitMsg);
  118. }
  119. }
  120. else
  121. Select (selected);
  122. }
  123. if ((keymodifiers & B_SHIFT_KEY) == 0
  124. && (keymodifiers & B_OPTION_KEY) == 0
  125. && (keymodifiers & B_COMMAND_KEY) == 0
  126. && (keymodifiers & B_CONTROL_KEY) == 0)
  127. {
  128. if (mousebuttons == B_SECONDARY_MOUSE_BUTTON)
  129. {
  130. if (item)
  131. {
  132. if(!item->IsSelected())
  133. Select (IndexOf (myPoint));
  134. BuildPopUp();
  135. fMyPopUp->Go (
  136. ConvertToScreen (myPoint),
  137. true,
  138. true,
  139. ConvertToScreen (ItemFrame (selected)),
  140. true);
  141. }
  142. }
  143. }
  144. }
  145. }
  146. void
  147. NotifyList::BuildPopUp(void)
  148. {
  149. delete fMyPopUp;
  150. fMyPopUp = new BPopUpMenu("Notify selection", false, false);
  151. int index (CurrentSelection());
  152. if (index < 0)
  153. return;
  154. NotifyListItem *item (dynamic_cast<NotifyListItem *>(ItemAt(index)));
  155. if (item)
  156. {
  157. BString name (item->Text());
  158. BMessage msg (M_SUBMIT);
  159. BString data ("/QUERY ");
  160. data.Append(name);
  161. msg.AddString("input", data.String());
  162. msg.AddBool ("history", false);
  163. msg.AddBool ("clear", false);
  164. fMyPopUp->AddItem (new BMenuItem (S_NOTIFYLIST_QUERY_ITEM, new BMessage (msg)));
  165. data = "/WHOIS ";
  166. data.Append(name);
  167. msg.ReplaceString("input", data.String());
  168. fMyPopUp->AddItem (new BMenuItem (S_NOTIFYLIST_WHOIS_ITEM, new BMessage (msg)));
  169. data = "/DCC CHAT ";
  170. data.Append(name);
  171. msg.ReplaceString("input", data.String());
  172. fMyPopUp->AddItem (new BMenuItem (S_NOTIFYLIST_DCC_ITEM, new BMessage (msg)));
  173. fMyPopUp->AddSeparatorItem();
  174. data = "/UNNOTIFY ";
  175. data.Append(name);
  176. msg.ReplaceString("input", data.String());
  177. fMyPopUp->AddItem (new BMenuItem (S_NOTIFYLIST_REMOVE_ITEM, new BMessage (msg)));
  178. WindowListItem *winItem (dynamic_cast<WindowListItem *>(
  179. vision_app->pClientWin()->pWindowList()->ItemAt(
  180. vision_app->pClientWin()->pWindowList()->CurrentSelection())));
  181. if (winItem)
  182. fMyPopUp->SetTargetForItems(winItem->pAgent());
  183. if (!item->GetState())
  184. {
  185. // user is offline, do not allow whois, query or dcc chat
  186. fMyPopUp->ItemAt(0)->SetEnabled(false);
  187. fMyPopUp->ItemAt(1)->SetEnabled(false);
  188. fMyPopUp->ItemAt(2)->SetEnabled(false);
  189. }
  190. fMyPopUp->SetFont(be_plain_font);
  191. }
  192. }
  193. void
  194. NotifyList::MessageReceived (BMessage *msg)
  195. {
  196. switch (msg->what)
  197. {
  198. case M_NOTIFYLIST_RESIZE:
  199. {
  200. ClientWindow *cWin (vision_app->pClientWin());
  201. cWin->DispatchMessage (msg, cWin->pCwDock());
  202. break;
  203. }
  204. case M_THEME_FOREGROUND_CHANGE:
  205. {
  206. int16 which (msg->FindInt16 ("which"));
  207. bool refresh (false);
  208. switch (which)
  209. {
  210. case C_NOTIFYLIST_BACKGROUND:
  211. fActiveTheme->ReadLock();
  212. SetViewColor (fActiveTheme->ForegroundAt (C_NOTIFYLIST_BACKGROUND));
  213. fActiveTheme->ReadUnlock();
  214. refresh = true;
  215. break;
  216. case C_NOTIFY_ON:
  217. case C_NOTIFY_OFF:
  218. case C_NOTIFYLIST_SELECTION:
  219. refresh = true;
  220. break;
  221. }
  222. if (refresh)
  223. Invalidate();
  224. }
  225. break;
  226. case M_THEME_FONT_CHANGE:
  227. {
  228. int16 which (msg->FindInt16 ("which"));
  229. if (which == F_WINLIST)
  230. {
  231. fActiveTheme->ReadLock();
  232. SetFont (&fActiveTheme->FontAt (F_WINLIST));
  233. fActiveTheme->ReadUnlock();
  234. Invalidate();
  235. }
  236. }
  237. break;
  238. default:
  239. BListView::MessageReceived (msg);
  240. }
  241. }
  242. NotifyListItem::NotifyListItem (const char *name, bool state)
  243. : BStringItem (name),
  244. fNotifyState (state)
  245. {
  246. // empty c'tor
  247. }
  248. NotifyListItem::NotifyListItem (const NotifyListItem &copyItem)
  249. : BStringItem (copyItem.Text()),
  250. fNotifyState (copyItem.fNotifyState)
  251. {
  252. // empty copy c'tor
  253. }
  254. NotifyListItem::~NotifyListItem (void)
  255. {
  256. // empty d'tor
  257. }
  258. void
  259. NotifyListItem::SetState (bool newState)
  260. {
  261. fNotifyState = newState;
  262. }
  263. bool
  264. NotifyListItem::GetState(void) const
  265. {
  266. return fNotifyState;
  267. }
  268. void
  269. NotifyListItem::DrawItem (BView *father, BRect frame, bool complete)
  270. {
  271. Theme *fActiveTheme (vision_app->ActiveTheme());
  272. fActiveTheme->ReadLock();
  273. if (IsSelected())
  274. {
  275. father->SetHighColor (fActiveTheme->ForegroundAt (C_NOTIFYLIST_SELECTION));
  276. father->SetLowColor (fActiveTheme->ForegroundAt (C_NOTIFYLIST_BACKGROUND));
  277. father->FillRect (frame);
  278. }
  279. else if (complete)
  280. {
  281. father->SetLowColor (fActiveTheme->ForegroundAt (C_NOTIFYLIST_BACKGROUND));
  282. father->FillRect (frame, B_SOLID_LOW);
  283. }
  284. rgb_color color = fActiveTheme->ForegroundAt ((fNotifyState) ? C_NOTIFY_ON : C_NOTIFY_OFF);
  285. font_height fh;
  286. father->GetFontHeight (&fh);
  287. father->MovePenTo (
  288. frame.left + 4,
  289. frame.bottom - fh.descent);
  290. BString drawString (Text());
  291. fActiveTheme->ReadUnlock();
  292. father->SetHighColor (color);
  293. father->SetDrawingMode (B_OP_OVER);
  294. father->DrawString (drawString.String());
  295. father->SetDrawingMode (B_OP_COPY);
  296. }