From c0580dfc1771002e48cd5b303c2a6ccea06ec544 Mon Sep 17 00:00:00 2001 From: Jaidyn Ann Date: Mon, 16 Aug 2021 11:58:27 -0500 Subject: [PATCH] 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. --- application/Account.cpp | 5 +- application/ProtocolManager.cpp | 102 ++++++++++++++++++++++--- application/ProtocolManager.h | 19 ++++- application/ProtocolSettings.cpp | 57 +++++++------- application/ProtocolSettings.h | 5 +- application/windows/AccountsWindow.cpp | 32 +------- application/windows/AccountsWindow.h | 4 - application/windows/MainWindow.cpp | 15 +--- 8 files changed, 153 insertions(+), 86 deletions(-) diff --git a/application/Account.cpp b/application/Account.cpp index 2286362..82299fd 100644 --- a/application/Account.cpp +++ b/application/Account.cpp @@ -40,7 +40,10 @@ Account::Account(bigtime_t instanceId, ChatProtocol* cayap, // Load settings file BFile file(path.Path(), B_READ_ONLY); 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; } } diff --git a/application/ProtocolManager.cpp b/application/ProtocolManager.cpp index d57082c..d6829ff 100644 --- a/application/ProtocolManager.cpp +++ b/application/ProtocolManager.cpp @@ -1,9 +1,11 @@ /* * Copyright 2009-2011, Andrea Anzani. All rights reserved. + * Copyright 2021, Jaidyn Levesque. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: * Andrea Anzani, andrea.anzani@gmail.com + * Jaidyn Levesque, jadedctrl@teknik.io */ #include @@ -16,7 +18,9 @@ #include "Account.h" #include "AppMessages.h" +#include "ChatProtocolMessages.h" #include "ProtocolManager.h" +#include "ProtocolSettings.h" #include "ChatProtocol.h" #include "MainWindow.h" #include "Server.h" @@ -124,33 +128,96 @@ ProtocolManager::ProtocolInstance(bigtime_t identifier) void ProtocolManager::AddAccount(ChatProtocolAddOn* addOn, const char* account, - BHandler* target) + BHandler* target) { - TheApp* theApp = reinterpret_cast(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(); ChatProtocol* cayap = addOn->Protocol(); Account* acc = 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 - if (acc->InitCheck() != B_OK) { + else if (acc->InitCheck() != B_OK) { BMessage error(APP_ACCOUNT_FAILED); cayap->Icon()->Archive(&error); error.AddString("name", account); - theApp->GetMainWindow()->MessageReceived(&error); + _MainWin()->MessageReceived(&error); return; } fProtocolMap.AddItem(instanceId, cayap); - theApp->GetMainWindow()->GetServer()->AddProtocolLooper( - instanceId, cayap); + _Server()->AddProtocolLooper(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 ProtocolManager::_LoadAccounts(const char* image_path, ChatProtocolAddOn* addOn, - int protoIndex, BHandler* target) + int protoIndex, BHandler* target) { // Find accounts path for this protocol BPath path(AccountPath(addOn->Signature(), addOn->Protocol()->Signature())); @@ -168,13 +235,13 @@ ProtocolManager::_LoadAccounts(const char* image_path, ChatProtocolAddOn* addOn, void ProtocolManager::_LoadAccount(const char* imagePath, BEntry accountEntry, - int protoIndex, BHandler* target) + int protoIndex, BHandler* target) { image_id id = load_add_on(imagePath); if (id < 0) 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); if (addOn->Version() != APP_VERSION) return; @@ -185,7 +252,7 @@ ProtocolManager::_LoadAccount(const char* imagePath, BEntry accountEntry, void ProtocolManager::_LoadAccount(ChatProtocolAddOn* addOn, BEntry accountEntry, - BHandler* target) + BHandler* target) { BFile file(&accountEntry, B_READ_ONLY); 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; +} diff --git a/application/ProtocolManager.h b/application/ProtocolManager.h index 654bdff..9c19ead 100644 --- a/application/ProtocolManager.h +++ b/application/ProtocolManager.h @@ -1,6 +1,7 @@ /* * Copyright 2009-2011, Andrea Anzani. 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. */ #ifndef _PROTOCOL_MANAGER_H @@ -18,6 +19,11 @@ class BBitmap; class BDirectory; class BHandler; +class MainWindow; +class ProtocolSettings; +class Server; + + class ProtocolManager { public: bool Init(BDirectory dir, BHandler* target); @@ -33,8 +39,14 @@ public: ChatProtocol* ProtocolInstance(bigtime_t identifier); void AddAccount(ChatProtocolAddOn* addOn, - const char* account, - BHandler* target); + const char* account, BHandler* target); + + void EnableAccount(ProtocolSettings* settings, + const char* account); + void DisableAccount(ProtocolSettings* settings, + const char* account); + void ToggleAccount(ProtocolSettings* settings, + const char* account); private: typedef KeyMap AddOnMap; @@ -51,6 +63,9 @@ private: void _LoadAccount(ChatProtocolAddOn* addOn, BEntry accountEntry, BHandler* target); + MainWindow* _MainWin(); + Server* _Server(); + AddOnMap fAddOnMap; ProtocolMap fProtocolMap; }; diff --git a/application/ProtocolSettings.cpp b/application/ProtocolSettings.cpp index 02dae13..749e281 100644 --- a/application/ProtocolSettings.cpp +++ b/application/ProtocolSettings.cpp @@ -76,7 +76,7 @@ ProtocolSettings::Load(const char* account, BView* parent) BMessage* settings = NULL; if (account) { - status_t ret = _Load(account, &settings); + status_t ret = Load(account, &settings); if (ret != B_OK) 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 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) 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 BPath path(AccountPath(fAddOn->Signature(), fAddOn->ProtoSignature())); + status_t ret; if ((ret = path.InitCheck()) != B_OK) 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; -} diff --git a/application/ProtocolSettings.h b/application/ProtocolSettings.h index e7ac826..b69761d 100644 --- a/application/ProtocolSettings.h +++ b/application/ProtocolSettings.h @@ -25,15 +25,16 @@ public: BObjectList Accounts() const; status_t Load(const char* account, BView* parent); + status_t Load(const char* account, BMessage** settings); + status_t Save(const char* account, BView* parent, BString* errorText = NULL); + status_t Save(const char* account, BMessage settings); status_t Rename(const char* from, const char* to); status_t Delete(const char* account); private: - status_t _Load(const char* account, BMessage** settings); - ChatProtocolAddOn* fAddOn; ProtocolTemplate fTemplate; status_t fStatus; diff --git a/application/windows/AccountsWindow.cpp b/application/windows/AccountsWindow.cpp index 0f8d67d..68aa4ef 100644 --- a/application/windows/AccountsWindow.cpp +++ b/application/windows/AccountsWindow.cpp @@ -195,12 +195,8 @@ AccountsWindow::MessageReceived(BMessage* msg) break; const char* account = item->Account(); - int64 instance = _AccountInstance(account); - - if (instance == -1) - _EnableAccount(account, item->Settings()); - else - _DisableAccount(account, instance); + ProtocolManager::Get()->ToggleAccount(item->Settings(), account); + fListView->DeselectAll(); break; } case kAccountAdded: @@ -232,7 +228,7 @@ AccountsWindow::MessageReceived(BMessage* msg) = new AccountListItem(settings, account.String()); fListView->AddItem(listItem); - _EnableAccount(account, settings); + ProtocolManager::Get()->EnableAccount(settings, account); } else { // Rename list item 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 AccountsWindow::_AccountInstance(const char* account) { diff --git a/application/windows/AccountsWindow.h b/application/windows/AccountsWindow.h index aef715f..91bd1f1 100644 --- a/application/windows/AccountsWindow.h +++ b/application/windows/AccountsWindow.h @@ -30,10 +30,6 @@ private: void _LoadListView(ProtocolSettings* settings); - void _DisableAccount(const char* account, int64 instance); - void _EnableAccount(const char* account, - ProtocolSettings* settings); - int64 _AccountInstance(const char* account); }; diff --git a/application/windows/MainWindow.cpp b/application/windows/MainWindow.cpp index 4e3f943..5e43c3d 100644 --- a/application/windows/MainWindow.cpp +++ b/application/windows/MainWindow.cpp @@ -139,23 +139,14 @@ MainWindow::MessageReceived(BMessage* message) } case APP_TOGGLE_ACCOUNT: { + ProtocolManager* protoMan = ProtocolManager::Get(); ProtocolSettings* settings = NULL; BString account = message->FindString("account"); int64 instance = message->GetInt64("instance", -1); message->FindPointer("settings", (void**)&settings); - if (account.IsEmpty() == false && settings != NULL) { - // Enable - 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); - } - } + if (account.IsEmpty() == false && settings != NULL) + protoMan->ToggleAccount(settings, account); break; } case APP_NEW_CHAT: