Save disabling of accounts, make persistent

If the user disables an account, this saves it so that on any
subsequent start-ups, the account won't be connected until the user
explicitly re-enables it.

ProtocolSettings were reworked to allow for publicly loading/saving
settings from BMessages, rather than solely from BViews.

In addition, all program-side disabling, enabling, and toggling of
accounts has been consolidated into ProtocolManager. This makes life
easier for other parts of the program that have to do these things
anyway.
This commit is contained in:
Jaidyn Ann 2021-08-16 11:58:27 -05:00
parent c492a46a65
commit c0580dfc17
8 changed files with 153 additions and 86 deletions

View File

@ -40,7 +40,10 @@ Account::Account(bigtime_t instanceId, ChatProtocol* cayap,
// Load settings file // Load settings file
BFile file(path.Path(), B_READ_ONLY); BFile file(path.Path(), B_READ_ONLY);
if (fSettings->Unflatten(&file) == B_OK) if (fSettings->Unflatten(&file) == B_OK)
fStatus = fProtocol->UpdateSettings(fSettings); if (fSettings->GetBool("disabled", false) == false)
fStatus = fProtocol->UpdateSettings(fSettings);
else
fStatus = B_DONT_DO_THAT;
} }
} }

View File

@ -1,9 +1,11 @@
/* /*
* Copyright 2009-2011, Andrea Anzani. All rights reserved. * Copyright 2009-2011, Andrea Anzani. All rights reserved.
* Copyright 2021, Jaidyn Levesque. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Andrea Anzani, andrea.anzani@gmail.com * Andrea Anzani, andrea.anzani@gmail.com
* Jaidyn Levesque, jadedctrl@teknik.io
*/ */
#include <stdio.h> #include <stdio.h>
@ -16,7 +18,9 @@
#include "Account.h" #include "Account.h"
#include "AppMessages.h" #include "AppMessages.h"
#include "ChatProtocolMessages.h"
#include "ProtocolManager.h" #include "ProtocolManager.h"
#include "ProtocolSettings.h"
#include "ChatProtocol.h" #include "ChatProtocol.h"
#include "MainWindow.h" #include "MainWindow.h"
#include "Server.h" #include "Server.h"
@ -124,33 +128,96 @@ ProtocolManager::ProtocolInstance(bigtime_t identifier)
void void
ProtocolManager::AddAccount(ChatProtocolAddOn* addOn, const char* account, ProtocolManager::AddAccount(ChatProtocolAddOn* addOn, const char* account,
BHandler* target) BHandler* target)
{ {
TheApp* theApp = reinterpret_cast<TheApp*>(be_app); // If already active, don't double-dip!
bool active = false;
_Server()->GetActiveAccounts().ValueFor(BString(account), &active);
if (active == true)
return;
bigtime_t instanceId = system_time(); bigtime_t instanceId = system_time();
ChatProtocol* cayap = addOn->Protocol(); ChatProtocol* cayap = addOn->Protocol();
Account* acc = Account* acc =
new Account(instanceId, cayap, account, addOn->Signature(), target); new Account(instanceId, cayap, account, addOn->Signature(), target);
// If account is disabled, just let it go
if (acc->InitCheck() == B_DONT_DO_THAT) {
delete acc;
return;
}
// Send a "whoops" notification if hits a failure // Send a "whoops" notification if hits a failure
if (acc->InitCheck() != B_OK) { else if (acc->InitCheck() != B_OK) {
BMessage error(APP_ACCOUNT_FAILED); BMessage error(APP_ACCOUNT_FAILED);
cayap->Icon()->Archive(&error); cayap->Icon()->Archive(&error);
error.AddString("name", account); error.AddString("name", account);
theApp->GetMainWindow()->MessageReceived(&error); _MainWin()->MessageReceived(&error);
return; return;
} }
fProtocolMap.AddItem(instanceId, cayap); fProtocolMap.AddItem(instanceId, cayap);
theApp->GetMainWindow()->GetServer()->AddProtocolLooper( _Server()->AddProtocolLooper(instanceId, cayap);
instanceId, cayap); }
void
ProtocolManager::EnableAccount(ProtocolSettings* settings, const char* account)
{
BMessage* msg = NULL;
if (settings->Load(account, &msg) == B_OK) {
if (msg->HasBool("disabled"))
msg->ReplaceBool("disabled", false);
else
msg->AddBool("disabled", false);
settings->Save(account, *msg);
}
AddAccount(settings->AddOn(), account, _MainWin());
}
void
ProtocolManager::DisableAccount(ProtocolSettings* settings, const char* account)
{
bool active = false;
int64 instance
= _Server()->GetActiveAccounts().ValueFor(BString(account), &active);
if (active == false)
return;
BMessage* msg = NULL;
if (settings->Load(account, &msg) == B_OK) {
if (msg->HasBool("disabled"))
msg->ReplaceBool("disabled", true);
else
msg->AddBool("disabled", true);
settings->Save(account, *msg);
}
BMessage remove(IM_MESSAGE);
remove.AddInt32("im_what", IM_PROTOCOL_DISABLE);
remove.AddInt64("instance", instance);
_MainWin()->PostMessage(&remove);
}
void
ProtocolManager::ToggleAccount(ProtocolSettings* settings, const char* account)
{
bool active = false;
int64 instance
= _Server()->GetActiveAccounts().ValueFor(BString(account), &active);
if (active == true)
DisableAccount(settings, account);
else
EnableAccount(settings, account);
} }
void void
ProtocolManager::_LoadAccounts(const char* image_path, ChatProtocolAddOn* addOn, ProtocolManager::_LoadAccounts(const char* image_path, ChatProtocolAddOn* addOn,
int protoIndex, BHandler* target) int protoIndex, BHandler* target)
{ {
// Find accounts path for this protocol // Find accounts path for this protocol
BPath path(AccountPath(addOn->Signature(), addOn->Protocol()->Signature())); BPath path(AccountPath(addOn->Signature(), addOn->Protocol()->Signature()));
@ -168,13 +235,13 @@ ProtocolManager::_LoadAccounts(const char* image_path, ChatProtocolAddOn* addOn,
void void
ProtocolManager::_LoadAccount(const char* imagePath, BEntry accountEntry, ProtocolManager::_LoadAccount(const char* imagePath, BEntry accountEntry,
int protoIndex, BHandler* target) int protoIndex, BHandler* target)
{ {
image_id id = load_add_on(imagePath); image_id id = load_add_on(imagePath);
if (id < 0) if (id < 0)
return; return;
// If add-on's API version fits then load accounts... // If add-on's API version fits then load accounts
ChatProtocolAddOn* addOn = new ChatProtocolAddOn(id, imagePath, protoIndex); ChatProtocolAddOn* addOn = new ChatProtocolAddOn(id, imagePath, protoIndex);
if (addOn->Version() != APP_VERSION) if (addOn->Version() != APP_VERSION)
return; return;
@ -185,7 +252,7 @@ ProtocolManager::_LoadAccount(const char* imagePath, BEntry accountEntry,
void void
ProtocolManager::_LoadAccount(ChatProtocolAddOn* addOn, BEntry accountEntry, ProtocolManager::_LoadAccount(ChatProtocolAddOn* addOn, BEntry accountEntry,
BHandler* target) BHandler* target)
{ {
BFile file(&accountEntry, B_READ_ONLY); BFile file(&accountEntry, B_READ_ONLY);
BMessage msg; BMessage msg;
@ -198,3 +265,18 @@ ProtocolManager::_LoadAccount(ChatProtocolAddOn* addOn, BEntry accountEntry,
} }
} }
} }
MainWindow*
ProtocolManager::_MainWin()
{
return ((TheApp*)be_app)->GetMainWindow();
}
Server*
ProtocolManager::_Server()
{
MainWindow* win = _MainWin();
return win ? win->GetServer() : NULL;
}

View File

@ -1,6 +1,7 @@
/* /*
* Copyright 2009-2011, Andrea Anzani. All rights reserved. * Copyright 2009-2011, Andrea Anzani. All rights reserved.
* Copyright 2009-2011, Pier Luigi Fiorini. 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. * Distributed under the terms of the MIT License.
*/ */
#ifndef _PROTOCOL_MANAGER_H #ifndef _PROTOCOL_MANAGER_H
@ -18,6 +19,11 @@ class BBitmap;
class BDirectory; class BDirectory;
class BHandler; class BHandler;
class MainWindow;
class ProtocolSettings;
class Server;
class ProtocolManager { class ProtocolManager {
public: public:
bool Init(BDirectory dir, BHandler* target); bool Init(BDirectory dir, BHandler* target);
@ -33,8 +39,14 @@ public:
ChatProtocol* ProtocolInstance(bigtime_t identifier); ChatProtocol* ProtocolInstance(bigtime_t identifier);
void AddAccount(ChatProtocolAddOn* addOn, void AddAccount(ChatProtocolAddOn* addOn,
const char* account, const char* account, BHandler* target);
BHandler* target);
void EnableAccount(ProtocolSettings* settings,
const char* account);
void DisableAccount(ProtocolSettings* settings,
const char* account);
void ToggleAccount(ProtocolSettings* settings,
const char* account);
private: private:
typedef KeyMap<BString, ChatProtocolAddOn*> AddOnMap; typedef KeyMap<BString, ChatProtocolAddOn*> AddOnMap;
@ -51,6 +63,9 @@ private:
void _LoadAccount(ChatProtocolAddOn* addOn, void _LoadAccount(ChatProtocolAddOn* addOn,
BEntry accountEntry, BHandler* target); BEntry accountEntry, BHandler* target);
MainWindow* _MainWin();
Server* _Server();
AddOnMap fAddOnMap; AddOnMap fAddOnMap;
ProtocolMap fProtocolMap; ProtocolMap fProtocolMap;
}; };

View File

@ -76,7 +76,7 @@ ProtocolSettings::Load(const char* account, BView* parent)
BMessage* settings = NULL; BMessage* settings = NULL;
if (account) { if (account) {
status_t ret = _Load(account, &settings); status_t ret = Load(account, &settings);
if (ret != B_OK) if (ret != B_OK)
return ret; return ret;
} }
@ -84,6 +84,30 @@ ProtocolSettings::Load(const char* account, BView* parent)
} }
status_t
ProtocolSettings::Load(const char* account, BMessage** settings)
{
if (!account || !settings)
return B_BAD_VALUE;
status_t ret = B_ERROR;
// Find user's settings path
BPath path(AccountPath(fAddOn->Signature(), fAddOn->ProtoSignature()));
if ((ret = path.InitCheck()) != B_OK)
return ret;
// Load settings file
path.Append(account);
BFile file(path.Path(), B_READ_ONLY);
BMessage* msg = new BMessage();
ret = msg->Unflatten(&file);
*settings = msg;
return ret;
}
status_t status_t
ProtocolSettings::Save(const char* account, BView* parent, BString* errorText) ProtocolSettings::Save(const char* account, BView* parent, BString* errorText)
{ {
@ -95,12 +119,17 @@ ProtocolSettings::Save(const char* account, BView* parent, BString* errorText)
if (status != B_OK) if (status != B_OK)
return status; return status;
return Save(account, settings);
}
status_t ret = B_ERROR;
status_t
ProtocolSettings::Save(const char* account, BMessage settings)
{
// Find user's settings path // Find user's settings path
BPath path(AccountPath(fAddOn->Signature(), fAddOn->ProtoSignature())); BPath path(AccountPath(fAddOn->Signature(), fAddOn->ProtoSignature()));
status_t ret;
if ((ret = path.InitCheck()) != B_OK) if ((ret = path.InitCheck()) != B_OK)
return ret; return ret;
@ -155,27 +184,3 @@ ProtocolSettings::Delete(const char* account)
} }
status_t
ProtocolSettings::_Load(const char* account, BMessage** settings)
{
*settings = NULL;
if (!account || !settings)
return B_BAD_VALUE;
status_t ret = B_ERROR;
// Find user's settings path
BPath path(AccountPath(fAddOn->Signature(), fAddOn->ProtoSignature()));
if ((ret = path.InitCheck()) != B_OK)
return ret;
// Load settings file
path.Append(account);
BFile file(path.Path(), B_READ_ONLY);
BMessage* msg = new BMessage();
ret = msg->Unflatten(&file);
*settings = msg;
return ret;
}

View File

@ -25,15 +25,16 @@ public:
BObjectList<BString> Accounts() const; BObjectList<BString> Accounts() const;
status_t Load(const char* account, BView* parent); status_t Load(const char* account, BView* parent);
status_t Load(const char* account, BMessage** settings);
status_t Save(const char* account, BView* parent, status_t Save(const char* account, BView* parent,
BString* errorText = NULL); BString* errorText = NULL);
status_t Save(const char* account, BMessage settings);
status_t Rename(const char* from, const char* to); status_t Rename(const char* from, const char* to);
status_t Delete(const char* account); status_t Delete(const char* account);
private: private:
status_t _Load(const char* account, BMessage** settings);
ChatProtocolAddOn* fAddOn; ChatProtocolAddOn* fAddOn;
ProtocolTemplate fTemplate; ProtocolTemplate fTemplate;
status_t fStatus; status_t fStatus;

View File

@ -195,12 +195,8 @@ AccountsWindow::MessageReceived(BMessage* msg)
break; break;
const char* account = item->Account(); const char* account = item->Account();
int64 instance = _AccountInstance(account); ProtocolManager::Get()->ToggleAccount(item->Settings(), account);
fListView->DeselectAll();
if (instance == -1)
_EnableAccount(account, item->Settings());
else
_DisableAccount(account, instance);
break; break;
} }
case kAccountAdded: case kAccountAdded:
@ -232,7 +228,7 @@ AccountsWindow::MessageReceived(BMessage* msg)
= new AccountListItem(settings, account.String()); = new AccountListItem(settings, account.String());
fListView->AddItem(listItem); fListView->AddItem(listItem);
_EnableAccount(account, settings); ProtocolManager::Get()->EnableAccount(settings, account);
} else { } else {
// Rename list item // Rename list item
for (int32 i = 0; i < fListView->CountItems(); i++) { for (int32 i = 0; i < fListView->CountItems(); i++) {
@ -274,28 +270,6 @@ AccountsWindow::_LoadListView(ProtocolSettings* settings)
} }
void
AccountsWindow::_DisableAccount(const char* account, int64 instance)
{
BMessage* remove = new BMessage(IM_MESSAGE);
remove->AddInt32("im_what", IM_PROTOCOL_DISABLE);
remove->AddInt64("instance", instance);
((TheApp*)be_app)->GetMainWindow()->PostMessage(remove);
fToggleButton->SetLabel(B_TRANSLATE("Enable"));
fToggleButton->SetEnabled(false);
}
void
AccountsWindow::_EnableAccount(const char* account,
ProtocolSettings* settings)
{
ProtocolManager::Get()->AddAccount(settings->AddOn(), account,
((TheApp*)be_app)->GetMainWindow());
}
int64 int64
AccountsWindow::_AccountInstance(const char* account) AccountsWindow::_AccountInstance(const char* account)
{ {

View File

@ -30,10 +30,6 @@ private:
void _LoadListView(ProtocolSettings* settings); void _LoadListView(ProtocolSettings* settings);
void _DisableAccount(const char* account, int64 instance);
void _EnableAccount(const char* account,
ProtocolSettings* settings);
int64 _AccountInstance(const char* account); int64 _AccountInstance(const char* account);
}; };

View File

@ -139,23 +139,14 @@ MainWindow::MessageReceived(BMessage* message)
} }
case APP_TOGGLE_ACCOUNT: case APP_TOGGLE_ACCOUNT:
{ {
ProtocolManager* protoMan = ProtocolManager::Get();
ProtocolSettings* settings = NULL; ProtocolSettings* settings = NULL;
BString account = message->FindString("account"); BString account = message->FindString("account");
int64 instance = message->GetInt64("instance", -1); int64 instance = message->GetInt64("instance", -1);
message->FindPointer("settings", (void**)&settings); message->FindPointer("settings", (void**)&settings);
if (account.IsEmpty() == false && settings != NULL) { if (account.IsEmpty() == false && settings != NULL)
// Enable protoMan->ToggleAccount(settings, account);
if (instance == -1)
ProtocolManager::Get()->AddAccount(settings->AddOn(),
account, this);
else {
BMessage remove(IM_MESSAGE);
remove.AddInt32("im_what", IM_PROTOCOL_DISABLE);
remove.AddInt64("instance", instance);
PostMessage(&remove);
}
}
break; break;
} }
case APP_NEW_CHAT: case APP_NEW_CHAT: