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.
This commit is contained in:
Jaidyn Ann 2021-06-11 20:33:28 -05:00
parent 552e937e51
commit dcc5e443d3
14 changed files with 156 additions and 59 deletions

View File

@ -44,4 +44,7 @@ const uint32 CAYA_MOVE_UP = 'CYmu';
//! Select the downward conversation //! Select the downward conversation
const uint32 CAYA_MOVE_DOWN = 'CYmd'; const uint32 CAYA_MOVE_DOWN = 'CYmd';
//! Select the downward conversation
const uint32 CAYA_DISABLE_ACCOUNT = 'CYda';
#endif // _CAYA_MESSAGES_H #endif // _CAYA_MESSAGES_H

View File

@ -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 BString
Conversation::GetId() const Conversation::GetId() const
{ {
@ -332,12 +345,7 @@ Conversation::_LogChatMessage(BMessage* msg)
uname = "You"; uname = "You";
BString logLine("["); BString logLine("[");
logLine << date; logLine << date << "] <" << uname << "> " << body << "\n";
logLine << "] ";
logLine << uname;
logLine << ": ";
logLine << body;
logLine << "\n";
logFile.Write(logLine.String(), logLine.Length()); logFile.Write(logLine.String(), logLine.Length());
} }

View File

@ -30,6 +30,7 @@ typedef KeyMap<BString, Role*> RoleMap;
class Conversation : public Notifier, public Observer { class Conversation : public Notifier, public Observer {
public: public:
Conversation(BString id, BMessenger msgn); Conversation(BString id, BMessenger msgn);
~Conversation();
BString GetId() const; BString GetId() const;

View File

@ -36,6 +36,13 @@ ProtocolLooper::ProtocolLooper(CayaProtocol* protocol, int64 instance)
} }
ProtocolLooper::~ProtocolLooper()
{
fProtocol->Shutdown();
delete fProtocol;
}
void void
ProtocolLooper::MessageReceived(BMessage* msg) ProtocolLooper::MessageReceived(BMessage* msg)
{ {

View File

@ -28,6 +28,7 @@ typedef KeyMap<BString, User*> UserMap;
class ProtocolLooper : public BLooper { class ProtocolLooper : public BLooper {
public: public:
ProtocolLooper(CayaProtocol* protocol, int64 instance); ProtocolLooper(CayaProtocol* protocol, int64 instance);
~ProtocolLooper();
void MessageReceived(BMessage* msg); void MessageReceived(BMessage* msg);

View File

@ -109,6 +109,18 @@ Server::Filter(BMessage* message, BHandler **target)
break; break;
} }
case CAYA_DISABLE_ACCOUNT:
{
int64 instance = 0;
if (message->FindInt64("instance", &instance) != B_OK) {
result = B_SKIP_MESSAGE;
break;
}
RemoveProtocolLooper(instance);
break;
}
default: default:
// Dispatch not handled messages to main window // Dispatch not handled messages to main window
break; break;
@ -475,6 +487,22 @@ Server::AddProtocolLooper(bigtime_t instanceId, CayaProtocol* cayap)
void void
Server::RemoveProtocolLooper(bigtime_t instanceId) 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* ProtocolLooper*
Server::_LooperFromMessage(BMessage* message) Server::_LooperFromMessage(BMessage* message)
{ {

View File

@ -57,7 +57,6 @@ public:
ChatMap Conversations() const; ChatMap Conversations() const;
Conversation* ConversationById(BString id, int64 instance); Conversation* ConversationById(BString id, int64 instance);
void AddConversation(Conversation* chat, int64 instance); void AddConversation(Conversation* chat, int64 instance);
void RemoveConversation(Conversation* chat, int64 instance);
private: private:
ProtocolLooper* _LooperFromMessage(BMessage* message); ProtocolLooper* _LooperFromMessage(BMessage* message);

View File

@ -27,6 +27,7 @@
#include "ReplicantStatusView.h" #include "ReplicantStatusView.h"
#include "Server.h" #include "Server.h"
TheApp::TheApp() TheApp::TheApp()
: :
BApplication(CAYA_SIGNATURE), BApplication(CAYA_SIGNATURE),
@ -59,7 +60,7 @@ TheApp::ReadyToRun()
BString msg("Can't find smileys settings in:\n\n"); BString msg("Can't find smileys settings in:\n\n");
msg << currentPath.Path(); msg << currentPath.Path();
BAlert* alert = new BAlert("", msg.String(), "Ouch!"); BAlert* alert = new BAlert("", msg.String(), "Ouch!");
alert->Go(); // alert->Go();
} }
printf("Loaded Emoticons settings from: %s\n", currentPath.Path()); printf("Loaded Emoticons settings from: %s\n", currentPath.Path());

View File

@ -18,17 +18,21 @@
#include "AccountDialog.h" #include "AccountDialog.h"
#include "AccountListItem.h" #include "AccountListItem.h"
#include "CayaMessages.h"
#include "CayaProtocol.h" #include "CayaProtocol.h"
#include "PreferencesAccounts.h" #include "PreferencesAccounts.h"
#include "ProtocolManager.h" #include "ProtocolManager.h"
#include "ProtocolSettings.h" #include "ProtocolSettings.h"
#include "MainWindow.h" #include "MainWindow.h"
#include "Server.h"
#include "TheApp.h" #include "TheApp.h"
const uint32 kAddAccount = 'adac';
const uint32 kEditAccount = 'edac'; const uint32 kAddAccount = 'adac';
const uint32 kDelAccount = 'dlac'; const uint32 kEditAccount = 'edac';
const uint32 kSelect = 'selt'; const uint32 kDelAccount = 'dlac';
const uint32 kToggleAccount = 'tgac';
const uint32 kSelect = 'selt';
static int static int
@ -74,8 +78,10 @@ PreferencesAccounts::PreferencesAccounts()
proto->SetMenu(fProtosMenu); proto->SetMenu(fProtosMenu);
fDelButton = new BButton("Del", new BMessage(kDelAccount)); fDelButton = new BButton("Del", new BMessage(kDelAccount));
fEditButton = new BButton("Edit" B_UTF8_ELLIPSIS, new BMessage(kEditAccount)); fEditButton = new BButton("Edit" B_UTF8_ELLIPSIS, new BMessage(kEditAccount));
fToggleButton = new BButton("Enable", new BMessage(kToggleAccount));
fDelButton->SetEnabled(false); fDelButton->SetEnabled(false);
fEditButton->SetEnabled(false); fEditButton->SetEnabled(false);
fToggleButton->SetEnabled(false);
BLayoutBuilder::Group<>(this, B_VERTICAL) BLayoutBuilder::Group<>(this, B_VERTICAL)
.SetInsets(B_USE_DEFAULT_SPACING) .SetInsets(B_USE_DEFAULT_SPACING)
@ -85,6 +91,7 @@ PreferencesAccounts::PreferencesAccounts()
.Add(proto) .Add(proto)
.Add(fDelButton) .Add(fDelButton)
.AddGlue() .AddGlue()
.Add(fToggleButton)
.Add(fEditButton) .Add(fEditButton)
.End() .End()
.End(); .End();
@ -98,6 +105,7 @@ PreferencesAccounts::AttachedToWindow()
fProtosMenu->SetTargetForItems(this); fProtosMenu->SetTargetForItems(this);
fDelButton->SetTarget(this); fDelButton->SetTarget(this);
fEditButton->SetTarget(this); fEditButton->SetTarget(this);
fToggleButton->SetTarget(this);
} }
@ -106,14 +114,28 @@ PreferencesAccounts::MessageReceived(BMessage* msg)
{ {
switch (msg->what) { switch (msg->what) {
case kSelect: { case kSelect: {
int32 index; int32 index;
if (msg->FindInt32("index", &index) == B_OK) { if (msg->FindInt32("index", &index) == B_OK) {
fDelButton->SetEnabled(index >= 0); fDelButton->SetEnabled(index >= 0);
fEditButton->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; break;
}
case kAddAccount: { case kAddAccount: {
void *pointer = NULL; void *pointer = NULL;
if (msg->FindPointer("settings", &pointer) == B_OK) { if (msg->FindPointer("settings", &pointer) == B_OK) {
@ -161,6 +183,28 @@ PreferencesAccounts::MessageReceived(BMessage* msg)
} }
break; 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 kAccountAdded:
case kAccountRenamed: { case kAccountRenamed: {
void* pointer = NULL; void* pointer = NULL;
@ -234,3 +278,16 @@ PreferencesAccounts::_LoadListView(ProtocolSettings* settings)
fListView->AddItem(listItem); 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;
}

View File

@ -14,6 +14,7 @@ class BPopUpMenu;
class ToolButton; class ToolButton;
class ProtocolSettings; class ProtocolSettings;
class PreferencesAccounts : public BView { class PreferencesAccounts : public BView {
public: public:
PreferencesAccounts(); PreferencesAccounts();
@ -26,9 +27,12 @@ private:
BPopUpMenu* fProtosMenu; BPopUpMenu* fProtosMenu;
BButton* fDelButton; BButton* fDelButton;
BButton* fEditButton; BButton* fEditButton;
BButton* fToggleButton;
void _LoadListView(ProtocolSettings* settings); void _LoadListView(ProtocolSettings* settings);
bool _AccountEnabled(const char* account);
}; };
#endif // _PREFERENCES_ACCOUNTS_H #endif // _PREFERENCES_ACCOUNTS_H

View File

@ -36,8 +36,9 @@ ConversationListView::MessageReceived(BMessage* msg)
ConversationItem* item; ConversationItem* item;
int32 selIndex = CurrentSelection(); int32 selIndex = CurrentSelection();
if (ItemAt(selIndex)->OutlineLevel() == 1 if (selIndex >= 0
&& (item = (ConversationItem*)ItemAt(selIndex)) != NULL) && (item = (ConversationItem*)ItemAt(selIndex)) != NULL
&& item->OutlineLevel() == 1)
item->GetConversation()->ShowView(false, true); item->GetConversation()->ShowView(false, true);
break; break;
} }
@ -73,7 +74,7 @@ ConversationListView::MouseDown(BPoint where)
int32 newSel = CurrentSelection(); int32 newSel = CurrentSelection();
// Don't allow selecting an AccountItem // Don't allow selecting an AccountItem
if (ItemAt(newSel)->OutlineLevel() == 0) { if (newSel >= 0 && ItemAt(newSel)->OutlineLevel() == 0) {
Select(selection); Select(selection);
return; return;
} }

View File

@ -249,8 +249,7 @@ MainWindow::ImMessage(BMessage* msg)
if (item == NULL) if (item == NULL)
break; break;
_RemoveConversation(item->GetConversation()); delete item->GetConversation();
item->GetConversation()->GetView()->MessageReceived(msg);
break; break;
} }
case IM_AVATAR_SET: 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 void
MainWindow::_InitInterface() 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);
}

View File

@ -42,8 +42,9 @@ public:
bool active); bool active);
void SetConversation(Conversation* chat); void SetConversation(Conversation* chat);
Server* GetServer() const { return fServer; } void RemoveConversation(Conversation* chat);
Server* GetServer() const { return fServer; }
private: private:
void _InitInterface(); void _InitInterface();
@ -51,8 +52,6 @@ private:
ConversationItem* ConversationItem*
_EnsureConversationItem(BMessage* msg); _EnsureConversationItem(BMessage* msg);
void _RemoveConversation(Conversation* chat);
Server* fServer; Server* fServer;
RosterWindow* fRosterWindow; RosterWindow* fRosterWindow;

View File

@ -1,9 +1,11 @@
/* /*
* Copyright 2021, Jaidyn Levesque. All rights reserved.
* Copyright 2010, Pier Luigi Fiorini. All rights reserved. * Copyright 2010, Pier Luigi Fiorini. All rights reserved.
* Distributed under the terms of the GPL v2 License. * Distributed under the terms of the GPL v2 License.
* *
* Authors: * Authors:
* Pier Luigi Fiorini, pierluigi.fiorini@gmail.com * Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
* Jaidyn Levesque, jadedctrl@teknik.io
*/ */
#include <Directory.h> #include <Directory.h>
@ -214,10 +216,10 @@ JabberHandler::Shutdown()
if (fVCardManager) if (fVCardManager)
fVCardManager->cancelVCardOperations(this); fVCardManager->cancelVCardOperations(this);
if (fClient) { if (fClient)
fClient->disposeMessageSession(fSession); fClient->disposeMessageSession(fSession);
fClient->disconnect();
} kill_thread(fRecvThread);
return B_OK; return B_OK;
} }