From 9d72c53dd9e0f829fd480318910f6d06dd3d4b6b Mon Sep 17 00:00:00 2001 From: Jaidyn Ann Date: Fri, 18 Jun 2021 16:41:09 -0500 Subject: [PATCH] Split RosterWindow into per-account RosterView MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Most of RosterWindow's special functions have been split into a special BGroupView (including both the roster search-box and roster list), RosterView. This will give some more flexibility in other uses of the roster list. In addition, RosterViews can be tied to a specific account by its looper's instance ID, allowing it to either show all contacts (globally; if the ID is set to -1) or only those of the specified account. This can be useful, for example, when inviting contacts to a room― you can only invite contacts that use the same protocol, and are associated with your account, so showing all contacts doesn't make sense. The SearchBarTextControl class was removed, as it isn't particularly necessary. --- application/Makefile | 2 +- application/views/RosterListView.cpp | 16 ++ application/views/RosterListView.h | 4 + application/views/RosterView.cpp | 243 +++++++++++++++++++++ application/views/RosterView.h | 50 +++++ application/views/SearchBarTextControl.cpp | 34 --- application/views/SearchBarTextControl.h | 17 -- application/windows/RosterWindow.cpp | 218 +----------------- application/windows/RosterWindow.h | 17 +- 9 files changed, 327 insertions(+), 274 deletions(-) create mode 100644 application/views/RosterView.cpp create mode 100644 application/views/RosterView.h delete mode 100644 application/views/SearchBarTextControl.cpp delete mode 100644 application/views/SearchBarTextControl.h diff --git a/application/Makefile b/application/Makefile index 443c85f..2c45c64 100644 --- a/application/Makefile +++ b/application/Makefile @@ -69,7 +69,7 @@ SRCS = \ application/views/ReplicantMenuItem.cpp \ application/views/RosterItem.cpp \ application/views/RosterListView.cpp \ - application/views/SearchBarTextControl.cpp \ + application/views/RosterView.cpp \ application/views/StatusMenuItem.cpp \ application/views/StatusView.cpp \ application/views/TemplateView.cpp \ diff --git a/application/views/RosterListView.cpp b/application/views/RosterListView.cpp index ee8b048..e6490e0 100644 --- a/application/views/RosterListView.cpp +++ b/application/views/RosterListView.cpp @@ -215,6 +215,22 @@ RosterListView::Draw(BRect updateRect) } +bool +RosterListView::AddRosterItem(RosterItem* item) +{ + if (HasItem(item) == false) + return AddItem(item); + return false; +} + + +RosterItem* +RosterListView::RosterItemAt(int32 index) +{ + return dynamic_cast(ItemAt(index)); +} + + void RosterListView::Sort() { diff --git a/application/views/RosterListView.h b/application/views/RosterListView.h index 65c5ad2..47cbf17 100644 --- a/application/views/RosterListView.h +++ b/application/views/RosterListView.h @@ -22,6 +22,10 @@ public: virtual void MouseDown(BPoint where); virtual void Draw(BRect updateRect); virtual void AttachedToWindow(); + + bool AddRosterItem(RosterItem* item); + RosterItem* RosterItemAt(int32 index); + void Sort(); private: diff --git a/application/views/RosterView.cpp b/application/views/RosterView.cpp new file mode 100644 index 0000000..af8b0ad --- /dev/null +++ b/application/views/RosterView.cpp @@ -0,0 +1,243 @@ +/* + * Copyright 2009-2011, Andrea Anzani. All rights reserved. + * Copyright 2009-2011, Pier Luigi Fiorini. All rights reserved. + * Copyright 2021, Jaidyn Levesque. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Andrea Anzani, andrea.anzani@gmail.com + * Pier Luigi Fiorini, pierluigi.fiorini@gmail.com + * Jaidyn Levesque, jadedctrl@teknik.io + */ + +#include "RosterView.h" + +#include +#include +#include + +#include "CayaMessages.h" +#include "CayaPreferences.h" +#include "CayaProtocolMessages.h" +#include "RosterItem.h" +#include "RosterListView.h" + + +const uint32 kSearchContact = 'RWSC'; + + +RosterView::RosterView(const char* title, Server* server, bigtime_t account) + : + BGroupView(title, B_VERTICAL, B_USE_DEFAULT_SPACING), + fAccount(-1), + fServer(server) +{ + fSearchBox = new BTextControl("searchBox", "", "", + new BMessage(kSearchContact)); + fSearchBox->SetModificationMessage(new BMessage(kSearchContact)); + + + fListView = new RosterListView("buddyView"); + BScrollView* scrollView = new BScrollView("scrollview", fListView, + B_WILL_DRAW, false, true); + + BLayoutBuilder::Group<>(this, B_VERTICAL, 0.0f) + .AddGroup(B_VERTICAL) + .SetInsets(5, 5, 5, 10) + .Add(fSearchBox) + .Add(scrollView) + .End() + .End(); + + SetAccount(account); +} + + +void +RosterView::MessageReceived(BMessage* message) +{ + switch (message->what) { + case kSearchContact: + { + RosterMap map = _RosterMap(); + for (uint32 i = 0; i < map.CountItems(); i++) { + Contact* linker = map.ValueAt(i); + RosterItem* item = linker->GetRosterItem(); + + // If the search filter has been deleted show all the items, + // otherwise remove the item in order to show only items + // that matches the search criteria + if (strcmp(fSearchBox->Text(), "") == 0) + fListView->AddRosterItem(item); + else if (linker->GetName().IFindFirst(fSearchBox->Text()) == B_ERROR) + fListView->RemoveItem(item); + else + fListView->AddRosterItem(item); + UpdateListItem(item); + } + break; + } + case IM_MESSAGE: + ImMessage(message); + break; + + default: + BGroupView::MessageReceived(message); + } +} + + +void +RosterView::ImMessage(BMessage* msg) +{ + int32 im_what = msg->FindInt32("im_what"); + switch (im_what) { + case IM_STATUS_SET: + { + int32 status; + int64 instance; + BString user_id = msg->FindString("user_id"); + if (msg->FindInt32("status", &status) != B_OK + || msg->FindInt64("instance", &instance) != B_OK + || user_id.IsEmpty() == true) + return; + + Contact* contact = fServer->ContactById(user_id, instance); + if (contact == NULL) + return; + + RosterItem* rosterItem = contact->GetRosterItem(); + + if (rosterItem) { + UpdateListItem(rosterItem); + + // Add or remove item + switch (status) { + /*case CAYA_OFFLINE: + // By default offline contacts are hidden + if (!CayaPreferences::Item()->HideOffline) + break; + if (HasItem(rosterItem)) + RemoveItem(rosterItem); + return;*/ + default: + // Add item because it has a non-offline status + fListView->AddRosterItem(rosterItem); + break; + } + + UpdateListItem(rosterItem); + + // Sort list view again + fListView->Sort(); + + // Check if the user want the notification + if (!CayaPreferences::Item()->NotifyContactStatus) + break; + + switch (status) { + case CAYA_ONLINE: + case CAYA_OFFLINE: + // Notify when contact is online or offline + if (status == CAYA_ONLINE) { + BString message; + message << rosterItem->GetContact()->GetName(); + + if (status == CAYA_ONLINE) + message << " is available!"; + else + message << " is offline!"; + + BNotification notification(B_INFORMATION_NOTIFICATION); + notification.SetGroup(BString("Caya")); + notification.SetTitle(BString("Presence")); + notification.SetIcon(rosterItem->Bitmap()); + notification.SetContent(message); + notification.Send(); + } + break; + default: + break; + } + } + break; + } + case IM_AVATAR_SET: + case IM_CONTACT_INFO: + case IM_EXTENDED_CONTACT_INFO: + { + int32 status = -1; + int64 instance; + BString user_id = msg->FindString("user_id"); + if (msg->FindInt32("status", &status) != B_OK + || msg->FindInt64("instance", &instance) != B_OK + || user_id.IsEmpty() == true) + return; + + Contact* contact = fServer->ContactById(user_id, instance); + if (contact == NULL) + return; + + RosterItem* rosterItem = contact->GetRosterItem(); + if (rosterItem) + UpdateListItem(rosterItem); + break; + } + } +} + + +void +RosterView::AttachedToWindow() +{ + fSearchBox->SetTarget(this); + fSearchBox->MakeFocus(true); +} + + +void +RosterView::SetInvocationMessage(BMessage* msg) +{ + fListView->SetInvocationMessage(msg); +} + + +void +RosterView::SetAccount(bigtime_t instance_id) +{ + fAccount = instance_id; + RosterMap contacts = _RosterMap(); + + fListView->MakeEmpty(); + for (int i = 0; i < contacts.CountItems(); i++) + fListView->AddRosterItem(contacts.ValueAt(i)->GetRosterItem()); +} + + +void +RosterView::UpdateListItem(RosterItem* item) +{ + if (fListView->HasItem(item)) + fListView->InvalidateItem(fListView->IndexOf(item)); +} + + +RosterListView* +RosterView::ListView() +{ + return fListView; +} + + +RosterMap +RosterView::_RosterMap() +{ + RosterMap contacts; + if (fAccount < 0) + contacts = fServer->Contacts(); + else { + ProtocolLooper* looper = fServer->GetProtocolLooper(fAccount); + contacts = looper->Contacts(); + } + return contacts; +} diff --git a/application/views/RosterView.h b/application/views/RosterView.h new file mode 100644 index 0000000..1f0503d --- /dev/null +++ b/application/views/RosterView.h @@ -0,0 +1,50 @@ +/* + * Copyright 2009-2011, Andrea Anzani. All rights reserved. + * Copyright 2009-2011, Pier Luigi Fiorini. All rights reserved. + * Copyright 2021, Jaidyn Levesque. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Andrea Anzani, andrea.anzani@gmail.com + * Pier Luigi Fiorini, pierluigi.fiorini@gmail.com + * Jaidyn Levesque, jadedctrl@teknik.io + */ +#ifndef _ROSTER_VIEW_H +#define _ROSTER_VIEW_H + +#include + +#include "Server.h" + +class BTextControl; +class RosterItem; +class RosterListView; +class Server; + + +class RosterView : public BGroupView { +public: + RosterView(const char* title, Server* server, bigtime_t account = -1); + + void MessageReceived(BMessage* message); + void ImMessage(BMessage* msg); + + void AttachedToWindow(); + void SetInvocationMessage(BMessage* msg); + + void SetAccount(bigtime_t instance_id); + + void UpdateListItem(RosterItem* item); + + RosterListView* ListView(); + +private: + RosterMap _RosterMap(); + + Server* fServer; + RosterListView* fListView; + BTextControl* fSearchBox; + bigtime_t fAccount; +}; + +#endif // _ROSTER_VIEW_H diff --git a/application/views/SearchBarTextControl.cpp b/application/views/SearchBarTextControl.cpp deleted file mode 100644 index 77432fe..0000000 --- a/application/views/SearchBarTextControl.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2012, Dario Casalinuovo. All rights reserved. - * Distributed under the terms of the MIT License. - * - * Authors: - * Dario Casalinuovo, dario.casalinuovo@gmail.com - */ - -#include "CayaConstants.h" -#include "SearchBarTextControl.h" - -#include -#include -#include - -#include - - -SearchBarTextControl::SearchBarTextControl(BMessage* message) - : - BTextControl("searchBox", NULL, NULL, message) -{ - SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); - rgb_color color = tint_color(ViewColor(), B_DARKEN_3_TINT); - TextView()->SetFontAndColor(NULL, B_FONT_ALL, &color); - TextView()->MakeSelectable(false); - SetModificationMessage(new BMessage(*message)); -} - - -void -SearchBarTextControl::KeyDown(const char* bytes, int32 numBytes) -{ -} diff --git a/application/views/SearchBarTextControl.h b/application/views/SearchBarTextControl.h deleted file mode 100644 index b6889c3..0000000 --- a/application/views/SearchBarTextControl.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2012, Dario Casalinuovo. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _SEARCHBAR_TEXT_CONTROL_H -#define _SEARCHBAR_TEXT_CONTROL_H - -#include - -class SearchBarTextControl : public BTextControl { -public: - SearchBarTextControl(BMessage* message); - - virtual void KeyDown(const char* bytes, int32 numBytes); -}; - -#endif // _SEARCHBAR_TEXT_CONTROL_H diff --git a/application/windows/RosterWindow.cpp b/application/windows/RosterWindow.cpp index feb21a5..a1adae4 100644 --- a/application/windows/RosterWindow.cpp +++ b/application/windows/RosterWindow.cpp @@ -1,11 +1,13 @@ /* * Copyright 2009-2011, Andrea Anzani. All rights reserved. * Copyright 2009-2011, Pier Luigi Fiorini. All rights reserved. + * Copyright 2021, Jaidyn Levesque. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: * Andrea Anzani, andrea.anzani@gmail.com * Pier Luigi Fiorini, pierluigi.fiorini@gmail.com + * Jaidyn Levesque, jadedctrl@teknik.io */ @@ -20,11 +22,10 @@ #include "CayaProtocolMessages.h" #include "RosterItem.h" #include "RosterListView.h" -#include "SearchBarTextControl.h" +#include "RosterView.h" #include "Server.h" -const uint32 kSearchContact = 'RWSC'; const uint32 kSendMessage = 'RWSM'; @@ -36,24 +37,16 @@ RosterWindow::RosterWindow(const char* title, BMessage* selectMsg, fMessage(selectMsg), fServer(server) { - SearchBarTextControl* searchBox = - new SearchBarTextControl(new BMessage(kSearchContact)); - - fListView = new RosterListView("buddyView"); - fListView->SetInvocationMessage(new BMessage(kSendMessage)); - BScrollView* scrollView = new BScrollView("scrollview", fListView, - B_WILL_DRAW, false, true); + fRosterView = new RosterView("buddyView", server); + fRosterView->SetInvocationMessage(new BMessage(kSendMessage)); BLayoutBuilder::Group<>(this, B_VERTICAL, 0.0f) .AddGroup(B_VERTICAL) .SetInsets(5, 5, 5, 10) - .Add(searchBox) - .Add(scrollView) + .Add(fRosterView) .End() .End(); - _PopulateRosterList(); - CenterOnScreen(); } @@ -62,40 +55,10 @@ void RosterWindow::MessageReceived(BMessage* message) { switch (message->what) { - case kSearchContact: - { - void* control = NULL; - if (message->FindPointer("source", &control) != B_OK) - return; - - SearchBarTextControl* searchBox - = static_cast(control); - if (searchBox == NULL) - return; - - RosterMap map = fServer->Contacts(); - for (uint32 i = 0; i < map.CountItems(); i++) { - Contact* linker = map.ValueAt(i); - RosterItem* item = linker->GetRosterItem(); - - // If the search filter has been deleted show all the items, - // otherwise remove the item in order to show only items - // that matches the search criteria - if (strcmp(searchBox->Text(), "") == 0) - AddItem(item); - else if (linker->GetName().IFindFirst(searchBox->Text()) == B_ERROR) - RemoveItem(item); - else - AddItem(item); - UpdateListItem(item); - } - break; - } - case kSendMessage: { int index = message->FindInt32("index"); - RosterItem* ritem = ItemAt(index); + RosterItem* ritem = fRosterView->ListView()->RosterItemAt(index); if (ritem == NULL) return; @@ -108,180 +71,17 @@ RosterWindow::MessageReceived(BMessage* message) break; } - case IM_MESSAGE: - ImMessage(message); + fRosterView->MessageReceived(message); break; - default: BWindow::MessageReceived(message); } } -void -RosterWindow::ImMessage(BMessage* msg) -{ - int32 im_what = msg->FindInt32("im_what"); - switch (im_what) { - case IM_STATUS_SET: - { - int32 status; - int64 instance; - BString user_id = msg->FindString("user_id"); - if (msg->FindInt32("status", &status) != B_OK - || msg->FindInt64("instance", &instance) != B_OK - || user_id.IsEmpty() == true) - return; - - Contact* contact = fServer->ContactById(user_id, instance); - if (contact == NULL) - return; - - RosterItem* rosterItem = contact->GetRosterItem(); - - if (rosterItem) { - UpdateListItem(rosterItem); - - // Add or remove item - switch (status) { - /*case CAYA_OFFLINE: - // By default offline contacts are hidden - if (!CayaPreferences::Item()->HideOffline) - break; - if (HasItem(rosterItem)) - RemoveItem(rosterItem); - return;*/ - default: - // Add item because it has a non-offline status - if (!HasItem(rosterItem)) - AddItem(rosterItem); - break; - } - - UpdateListItem(rosterItem); - - // Sort list view again - fListView->Sort(); - - // Check if the user want the notification - if (!CayaPreferences::Item()->NotifyContactStatus) - break; - - switch (status) { - case CAYA_ONLINE: - case CAYA_OFFLINE: - // Notify when contact is online or offline - if (status == CAYA_ONLINE) { - BString message; - message << rosterItem->GetContact()->GetName(); - - if (status == CAYA_ONLINE) - message << " is available!"; - else - message << " is offline!"; - - BNotification notification(B_INFORMATION_NOTIFICATION); - notification.SetGroup(BString("Caya")); - notification.SetTitle(BString("Presence")); - notification.SetIcon(rosterItem->Bitmap()); - notification.SetContent(message); - notification.Send(); - } - break; - default: - break; - } - } - break; - } - case IM_AVATAR_SET: - case IM_CONTACT_INFO: - case IM_EXTENDED_CONTACT_INFO: - { - int32 status = -1; - int64 instance; - BString user_id = msg->FindString("user_id"); - if (msg->FindInt32("status", &status) != B_OK - || msg->FindInt64("instance", &instance) != B_OK - || user_id.IsEmpty() == true) - return; - - Contact* contact = fServer->ContactById(user_id, instance); - if (contact == NULL) - return; - - RosterItem* rosterItem = contact->GetRosterItem(); - if (rosterItem) - UpdateListItem(rosterItem); - break; - } - } -} - - -int32 -RosterWindow::CountItems() const -{ - return fListView->CountItems(); -} - - -RosterItem* -RosterWindow::ItemAt(int index) -{ - return dynamic_cast(fListView->ItemAt(index)); -} - - -void -RosterWindow::AddItem(RosterItem* item) -{ - // Don't add offline items and avoid duplicates - if ((item->Status() == CAYA_OFFLINE) - && CayaPreferences::Item()->HideOffline) - return; - - if (HasItem(item)) - return; - - // Add item and sort - fListView->AddItem(item); - fListView->Sort(); -} - - -bool -RosterWindow::HasItem(RosterItem* item) -{ - return fListView->HasItem(item); -} - - -void -RosterWindow::RemoveItem(RosterItem* item) -{ - // Remove item and sort - fListView->RemoveItem(item); - fListView->Sort(); -} - - void RosterWindow::UpdateListItem(RosterItem* item) { - if (fListView->HasItem(item)) - fListView->InvalidateItem(fListView->IndexOf(item)); + fRosterView->UpdateListItem(item); } - - -void -RosterWindow::_PopulateRosterList() -{ - RosterMap contacts = fServer->Contacts(); - - for (int i = 0; i < contacts.CountItems(); i++) - AddItem(contacts.ValueAt(i)->GetRosterItem()); -} - - diff --git a/application/windows/RosterWindow.h b/application/windows/RosterWindow.h index 3380ae2..40b30fd 100644 --- a/application/windows/RosterWindow.h +++ b/application/windows/RosterWindow.h @@ -1,11 +1,13 @@ /* * Copyright 2009-2011, Andrea Anzani. All rights reserved. * Copyright 2009-2011, Pier Luigi Fiorini. All rights reserved. + * Copyright 2021, Jaidyn Levesque. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: * Andrea Anzani, andrea.anzani@gmail.com * Pier Luigi Fiorini, pierluigi.fiorini@gmail.com + * Jaidyn Levesque, jadedctrl@teknik.io */ #ifndef ROSTERWINDOW_H #define ROSTERWINDOW_H @@ -13,7 +15,7 @@ #include class RosterItem; -class RosterListView; +class RosterView; class Server; @@ -25,25 +27,14 @@ public: Server* server); void MessageReceived(BMessage* message); - void ImMessage(BMessage* msg); - - int32 CountItems() const; - RosterItem* ItemAt(int index); - void AddItem(RosterItem*); - bool HasItem(RosterItem*); - void RemoveItem(RosterItem*); void UpdateListItem(RosterItem* item); private: - void _PopulateRosterList(); - Server* fServer; - RosterListView* fListView; + RosterView* fRosterView; BMessenger* fTarget; BMessage* fMessage; }; - #endif // ROSTERWINDOW_H -