From 552e937e514aa98c607c59160b44891e4e066f6a Mon Sep 17 00:00:00 2001 From: Jaidyn Ann Date: Fri, 11 Jun 2021 17:24:04 -0500 Subject: [PATCH] Group rooms in roomlist by account The ConversationListView is now an BOutlineListView, and rooms are added as subitems to the item of their associated account. Right now, account items aren't selectable or useful. --- application/Makefile | 1 + application/ProtocolLooper.cpp | 15 ++- application/ProtocolLooper.h | 8 ++ application/views/ConversationAccountItem.cpp | 23 +++++ application/views/ConversationAccountItem.h | 25 +++++ application/views/ConversationItem.h | 2 +- application/views/ConversationListView.cpp | 97 ++++++++++++++++++- application/views/ConversationListView.h | 13 ++- application/windows/MainWindow.cpp | 53 ++++------ application/windows/MainWindow.h | 4 +- 10 files changed, 198 insertions(+), 43 deletions(-) create mode 100644 application/views/ConversationAccountItem.cpp create mode 100644 application/views/ConversationAccountItem.h diff --git a/application/Makefile b/application/Makefile index 9ec10ab..ead102a 100644 --- a/application/Makefile +++ b/application/Makefile @@ -57,6 +57,7 @@ SRCS = \ application/preferences/PreferencesBehavior.cpp \ application/preferences/PreferencesReplicant.cpp \ application/views/CayaRenderView.cpp \ + application/views/ConversationAccountItem.cpp \ application/views/ConversationItem.cpp \ application/views/ConversationListView.cpp \ application/views/ConversationView.cpp \ diff --git a/application/ProtocolLooper.cpp b/application/ProtocolLooper.cpp index 0391b82..4ef1da5 100644 --- a/application/ProtocolLooper.cpp +++ b/application/ProtocolLooper.cpp @@ -1,4 +1,5 @@ /* + * Copyright 2021, Jaidyn Levesque. All rights reserved. * Copyright 2009-2011, Andrea Anzani. All rights reserved. * Copyright 2009-2011, Pier Luigi Fiorini. All rights reserved. * Distributed under the terms of the MIT License. @@ -14,13 +15,15 @@ #include "Account.h" #include "Conversation.h" +#include "ConversationAccountItem.h" ProtocolLooper::ProtocolLooper(CayaProtocol* protocol, int64 instance) : BLooper(), fProtocol(protocol), - fInstance(instance) + fInstance(instance), + fListItem(NULL) { Account* account = reinterpret_cast( protocol->MessengerInterface()); @@ -153,3 +156,13 @@ ProtocolLooper::GetInstance() } +ConversationAccountItem* +ProtocolLooper::GetListItem() +{ + if (fListItem == NULL) + fListItem = new ConversationAccountItem(fProtocol->GetName(), + fInstance); + return fListItem; +} + + diff --git a/application/ProtocolLooper.h b/application/ProtocolLooper.h index 795effc..e1aa070 100644 --- a/application/ProtocolLooper.h +++ b/application/ProtocolLooper.h @@ -1,4 +1,5 @@ /* + * Copyright 2021, Jaidyn Levesque. All rights reserved. * Copyright 2009-2011, Andrea Anzani. All rights reserved. * Copyright 2009-2011, Pier Luigi Fiorini. All rights reserved. * Distributed under the terms of the MIT License. @@ -15,6 +16,7 @@ class Contact; class Conversation; +class ConversationAccountItem; class User; @@ -49,6 +51,9 @@ public: int64 GetInstance(); + ConversationAccountItem* + GetListItem(); + private: CayaProtocol* fProtocol; int64 fInstance; @@ -58,6 +63,9 @@ private: ChatMap fChatMap; RosterMap fRosterMap; UserMap fUserMap; + + ConversationAccountItem* + fListItem; }; #endif // _PROTOCOL_LOOPER_H diff --git a/application/views/ConversationAccountItem.cpp b/application/views/ConversationAccountItem.cpp new file mode 100644 index 0000000..1edc0fb --- /dev/null +++ b/application/views/ConversationAccountItem.cpp @@ -0,0 +1,23 @@ +/* + * Copyright 2021, Jaidyn Levesque + * All rights reserved. Distributed under the terms of the MIT license. + */ + +#include "ConversationAccountItem.h" + + +ConversationAccountItem::ConversationAccountItem(const char* name, int64 instance) + : + BStringItem(name), + fInstance(instance) +{ +} + + +int64 +ConversationAccountItem::GetInstance() +{ + return fInstance; +} + + diff --git a/application/views/ConversationAccountItem.h b/application/views/ConversationAccountItem.h new file mode 100644 index 0000000..183101b --- /dev/null +++ b/application/views/ConversationAccountItem.h @@ -0,0 +1,25 @@ +/* + * Copyright 2021, Jaidyn Levesque + * All rights reserved. Distributed under the terms of the MIT license. + */ +#ifndef CONVERSATIONACCITEM_H +#define CONVERSATIONACCITEM_H + +#include + +class Conversation; + + +class ConversationAccountItem : public BStringItem { +public: + ConversationAccountItem(const char* name, int64 instance); + + int64 GetInstance(); + +private: + int64 fInstance; +}; + + +#endif // CONVERSATIONACCITEM_H + diff --git a/application/views/ConversationItem.h b/application/views/ConversationItem.h index b12d288..d6cbe0a 100644 --- a/application/views/ConversationItem.h +++ b/application/views/ConversationItem.h @@ -5,7 +5,7 @@ #ifndef CONVERSATIONITEM_H #define CONVERSATIONITEM_H -#include +#include #include "Observer.h" diff --git a/application/views/ConversationListView.cpp b/application/views/ConversationListView.cpp index fc222a8..f3e751e 100644 --- a/application/views/ConversationListView.cpp +++ b/application/views/ConversationListView.cpp @@ -12,6 +12,7 @@ #include "CayaMessages.h" #include "CayaProtocolMessages.h" #include "Conversation.h" +#include "ConversationAccountItem.h" #include "ConversationItem.h" #include "ProtocolLooper.h" @@ -21,7 +22,7 @@ const uint32 kLeaveSelectedChat = 'CVcs'; ConversationListView::ConversationListView(const char* name) - : BListView(name) + : BOutlineListView(name) { } @@ -35,7 +36,8 @@ ConversationListView::MessageReceived(BMessage* msg) ConversationItem* item; int32 selIndex = CurrentSelection(); - if ((item = (ConversationItem*)ItemAt(selIndex)) != NULL) + if (ItemAt(selIndex)->OutlineLevel() == 1 + && (item = (ConversationItem*)ItemAt(selIndex)) != NULL) item->GetConversation()->ShowView(false, true); break; } @@ -66,10 +68,18 @@ ConversationListView::MouseDown(BPoint where) { int32 selection = CurrentSelection(); - BListView::MouseDown(where); + BOutlineListView::MouseDown(where); - // Don't allow deselcting a room - if (CurrentSelection() < 0 && selection >= 0) + int32 newSel = CurrentSelection(); + + // Don't allow selecting an AccountItem + if (ItemAt(newSel)->OutlineLevel() == 0) { + Select(selection); + return; + } + + // Don't allow deselecting a room + if (newSel < 0 && selection >= 0) Select(selection); uint32 buttons = 0; @@ -92,6 +102,68 @@ ConversationListView::SelectionChanged() } +void +ConversationListView::AddConversation(Conversation* chat) +{ + ConversationAccountItem* superItem = _EnsureAccountItem(chat); + ConversationItem* item = chat->GetListItem(); + if (superItem == NULL || item == NULL) + return; + + AddUnder(item, superItem); +} + + +void +ConversationListView::RemoveConversation(Conversation* chat) +{ + RemoveItem(chat->GetListItem()); +} + + +int32 +ConversationListView::CountConversations() +{ + int32 count = 0; + for (int32 i = 0; i < CountItems(); i++) + if (ItemAt(i)->OutlineLevel() == 1) + count++; + return count; +} + + +int32 +ConversationListView::ConversationIndexOf(Conversation* chat) +{ + ConversationItem* item = chat->GetListItem(); + int32 index = IndexOf(item); + int32 chatIndex = index; + + if (item == NULL || index < 0) + return -1; + + for (int i = 0; i < index; i++) + if (ItemAt(i)->OutlineLevel() == 0) // If AccountItem + chatIndex--; + return chatIndex; +} + + +void +ConversationListView::SelectConversation(int32 index) +{ + for (int32 i = 0, cindex = -1; i < CountItems(); i++) { + if (ItemAt(i)->OutlineLevel() == 1) // If ConversationItem + cindex++; + + if (cindex == index) { + Select(i); + break; + } + } +} + + BPopUpMenu* ConversationListView::_ConversationPopUp() { @@ -118,3 +190,18 @@ ConversationListView::_BlankPopUp() } +ConversationAccountItem* +ConversationListView::_EnsureAccountItem(Conversation* chat) +{ + ProtocolLooper* looper; + if (chat == NULL || (looper = chat->GetProtocolLooper()) == NULL) + return NULL; + + ConversationAccountItem* item = looper->GetListItem(); + if (HasItem(item) == false) + AddItem(item); + + return item; +} + + diff --git a/application/views/ConversationListView.h b/application/views/ConversationListView.h index 6d56a9d..71fe2ff 100644 --- a/application/views/ConversationListView.h +++ b/application/views/ConversationListView.h @@ -8,9 +8,11 @@ #include class BPopUpMenu; +class Conversation; +class ConversationAccountItem; -class ConversationListView : public BListView { +class ConversationListView : public BOutlineListView { public: ConversationListView(const char* name); @@ -18,9 +20,18 @@ public: void SelectionChanged(); void MouseDown(BPoint where); + void AddConversation(Conversation* chat); + void RemoveConversation(Conversation* chat); + + int32 CountConversations(); + int32 ConversationIndexOf(Conversation* chat); + void SelectConversation(int32 index); + private: BPopUpMenu* _ConversationPopUp(); BPopUpMenu* _BlankPopUp(); + + ConversationAccountItem* _EnsureAccountItem(Conversation* chat); }; diff --git a/application/windows/MainWindow.cpp b/application/windows/MainWindow.cpp index cfe2813..1e0333a 100644 --- a/application/windows/MainWindow.cpp +++ b/application/windows/MainWindow.cpp @@ -1,4 +1,5 @@ /* + * Copyright 2021, Jaidyn Levesque. All rights reserved. * Copyright 2009-2011, Andrea Anzani. All rights reserved. * Copyright 2009-2011, Pier Luigi Fiorini. All rights reserved. * Distributed under the terms of the MIT License. @@ -87,9 +88,8 @@ MainWindow::QuitRequested() ReplicantStatusView::RemoveReplicant(); be_app->PostMessage(B_QUIT_REQUESTED); return true; - } else { + } else return false; - } } @@ -146,9 +146,9 @@ MainWindow::MessageReceived(BMessage* message) if (fConversation == NULL) break; - int32 index = fListView->IndexOf(fConversation->GetListItem()); + int32 index = fListView->ConversationIndexOf(fConversation); if (index > 0) - fListView->Select(index - 1); + fListView->SelectConversation(index - 1); break; } @@ -157,10 +157,10 @@ MainWindow::MessageReceived(BMessage* message) if (fConversation == NULL) break; - int32 index = fListView->IndexOf(fConversation->GetListItem()); - int32 count = fListView->CountItems(); + int32 index = fListView->ConversationIndexOf(fConversation); + int32 count = fListView->CountConversations(); if (index < (count - 1)) - fListView->Select(index + 1); + fListView->SelectConversation(index + 1); break; } @@ -249,7 +249,7 @@ MainWindow::ImMessage(BMessage* msg) if (item == NULL) break; - _RemoveListItem(item); + _RemoveConversation(item->GetConversation()); item->GetConversation()->GetView()->MessageReceived(msg); break; } @@ -425,18 +425,16 @@ MainWindow::_EnsureConversationItem(BMessage* msg) BString chat_id = msg->FindString("chat_id"); Conversation* chat = fServer->ConversationById(chat_id, msg->FindInt64("instance")); + ConversationItem* item = chat->GetListItem(); if (chat != NULL) { - ConversationItem* item = chat->GetListItem(); - if (fListView->HasItem(item)) { - _UpdateListItem(item); - } - else if (item != NULL) { - fListView->AddItem(item); - } + if (fListView->HasItem(item)) + fListView->InvalidateItem(fListView->IndexOf(item)); + else if (item != NULL) + fListView->AddConversation(chat); - if (fListView->CountItems() == 1) - fListView->Select(0); + if (fListView->CountConversations() == 1) + fListView->SelectConversation(0); return item; } @@ -445,35 +443,24 @@ MainWindow::_EnsureConversationItem(BMessage* msg) void -MainWindow::_UpdateListItem(ConversationItem* item) +MainWindow::_RemoveConversation(Conversation* chat) { - if (fListView->HasItem(item) == true) - fListView->InvalidateItem(fListView->IndexOf(item)); - else - fListView->AddItem(item); -} - - -void -MainWindow::_RemoveListItem(ConversationItem* item) -{ - int32 index = fListView->IndexOf(item); + int32 index = fListView->ConversationIndexOf(chat); if (index > 0) index--; - fListView->RemoveItem(item); - Conversation* chat = item->GetConversation(); + fListView->RemoveConversation(chat); ProtocolLooper* looper = chat->GetProtocolLooper(); if (chat != NULL && looper != NULL) looper->RemoveConversation(chat); - if (fListView->CountItems() == 0) { + if (fListView->CountConversations() == 0) { fChatView = new ConversationView(); SetConversation(NULL); } else - fListView->Select(index); + fListView->SelectConversation(index); } diff --git a/application/windows/MainWindow.h b/application/windows/MainWindow.h index 6ab7ea4..31c2493 100644 --- a/application/windows/MainWindow.h +++ b/application/windows/MainWindow.h @@ -1,4 +1,5 @@ /* + * Copyright 2021, Jaidyn Levesque. All rights reserved. * Copyright 2009-2011, Andrea Anzani. All rights reserved. * Copyright 2009-2011, Pier Luigi Fiorini. All rights reserved. * Distributed under the terms of the MIT License. @@ -50,8 +51,7 @@ private: ConversationItem* _EnsureConversationItem(BMessage* msg); - void _UpdateListItem(ConversationItem* item); - void _RemoveListItem(ConversationItem* item); + void _RemoveConversation(Conversation* chat); Server* fServer;