RosterEditWindow.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. /*
  2. * Copyright 2009-2011, Andrea Anzani. All rights reserved.
  3. * Copyright 2009-2011, Pier Luigi Fiorini. All rights reserved.
  4. * Copyright 2021, Jaidyn Levesque. All rights reserved.
  5. * Distributed under the terms of the MIT License.
  6. *
  7. * Authors:
  8. * Andrea Anzani, andrea.anzani@gmail.com
  9. * Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
  10. * Jaidyn Levesque, jadedctrl@teknik.io
  11. */
  12. #include "RosterEditWindow.h"
  13. #include <Button.h>
  14. #include <Catalog.h>
  15. #include <LayoutBuilder.h>
  16. #include <MenuField.h>
  17. #include <Notification.h>
  18. #include <ScrollView.h>
  19. #include <SeparatorView.h>
  20. #include "AccountsMenu.h"
  21. #include "AppMessages.h"
  22. #include "AppPreferences.h"
  23. #include "ChatProtocolMessages.h"
  24. #include "RosterItem.h"
  25. #include "RosterListView.h"
  26. #include "RosterView.h"
  27. #include "TemplateWindow.h"
  28. #undef B_TRANSLATION_CONTEXT
  29. #define B_TRANSLATION_CONTEXT "RosterEditWindow"
  30. const uint32 kSendMessage = 'RWSM';
  31. const uint32 kAddMember = 'RWAM';
  32. const uint32 kRemoveMember = 'RWRM';
  33. const uint32 kEditMember = 'RWEM';
  34. const uint32 kSelAccount = 'RWSA';
  35. const uint32 kSelNoAccount = 'RWNA';
  36. const char* kAddTitle = B_TRANSLATE("Adding contact");
  37. const char* kEditTitle = B_TRANSLATE("Editing contact");
  38. RosterEditWindow* RosterEditWindow::fInstance = NULL;
  39. RosterEditWindow::RosterEditWindow(Server* server)
  40. :
  41. BWindow(BRect(0, 0, 300, 400), B_TRANSLATE("Roster"), B_FLOATING_WINDOW,
  42. B_AUTO_UPDATE_SIZE_LIMITS),
  43. fServer(server),
  44. fEditingWindow(NULL)
  45. {
  46. fRosterView = new RosterView("buddyView", server);
  47. fRosterView->SetInvocationMessage(new BMessage(kEditMember));
  48. fRosterView->SetManualString(BString("Add %user% as contact"
  49. B_UTF8_ELLIPSIS));
  50. fAccountField = new BMenuField("accountMenuField", NULL,
  51. new AccountsMenu("accountMenu", BMessage(kSelAccount),
  52. new BMessage(kSelNoAccount)));
  53. font_height fontHeight;
  54. fRosterView->GetFontHeight(&fontHeight);
  55. int16 buttonHeight = int16(fontHeight.ascent + fontHeight.descent + 12);
  56. BSize charButtonSize(buttonHeight, buttonHeight);
  57. BButton* fAddButton = new BButton("+", new BMessage(kAddMember));
  58. BButton* fRemoveButton = new BButton("-", new BMessage(kRemoveMember));
  59. fAddButton->SetExplicitSize(charButtonSize);
  60. fRemoveButton->SetExplicitSize(charButtonSize);
  61. BLayoutBuilder::Group<>(this, B_VERTICAL, 0.0f)
  62. .SetInsets(B_USE_DEFAULT_SPACING)
  63. .Add(fRosterView)
  64. .AddGroup(B_HORIZONTAL, 0, 0.0)
  65. .Add(fAccountField)
  66. .AddGlue()
  67. .Add(new BSeparatorView(B_VERTICAL))
  68. .AddGroup(B_VERTICAL, 0, 0.0)
  69. .Add(new BSeparatorView(B_HORIZONTAL))
  70. .AddGroup(B_HORIZONTAL, 1, 0.0)
  71. .SetInsets(1)
  72. .Add(fRemoveButton)
  73. .Add(fAddButton)
  74. .End()
  75. .Add(new BSeparatorView(B_HORIZONTAL))
  76. .End()
  77. .Add(new BSeparatorView(B_VERTICAL))
  78. .End()
  79. .End();
  80. CenterOnScreen();
  81. }
  82. RosterEditWindow::~RosterEditWindow()
  83. {
  84. fInstance = NULL;
  85. }
  86. RosterEditWindow*
  87. RosterEditWindow::Get(Server* server)
  88. {
  89. if (fInstance == NULL) {
  90. fInstance = new RosterEditWindow(server);
  91. }
  92. return fInstance;
  93. }
  94. bool
  95. RosterEditWindow::Check()
  96. {
  97. return (fInstance != NULL);
  98. }
  99. void
  100. RosterEditWindow::MessageReceived(BMessage* message)
  101. {
  102. switch (message->what) {
  103. case kEditMember:
  104. {
  105. if (fEditingWindow != NULL && fEditingWindow->Lock()) {
  106. fEditingWindow->Quit();
  107. fEditingUser.SetTo("");
  108. }
  109. int index = message->FindInt32("index");
  110. RosterItem* ritem = fRosterView->ListView()->RosterItemAt(index);
  111. const char* search = fRosterView->SearchBox()->Text();
  112. User* user;
  113. BString user_id;
  114. int64 instance;
  115. if (ritem != NULL) {
  116. user = ritem->GetContact();
  117. user_id = user->GetId();
  118. instance = user->GetProtocolLooper()->GetInstance();
  119. }
  120. else if (search != NULL) {
  121. user_id = search;
  122. instance = fRosterView->GetAccount();
  123. }
  124. else
  125. break;
  126. fEditingUser.SetTo(user_id.String());
  127. // The response IM_EXTENDED_CONTACT_INFO is used to populate the
  128. // TemplateWindow― if we're editing a pre-existing contact
  129. if (ritem != NULL) {
  130. user = ritem->GetContact();
  131. BMessage* request = new BMessage(IM_MESSAGE);
  132. request->AddInt32("im_what", IM_GET_EXTENDED_CONTACT_INFO);
  133. request->AddString("user_id", user_id);
  134. user->GetProtocolLooper()->PostMessage(request);
  135. }
  136. BMessage* edit = new BMessage(IM_MESSAGE);
  137. edit->AddInt32("im_what", IM_ROSTER_EDIT_CONTACT);
  138. const char* title;
  139. if (ritem == NULL)
  140. title = kAddTitle;
  141. else
  142. title = kEditTitle;
  143. fEditingWindow =
  144. new TemplateWindow(title, "roster",
  145. edit, fServer, instance);
  146. fEditingWindow->Show();
  147. if (ritem == NULL) {
  148. BMessage* idMsg = new BMessage(IM_MESSAGE);
  149. idMsg->AddString("user_id", user_id);
  150. fEditingWindow->PostMessage(idMsg);
  151. }
  152. break;
  153. }
  154. case kAddMember:
  155. {
  156. BMessage* add = new BMessage(IM_MESSAGE);
  157. add->AddInt32("im_what", IM_ROSTER_ADD_CONTACT);
  158. TemplateWindow* win =
  159. new TemplateWindow(B_TRANSLATE(kAddTitle), "roster",
  160. add, fServer);
  161. win->Show();
  162. break;
  163. }
  164. case kRemoveMember:
  165. {
  166. int index = message->FindInt32("index");
  167. RosterItem* ritem = fRosterView->ListView()->RosterItemAt(index);
  168. if (ritem == NULL)
  169. return;
  170. User* user = ritem->GetContact();
  171. BMessage* rem = new BMessage(IM_MESSAGE);
  172. rem->AddInt32("im_what", IM_ROSTER_REMOVE_CONTACT);
  173. rem->AddString("user_id", user->GetId());
  174. user->GetProtocolLooper()->PostMessage(rem);
  175. break;
  176. }
  177. case IM_MESSAGE: {
  178. if (message->GetInt32("im_what", 0) == IM_EXTENDED_CONTACT_INFO)
  179. if (message->GetString("user_id", "") == fEditingUser)
  180. fEditingWindow->PostMessage(message);
  181. fRosterView->MessageReceived(message);
  182. break;
  183. }
  184. case kSelAccount:
  185. {
  186. AccountInstances accounts = fServer->GetActiveAccounts();
  187. int index = message->FindInt32("index") - 1;
  188. if (index < 0 || index > (accounts.CountItems() - 1))
  189. return;
  190. fRosterView->SetAccount(accounts.ValueAt(index));
  191. break;
  192. }
  193. case kSelNoAccount:
  194. fRosterView->SetAccount(-1);
  195. break;
  196. default:
  197. BWindow::MessageReceived(message);
  198. }
  199. }
  200. void
  201. RosterEditWindow::UpdateListItem(RosterItem* item)
  202. {
  203. fRosterView->UpdateListItem(item);
  204. }