From dcc5e443d359a417d45fe8f3e6bbbb43b42623f5 Mon Sep 17 00:00:00 2001 From: Jaidyn Ann Date: Fri, 11 Jun 2021 20:33:28 -0500 Subject: [PATCH] Support temporary disabling of accounts Accounts can now be temporarily disabled (in a Pidgin-like style) through Preferences->Accounts. Work is still required to allow enabling/re-enabling of accounts on-the-fly, and for keeping an account's disabled state persistent. --- application/CayaMessages.h | 3 + application/Conversation.cpp | 20 +++-- application/Conversation.h | 1 + application/ProtocolLooper.cpp | 7 ++ application/ProtocolLooper.h | 1 + application/Server.cpp | 37 +++++++--- application/Server.h | 1 - application/TheApp.cpp | 3 +- .../preferences/PreferencesAccounts.cpp | 73 +++++++++++++++++-- application/preferences/PreferencesAccounts.h | 6 +- application/views/ConversationListView.cpp | 7 +- application/windows/MainWindow.cpp | 43 +++++------ application/windows/MainWindow.h | 5 +- protocols/xmpp/JabberHandler.cpp | 8 +- 14 files changed, 156 insertions(+), 59 deletions(-) diff --git a/application/CayaMessages.h b/application/CayaMessages.h index 3848467..8b6d2e3 100644 --- a/application/CayaMessages.h +++ b/application/CayaMessages.h @@ -44,4 +44,7 @@ const uint32 CAYA_MOVE_UP = 'CYmu'; //! Select the downward conversation const uint32 CAYA_MOVE_DOWN = 'CYmd'; +//! Select the downward conversation +const uint32 CAYA_DISABLE_ACCOUNT = 'CYda'; + #endif // _CAYA_MESSAGES_H diff --git a/application/Conversation.cpp b/application/Conversation.cpp index 1c4da80..f259339 100644 --- a/application/Conversation.cpp +++ b/application/Conversation.cpp @@ -38,6 +38,19 @@ Conversation::Conversation(BString id, BMessenger msgn) } +Conversation::~Conversation() +{ + ((TheApp*)be_app)->GetMainWindow()->RemoveConversation(this); + + ProtocolLooper* looper = GetProtocolLooper(); + if (looper != NULL) + looper->RemoveConversation(this); + + delete fChatView; + delete fConversationItem; +} + + BString Conversation::GetId() const { @@ -332,12 +345,7 @@ Conversation::_LogChatMessage(BMessage* msg) uname = "You"; BString logLine("["); - logLine << date; - logLine << "] "; - logLine << uname; - logLine << ": "; - logLine << body; - logLine << "\n"; + logLine << date << "] <" << uname << "> " << body << "\n"; logFile.Write(logLine.String(), logLine.Length()); } diff --git a/application/Conversation.h b/application/Conversation.h index f6d1fdc..17a81a1 100644 --- a/application/Conversation.h +++ b/application/Conversation.h @@ -30,6 +30,7 @@ typedef KeyMap RoleMap; class Conversation : public Notifier, public Observer { public: Conversation(BString id, BMessenger msgn); + ~Conversation(); BString GetId() const; diff --git a/application/ProtocolLooper.cpp b/application/ProtocolLooper.cpp index 4ef1da5..bd19c0f 100644 --- a/application/ProtocolLooper.cpp +++ b/application/ProtocolLooper.cpp @@ -36,6 +36,13 @@ ProtocolLooper::ProtocolLooper(CayaProtocol* protocol, int64 instance) } +ProtocolLooper::~ProtocolLooper() +{ + fProtocol->Shutdown(); + delete fProtocol; +} + + void ProtocolLooper::MessageReceived(BMessage* msg) { diff --git a/application/ProtocolLooper.h b/application/ProtocolLooper.h index e1aa070..c7f9020 100644 --- a/application/ProtocolLooper.h +++ b/application/ProtocolLooper.h @@ -28,6 +28,7 @@ typedef KeyMap UserMap; class ProtocolLooper : public BLooper { public: ProtocolLooper(CayaProtocol* protocol, int64 instance); + ~ProtocolLooper(); void MessageReceived(BMessage* msg); diff --git a/application/Server.cpp b/application/Server.cpp index 2a4390a..3792fdd 100644 --- a/application/Server.cpp +++ b/application/Server.cpp @@ -109,6 +109,18 @@ Server::Filter(BMessage* message, BHandler **target) break; } + case CAYA_DISABLE_ACCOUNT: + { + int64 instance = 0; + if (message->FindInt64("instance", &instance) != B_OK) { + result = B_SKIP_MESSAGE; + break; + } + + RemoveProtocolLooper(instance); + break; + } + default: // Dispatch not handled messages to main window break; @@ -475,6 +487,22 @@ Server::AddProtocolLooper(bigtime_t instanceId, CayaProtocol* cayap) void Server::RemoveProtocolLooper(bigtime_t instanceId) { + ProtocolLooper* looper = GetProtocolLooper(instanceId); + if (looper == NULL) + return; + + ChatMap chats = looper->Conversations(); + for (int i = 0; i < chats.CountItems(); i++) + delete chats.ValueAt(i); + + UserMap users = looper->Users(); + for (int i = 0; i < users.CountItems(); i++) + delete users.ValueAt(i); + + fLoopers.RemoveItemFor(instanceId); + fAccounts.RemoveItemFor(looper->Protocol()->GetName()); + looper->Lock(); + looper->Quit(); } @@ -642,15 +670,6 @@ Server::AddConversation(Conversation* chat, int64 instance) } -void -Server::RemoveConversation(Conversation* chat, int64 instance) -{ - ProtocolLooper* looper = fLoopers.ValueFor(instance); - if (looper != NULL) - looper->RemoveConversation(chat); -} - - ProtocolLooper* Server::_LooperFromMessage(BMessage* message) { diff --git a/application/Server.h b/application/Server.h index f39ef36..ef0a772 100644 --- a/application/Server.h +++ b/application/Server.h @@ -57,7 +57,6 @@ public: ChatMap Conversations() const; Conversation* ConversationById(BString id, int64 instance); void AddConversation(Conversation* chat, int64 instance); - void RemoveConversation(Conversation* chat, int64 instance); private: ProtocolLooper* _LooperFromMessage(BMessage* message); diff --git a/application/TheApp.cpp b/application/TheApp.cpp index 5bfe15c..b27a3b8 100644 --- a/application/TheApp.cpp +++ b/application/TheApp.cpp @@ -27,6 +27,7 @@ #include "ReplicantStatusView.h" #include "Server.h" + TheApp::TheApp() : BApplication(CAYA_SIGNATURE), @@ -59,7 +60,7 @@ TheApp::ReadyToRun() BString msg("Can't find smileys settings in:\n\n"); msg << currentPath.Path(); BAlert* alert = new BAlert("", msg.String(), "Ouch!"); - alert->Go(); +// alert->Go(); } printf("Loaded Emoticons settings from: %s\n", currentPath.Path()); diff --git a/application/preferences/PreferencesAccounts.cpp b/application/preferences/PreferencesAccounts.cpp index 8201230..2090df9 100644 --- a/application/preferences/PreferencesAccounts.cpp +++ b/application/preferences/PreferencesAccounts.cpp @@ -18,17 +18,21 @@ #include "AccountDialog.h" #include "AccountListItem.h" +#include "CayaMessages.h" #include "CayaProtocol.h" #include "PreferencesAccounts.h" #include "ProtocolManager.h" #include "ProtocolSettings.h" #include "MainWindow.h" +#include "Server.h" #include "TheApp.h" -const uint32 kAddAccount = 'adac'; -const uint32 kEditAccount = 'edac'; -const uint32 kDelAccount = 'dlac'; -const uint32 kSelect = 'selt'; + +const uint32 kAddAccount = 'adac'; +const uint32 kEditAccount = 'edac'; +const uint32 kDelAccount = 'dlac'; +const uint32 kToggleAccount = 'tgac'; +const uint32 kSelect = 'selt'; static int @@ -74,8 +78,10 @@ PreferencesAccounts::PreferencesAccounts() proto->SetMenu(fProtosMenu); fDelButton = new BButton("Del", new BMessage(kDelAccount)); fEditButton = new BButton("Edit" B_UTF8_ELLIPSIS, new BMessage(kEditAccount)); + fToggleButton = new BButton("Enable", new BMessage(kToggleAccount)); fDelButton->SetEnabled(false); fEditButton->SetEnabled(false); + fToggleButton->SetEnabled(false); BLayoutBuilder::Group<>(this, B_VERTICAL) .SetInsets(B_USE_DEFAULT_SPACING) @@ -85,6 +91,7 @@ PreferencesAccounts::PreferencesAccounts() .Add(proto) .Add(fDelButton) .AddGlue() + .Add(fToggleButton) .Add(fEditButton) .End() .End(); @@ -98,6 +105,7 @@ PreferencesAccounts::AttachedToWindow() fProtosMenu->SetTargetForItems(this); fDelButton->SetTarget(this); fEditButton->SetTarget(this); + fToggleButton->SetTarget(this); } @@ -106,14 +114,28 @@ PreferencesAccounts::MessageReceived(BMessage* msg) { switch (msg->what) { case kSelect: { - int32 index; + int32 index; - if (msg->FindInt32("index", &index) == B_OK) { - fDelButton->SetEnabled(index >= 0); - fEditButton->SetEnabled(index >= 0); + if (msg->FindInt32("index", &index) == B_OK) { + fDelButton->SetEnabled(index >= 0); + fEditButton->SetEnabled(index >= 0); + fToggleButton->SetEnabled(index >= 0); + + if (index >= 0) { + AccountListItem* item = (AccountListItem*)fListView->ItemAt(fListView->CurrentSelection()); + + if (_AccountEnabled(item->Account() ) == true) { + fToggleButton->SetLabel("Disable"); + fToggleButton->SetEnabled(true); + } + else { + fToggleButton->SetLabel("Enable"); + fToggleButton->SetEnabled(false); + } } } break; + } case kAddAccount: { void *pointer = NULL; if (msg->FindPointer("settings", &pointer) == B_OK) { @@ -161,6 +183,28 @@ PreferencesAccounts::MessageReceived(BMessage* msg) } break; } + case kToggleAccount: { + int32 current = fListView->CurrentSelection(); + AccountListItem* item; + + if (current < 0 + || (item = (AccountListItem*)fListView->ItemAt(current)) == NULL) + break; + + bool found = false; + AccountInstances accs = ((TheApp*)be_app)->GetMainWindow()->GetServer()->GetAccounts(); + int64 instance = accs.ValueFor(BString(item->Account()), &found); + if (found == false) + return; + + BMessage* remove = new BMessage(CAYA_DISABLE_ACCOUNT); + remove->AddInt64("instance", instance); + ((TheApp*)be_app)->GetMainWindow()->PostMessage(remove); + + fToggleButton->SetLabel("Enable"); + fToggleButton->SetEnabled(false); + break; + } case kAccountAdded: case kAccountRenamed: { void* pointer = NULL; @@ -234,3 +278,16 @@ PreferencesAccounts::_LoadListView(ProtocolSettings* settings) fListView->AddItem(listItem); } } + + +bool +PreferencesAccounts::_AccountEnabled(const char* account) +{ + bool found = false; + AccountInstances accs = ((TheApp*)be_app)->GetMainWindow()->GetServer()->GetAccounts(); + accs.ValueFor(BString(account), &found); + + return found; +} + + diff --git a/application/preferences/PreferencesAccounts.h b/application/preferences/PreferencesAccounts.h index 91ca3a9..e3fe708 100644 --- a/application/preferences/PreferencesAccounts.h +++ b/application/preferences/PreferencesAccounts.h @@ -14,6 +14,7 @@ class BPopUpMenu; class ToolButton; class ProtocolSettings; + class PreferencesAccounts : public BView { public: PreferencesAccounts(); @@ -26,9 +27,12 @@ private: BPopUpMenu* fProtosMenu; BButton* fDelButton; BButton* fEditButton; - + BButton* fToggleButton; void _LoadListView(ProtocolSettings* settings); + bool _AccountEnabled(const char* account); }; + #endif // _PREFERENCES_ACCOUNTS_H + diff --git a/application/views/ConversationListView.cpp b/application/views/ConversationListView.cpp index f3e751e..2fdd5af 100644 --- a/application/views/ConversationListView.cpp +++ b/application/views/ConversationListView.cpp @@ -36,8 +36,9 @@ ConversationListView::MessageReceived(BMessage* msg) ConversationItem* item; int32 selIndex = CurrentSelection(); - if (ItemAt(selIndex)->OutlineLevel() == 1 - && (item = (ConversationItem*)ItemAt(selIndex)) != NULL) + if (selIndex >= 0 + && (item = (ConversationItem*)ItemAt(selIndex)) != NULL + && item->OutlineLevel() == 1) item->GetConversation()->ShowView(false, true); break; } @@ -73,7 +74,7 @@ ConversationListView::MouseDown(BPoint where) int32 newSel = CurrentSelection(); // Don't allow selecting an AccountItem - if (ItemAt(newSel)->OutlineLevel() == 0) { + if (newSel >= 0 && ItemAt(newSel)->OutlineLevel() == 0) { Select(selection); return; } diff --git a/application/windows/MainWindow.cpp b/application/windows/MainWindow.cpp index 1e0333a..7c744c0 100644 --- a/application/windows/MainWindow.cpp +++ b/application/windows/MainWindow.cpp @@ -249,8 +249,7 @@ MainWindow::ImMessage(BMessage* msg) if (item == NULL) break; - _RemoveConversation(item->GetConversation()); - item->GetConversation()->GetView()->MessageReceived(msg); + delete item->GetConversation(); break; } case IM_AVATAR_SET: @@ -336,6 +335,24 @@ MainWindow::SetConversation(Conversation* chat) } +void +MainWindow::RemoveConversation(Conversation* chat) +{ + int32 index = fListView->ConversationIndexOf(chat); + if (index > 0) + index--; + + fListView->RemoveConversation(chat); + + if (fListView->CountConversations() == 0) { + fChatView = new ConversationView(); + SetConversation(NULL); + } + else + fListView->SelectConversation(index); +} + + void MainWindow::_InitInterface() { @@ -442,25 +459,3 @@ MainWindow::_EnsureConversationItem(BMessage* msg) } -void -MainWindow::_RemoveConversation(Conversation* chat) -{ - int32 index = fListView->ConversationIndexOf(chat); - if (index > 0) - index--; - - fListView->RemoveConversation(chat); - ProtocolLooper* looper = chat->GetProtocolLooper(); - - if (chat != NULL && looper != NULL) - looper->RemoveConversation(chat); - - if (fListView->CountConversations() == 0) { - fChatView = new ConversationView(); - SetConversation(NULL); - } - else - fListView->SelectConversation(index); -} - - diff --git a/application/windows/MainWindow.h b/application/windows/MainWindow.h index 31c2493..3f98278 100644 --- a/application/windows/MainWindow.h +++ b/application/windows/MainWindow.h @@ -42,8 +42,9 @@ public: bool active); void SetConversation(Conversation* chat); - Server* GetServer() const { return fServer; } + void RemoveConversation(Conversation* chat); + Server* GetServer() const { return fServer; } private: void _InitInterface(); @@ -51,8 +52,6 @@ private: ConversationItem* _EnsureConversationItem(BMessage* msg); - void _RemoveConversation(Conversation* chat); - Server* fServer; RosterWindow* fRosterWindow; diff --git a/protocols/xmpp/JabberHandler.cpp b/protocols/xmpp/JabberHandler.cpp index e571c44..a946999 100644 --- a/protocols/xmpp/JabberHandler.cpp +++ b/protocols/xmpp/JabberHandler.cpp @@ -1,9 +1,11 @@ /* + * Copyright 2021, Jaidyn Levesque. All rights reserved. * Copyright 2010, Pier Luigi Fiorini. All rights reserved. * Distributed under the terms of the GPL v2 License. * * Authors: * Pier Luigi Fiorini, pierluigi.fiorini@gmail.com + * Jaidyn Levesque, jadedctrl@teknik.io */ #include @@ -214,10 +216,10 @@ JabberHandler::Shutdown() if (fVCardManager) fVCardManager->cancelVCardOperations(this); - if (fClient) { + if (fClient) fClient->disposeMessageSession(fSession); - fClient->disconnect(); - } + + kill_thread(fRecvThread); return B_OK; }