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
const uint32 CAYA_MOVE_DOWN = 'CYmd';
//! Select the downward conversation
const uint32 CAYA_DISABLE_ACCOUNT = 'CYda';
#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
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());
}

View File

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

View File

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

View File

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

View File

@ -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)
{

View File

@ -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);

View File

@ -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());

View File

@ -18,16 +18,20 @@
#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 kToggleAccount = 'tgac';
const uint32 kSelect = 'selt';
@ -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);
}
@ -111,9 +119,23 @@ PreferencesAccounts::MessageReceived(BMessage* msg)
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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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 <Directory.h>
@ -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;
}