diff --git a/application/AccountManager.cpp b/application/AccountManager.cpp index 98943ae..ecec071 100644 --- a/application/AccountManager.cpp +++ b/application/AccountManager.cpp @@ -23,15 +23,11 @@ AccountManager::AccountManager() fStatus(STATUS_OFFLINE), fReplicantMessenger(NULL) { - TheApp* theApp = reinterpret_cast(be_app); - RegisterObserver(theApp->GetMainWindow()); } AccountManager::~AccountManager() { - TheApp* theApp = reinterpret_cast(be_app); - UnregisterObserver(theApp->GetMainWindow()); delete fReplicantMessenger; } @@ -46,7 +42,7 @@ AccountManager::Get() void -AccountManager::SetNickname(BString nick) +AccountManager::SetNickname(BString nick, int64 instance) { // Create message BMessage* msg = new BMessage(IM_MESSAGE); @@ -56,7 +52,12 @@ AccountManager::SetNickname(BString nick) // Send message TheApp* theApp = reinterpret_cast(be_app); MainWindow* win = theApp->GetMainWindow(); - win->GetServer()->SendAllProtocolMessage(msg); + if (instance > -1) { + msg->AddInt64("instance", instance); + win->GetServer()->SendProtocolMessage(msg); + } + else + win->GetServer()->SendAllProtocolMessage(msg); } @@ -75,26 +76,40 @@ AccountManager::Status() const void -AccountManager::SetStatus(UserStatus status, const char* str) +AccountManager::SetStatus(UserStatus status, const char* str, int64 instance) { - if (fStatus != status) { - // Create status change message - BMessage* msg = new BMessage(IM_MESSAGE); - msg->AddInt32("im_what", IM_SET_OWN_STATUS); - msg->AddInt32("status", (int32)status); - if (str != NULL) - msg->AddString("message", str); + if (fStatus == status && instance == -1) + return; - // Send message - TheApp* theApp = reinterpret_cast(be_app); - MainWindow* win = theApp->GetMainWindow(); + // Create status change message + BMessage* msg = new BMessage(IM_MESSAGE); + msg->AddInt32("im_what", IM_SET_OWN_STATUS); + msg->AddInt32("status", (int32)status); + if (str != NULL) + msg->AddString("message", str); + + // Send message + TheApp* theApp = reinterpret_cast(be_app); + MainWindow* win = theApp->GetMainWindow(); + + if (instance > -1) { + msg->AddInt64("instance", instance); + win->GetServer()->SendProtocolMessage(msg); + } + else win->GetServer()->SendAllProtocolMessage(msg); - // Notify status change - fStatus = status; - NotifyInteger(INT_ACCOUNT_STATUS, (int32)fStatus); - ReplicantStatusNotify((UserStatus)status); - } + // Notify status change + fStatus = status; + NotifyInteger(INT_ACCOUNT_STATUS, (int32)fStatus); + ReplicantStatusNotify((UserStatus)status); +} + + +void +AccountManager::SetStatus(UserStatus status, int64 instance) +{ + SetStatus(status, NULL, instance); } diff --git a/application/AccountManager.h b/application/AccountManager.h index ed0f76a..da8a089 100644 --- a/application/AccountManager.h +++ b/application/AccountManager.h @@ -15,11 +15,12 @@ class AccountManager : public Notifier { public: static AccountManager* Get(); - void SetNickname(BString nick); + void SetNickname(BString nick, int64 instance = -1); UserStatus Status() const; - void SetStatus(UserStatus status, - const char* str = NULL); + void SetStatus(UserStatus status, int64 instance = -1); + void SetStatus(UserStatus status, const char* str, + int64 instance = -1); void SetReplicantMessenger(BMessenger* messenger); void ReplicantStatusNotify(UserStatus status, diff --git a/application/Makefile b/application/Makefile index caf9b81..47fc518 100644 --- a/application/Makefile +++ b/application/Makefile @@ -63,7 +63,6 @@ SRCS = \ application/views/ConversationListView.cpp \ application/views/ConversationView.cpp \ application/views/InviteDialogue.cpp \ - application/views/NicknameTextControl.cpp \ application/views/ReplicantStatusView.cpp \ application/views/ReplicantMenuItem.cpp \ application/views/RosterItem.cpp \ diff --git a/application/Server.cpp b/application/Server.cpp index 7c8ecb4..f208c45 100644 --- a/application/Server.cpp +++ b/application/Server.cpp @@ -253,15 +253,18 @@ Server::ImMessage(BMessage* msg) case IM_OWN_STATUS_SET: { int32 status; - const char* protocol; - if (msg->FindInt32("status", &status) != B_OK) - return B_SKIP_MESSAGE; - if (msg->FindString("protocol", &protocol) != B_OK) + ProtocolLooper* looper = _LooperFromMessage(msg); + if (msg->FindInt32("status", &status) != B_OK || looper == NULL) return B_SKIP_MESSAGE; - AccountManager* accountManager = AccountManager::Get(); - accountManager->SetStatus((UserStatus)status); + Contact* contact = looper->GetOwnContact(); + if (contact != NULL) { + contact->SetNotifyStatus((UserStatus)status); + BString statusMsg; + if (msg->FindString("message", &statusMsg) == B_OK) + contact->SetNotifyPersonalStatus(statusMsg); + } break; } case IM_STATUS_SET: diff --git a/application/views/AccountsMenu.cpp b/application/views/AccountsMenu.cpp index 0dd7005..15a105e 100644 --- a/application/views/AccountsMenu.cpp +++ b/application/views/AccountsMenu.cpp @@ -26,27 +26,35 @@ int32 AccountsMenu::fDefaultSelection = 0; -AccountsMenu::AccountsMenu(const char* name, BMessage msg, BMessage* allMsg) +AccountsMenu::AccountsMenu(const char* name, BMessage msg, BMessage* allMsg, + Server* server) : - BMenu(name), + BPopUpMenu(name), fAccountMessage(msg), - fAllMessage(allMsg) + fAllMessage(allMsg), + fServer(server) { _PopulateMenu(); - SetRadioMode(true); SetLabelFromMarked(true); - - Server* server = ((TheApp*)be_app)->GetMainWindow()->GetServer(); - server->RegisterObserver(this); + fServer->RegisterObserver(this); } +AccountsMenu::AccountsMenu(const char* name, BMessage msg, BMessage* allMsg) + : + AccountsMenu(name, msg, allMsg, + ((TheApp*)be_app)->GetMainWindow()->GetServer()) +{ +} + + + + AccountsMenu::~AccountsMenu() { delete fAllMessage; - Server* server = ((TheApp*)be_app)->GetMainWindow()->GetServer(); - server->UnregisterObserver(this); + fServer->UnregisterObserver(this); } @@ -69,9 +77,6 @@ AccountsMenu::SetDefaultSelection(BMenuItem* item) void AccountsMenu::_PopulateMenu() { - BFont font; - GetFont(&font); - // Add 'all' item if missing if (fAllMessage != NULL && FindItem(B_TRANSLATE("All")) == NULL) { BBitmap* icon = _EnsureAsteriskIcon(); @@ -79,8 +84,7 @@ AccountsMenu::_PopulateMenu() icon, 0, 0, false)); } - Server* server = ((TheApp*)be_app)->GetMainWindow()->GetServer(); - AccountInstances accounts = server->GetActiveAccounts(); + AccountInstances accounts = fServer->GetActiveAccounts(); // Add protocol item if not already in menu for (int i = 0; i < accounts.CountItems(); i++) { @@ -94,7 +98,7 @@ AccountsMenu::_PopulateMenu() if (FindItem(label.String()) != NULL) continue; - ProtocolLooper* looper = server->GetProtocolLooper(instance); + ProtocolLooper* looper = fServer->GetProtocolLooper(instance); BBitmap* icon = _EnsureProtocolIcon(label.String(), looper); BMessage* message = new BMessage(fAccountMessage); @@ -132,7 +136,6 @@ BBitmap* AccountsMenu::_EnsureProtocolIcon(const char* label, ProtocolLooper* looper) { BFont font; - GetFont(&font); BBitmap* icon = ImageCache::Get()->GetImage(label); if (icon == NULL && looper != NULL && looper->Protocol()->Icon() != NULL) { @@ -148,7 +151,6 @@ BBitmap* AccountsMenu::_EnsureAsteriskIcon() { BFont font; - GetFont(&font); BBitmap* icon = ImageCache::Get()->GetImage("kAsteriskScaled"); if (icon == NULL) { diff --git a/application/views/AccountsMenu.h b/application/views/AccountsMenu.h index 0842129..236ddd6 100644 --- a/application/views/AccountsMenu.h +++ b/application/views/AccountsMenu.h @@ -5,15 +5,18 @@ #ifndef _ACCOUNTS_MENU_H #define _ACCOUNTS_MENU_H -#include +#include #include "Observer.h" class ProtocolLooper; +class Server; -class AccountsMenu : public BMenu, public Observer { +class AccountsMenu : public BPopUpMenu, public Observer { public: + AccountsMenu(const char* name, BMessage msg, + BMessage* allMsg, Server* server); AccountsMenu(const char* name, BMessage msg, BMessage* allMsg = NULL); ~AccountsMenu(); @@ -33,6 +36,7 @@ private: BMessage fAccountMessage; BMessage* fAllMessage; static int32 fDefaultSelection; + Server* fServer; }; #endif // _ACCOUNTS_MENU_H diff --git a/application/views/NicknameTextControl.cpp b/application/views/NicknameTextControl.cpp deleted file mode 100644 index 211fb53..0000000 --- a/application/views/NicknameTextControl.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2009, Pier Luigi Fiorini. All rights reserved. - * Distributed under the terms of the MIT License. - * - * Authors: - * Pier Luigi Fiorini, pierluigi.fiorini@gmail.com - */ - -#include "AppConstants.h" -#include "NicknameTextControl.h" - -#include - - -NicknameTextControl::NicknameTextControl(const char* name, BMessage* message) - : BTextView(name, B_WILL_DRAW) -{ - SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); -} - -/* -void -NicknameTextControl::Draw(BRect updateRect) -{ -// BRect rect(Bounds()); - -// FillRect(rect); -} -*/ diff --git a/application/views/NicknameTextControl.h b/application/views/NicknameTextControl.h deleted file mode 100644 index a815e23..0000000 --- a/application/views/NicknameTextControl.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2009, Pier Luigi Fiorini. All rights reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _NICKNAME_TEXT_CONTROL_H -#define _NICKNAME_TEXT_CONTROL_H - -#include - -class NicknameTextControl : public BTextView { -public: - NicknameTextControl(const char* name, BMessage* message); - -// virtual void Draw(BRect updateRect); -}; - -#endif // _NICKNAME_TEXT_CONTROL_H diff --git a/application/views/ReplicantStatusView.cpp b/application/views/ReplicantStatusView.cpp index 35124ba..7f65592 100644 --- a/application/views/ReplicantStatusView.cpp +++ b/application/views/ReplicantStatusView.cpp @@ -32,7 +32,6 @@ #include "AppMessages.h" #include "AppPreferences.h" #include "ChatProtocolMessages.h" -#include "NicknameTextControl.h" #include "ReplicantMenuItem.h" #include "Utils.h" diff --git a/application/views/StatusView.cpp b/application/views/StatusView.cpp index 0028697..291ac23 100644 --- a/application/views/StatusView.cpp +++ b/application/views/StatusView.cpp @@ -1,9 +1,11 @@ /* * Copyright 2009, Pier Luigi Fiorini. All rights reserved. + * Copyright 2021, Jaidyn Levesque. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: * Pier Luigi Fiorini, pierluigi.fiorini@gmail.com + * Jaidyn Levesque, jadedctrl@teknik.io */ #include "StatusView.h" @@ -16,30 +18,36 @@ #include #include #include +#include #include #include "AccountManager.h" +#include "AccountsMenu.h" #include "ChatProtocolMessages.h" +#include "Contact.h" #include "ImageCache.h" -#include "NicknameTextControl.h" +#include "NotifyMessage.h" #include "Server.h" #include "StatusMenuItem.h" #include "Utils.h" -const int32 kSetNickname = 'SVnk'; -const int32 kSelectAllAccounts = 'SVaa'; const int32 kSelectAccount = 'SVsa'; +const int32 kSetNick = 'SVsn'; StatusView::StatusView(const char* name, Server* server) : BView(name, B_WILL_DRAW), - fServer(server) + fServer(server), + fAccount(-1) { // Nick name - fNickname = new NicknameTextControl("Nickname", - new BMessage(kSetNickname)); + fNickname = new EnterTextView("nicknameTextView"); + fNickname->MakeEditable(true); + fNickname->MakeResizable(true); + fNickname->SetTarget(this); + fNickname->SetMessage(BMessage(kSetNick), "nick"); // Status menu fStatusMenu = new BPopUpMenu("-"); @@ -76,12 +84,12 @@ StatusView::StatusView(const char* name, Server* server) fAvatar->SetBitmap(ImageCache::Get()->GetImage("kPersonIcon")); // Changing the account used - fAccountsMenu = new BPopUpMenu("statusAccountsMenu", true, false); + fAccountsMenu = new AccountsMenu("statusAccountsMenu", + BMessage(kSelectAccount), new BMessage(kSelectAccount), fServer); fAccountsButton = new MenuButton("statusAccountsButton", "", new BMessage()); fAccountsButton->SetMenu(fAccountsMenu); - _PopulateAccountMenu(); - BMessage selected(kSelectAllAccounts); + BMessage selected(kSelectAccount); MessageReceived(&selected); // Set layout @@ -111,36 +119,45 @@ void StatusView::MessageReceived(BMessage* msg) { switch (msg->what) { - case kSetNickname: + case kSetNick: { - AccountManager* accountManager = AccountManager::Get(); - accountManager->SetNickname(fNickname->Text()); + BString nick; + if (msg->FindString("nick", &nick) == B_OK) + AccountManager::Get()->SetNickname(nick, fAccount); + _SetToAccount(); break; } case kSetStatus: { int32 status; - if (msg->FindInt32("status", &status) != B_OK) - return; - - AccountManager* accountManager = AccountManager::Get(); - accountManager->SetStatus((UserStatus)status, ""); + if (msg->FindInt32("status", &status) == B_OK) + AccountManager::Get()->SetStatus((UserStatus)status, "", + fAccount); + _SetToAccount(); break; } - case kSelectAllAccounts: case kSelectAccount: { - int32 index = msg->FindInt32("index"); + int32 index = msg->GetInt32("index", 0); BitmapMenuItem* item = (BitmapMenuItem*)fAccountsMenu->ItemAt(index); + + // Set button icon/label + fAccountsButton->SetLabel(""); BBitmap* bitmap = item->Bitmap(); fAccountsButton->SetIcon(bitmap); + if (bitmap == NULL) { + char label[2] = { item->Label()[0], '\0' }; + fAccountsButton->SetLabel(label); + } + + fAccount = msg->GetInt64("instance", -1); + _SetToAccount(); break; } - case IM_MESSAGE: - { + case IM_MESSAGE: { int32 im_what = msg->GetInt32("im_what", 0); - if (im_what == IM_PROTOCOL_DISABLE || im_what == IM_PROTOCOL_READY) - _PopulateAccountMenu(); + if (im_what == IM_PROTOCOL_READY || im_what == IM_PROTOCOL_DISABLE) + fAccountsMenu->SetTargetForItems(this); break; } default: @@ -149,15 +166,57 @@ StatusView::MessageReceived(BMessage* msg) } +void +StatusView::ObserveString(int32 what, BString str) +{ + if (what == STR_CONTACT_NAME || what == STR_PERSONAL_STATUS) + _SetToAccount(); +} + + +void +StatusView::ObserveInteger(int32 what, int32 value) +{ + if (what == INT_ACCOUNT_STATUS || what == INT_CONTACT_STATUS) + _SetToAccount(); +} + + +void +StatusView::ObservePointer(int32 what, void* ptr) +{ + if (what == PTR_AVATAR_BITMAP) + _SetToAccount(); +} + + +void +StatusView::_SetToAccount() +{ + int64 instance = fAccount; + if (instance == -1) + instance = fServer->GetActiveAccounts().ValueAt(0); + + ProtocolLooper* looper = fServer->GetProtocolLooper(instance); + if (looper == NULL || looper->GetOwnContact() == NULL) + return; + Contact* contact = looper->GetOwnContact(); + + _SetAvatarIcon(contact->AvatarBitmap()); + _SetName(contact->GetName()); + _SetStatus(contact->GetNotifyStatus()); +} + + void -StatusView::SetName(BString name) +StatusView::_SetName(BString name) { fNickname->SetText(name.String()); } void -StatusView::SetStatus(UserStatus status) +StatusView::_SetStatus(UserStatus status) { for (int32 i = 0; i < fStatusMenu->CountItems(); i++) { StatusMenuItem* item @@ -169,61 +228,7 @@ StatusView::SetStatus(UserStatus status) void -StatusView::SetAvatarIcon(const BBitmap* bitmap) +StatusView::_SetAvatarIcon(const BBitmap* bitmap) { - // We don't want the default avatar to override a real one - if (bitmap != ImageCache::Get()->GetImage("kPersonIcon")) - fAvatar->SetBitmap(bitmap); -} - - -void -StatusView::_PopulateAccountMenu() -{ - AccountInstances accounts = fServer->GetActiveAccounts(); - BFont font; - GetFont(&font); - - if (fAccountsMenu->FindItem(B_TRANSLATE("All")) == NULL) { - BBitmap* icon = ImageCache::Get()->GetImage("kAsteriskIcon"); - BBitmap* resized = RescaleBitmap(icon, font.Size(), font.Size()); - - fAccountsMenu->AddItem(new BitmapMenuItem(B_TRANSLATE("All"), - new BMessage(kSelectAllAccounts), resized)); - fAccountsMenu->FindItem(B_TRANSLATE("All"))->SetMarked(true); - } - - // Add unpopulated entries - for (int i = 0; i < accounts.CountItems(); i++) { - BString name = accounts.KeyAt(i); - int64 instance = accounts.ValueAt(i); - ProtocolLooper* looper = fServer->GetProtocolLooper(instance); - if (looper == NULL || looper->Protocol() == NULL - || fAccountsMenu->FindItem(name.String()) != NULL) - continue; - - BBitmap* icon = looper->Protocol()->Icon(); - BBitmap* resized = RescaleBitmap(icon, font.Size(), font.Size()); - - BMessage* selected = new BMessage(kSelectAccount); - selected->AddInt64("instance", instance); - fAccountsMenu->AddItem(new BitmapMenuItem(name.String(), selected, - resized)); - } - - // Remove disabled accounts - if (fAccountsMenu->CountItems() - 1 > accounts.CountItems()) { - fAccountsMenu->FindMarked()->SetMarked(false); - fAccountsMenu->ItemAt(0)->SetMarked(true); - BMessage select(kSelectAllAccounts); - MessageReceived(&select); - - for (int i = 0; i < fAccountsMenu->CountItems(); i++) { - bool found = false; - accounts.ValueFor(BString(fAccountsMenu->ItemAt(i)->Label()), &found); - if (found == false) - fAccountsMenu->RemoveItem(i); - } - } - fAccountsMenu->SetTargetForItems(this); + fAvatar->SetBitmap(bitmap); } diff --git a/application/views/StatusView.h b/application/views/StatusView.h index a41a2d1..9f82ddd 100644 --- a/application/views/StatusView.h +++ b/application/views/StatusView.h @@ -1,5 +1,6 @@ /* * Copyright 2009, Pier Luigi Fiorini. All rights reserved. + * Copyright 2021, Jaidyn Levesque. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _STATUS_VIEW_H @@ -8,34 +9,42 @@ #include #include "AppConstants.h" +#include "Observer.h" class BPopUpMenu; +class AccountsMenu; class BitmapView; +class EnterTextView; class MenuButton; -class NicknameTextControl; class Server; -class StatusView : public BView { +class StatusView : public BView, public Observer { public: StatusView(const char* name, Server* server); virtual void AttachedToWindow(); virtual void MessageReceived(BMessage* msg); - void SetName(BString name); - void SetStatus(UserStatus status); - void SetAvatarIcon(const BBitmap* bitmap); + virtual void ObserveString(int32 what, BString str); + virtual void ObserveInteger(int32 what, int32 value); + virtual void ObservePointer(int32 what, void* ptr); + private: - void _PopulateAccountMenu(); + void _SetName(BString name); + void _SetStatus(UserStatus status); + void _SetAvatarIcon(const BBitmap* bitmap); - NicknameTextControl* fNickname; + void _SetToAccount(); + + EnterTextView* fNickname; BitmapView* fAvatar; BPopUpMenu* fStatusMenu; MenuButton* fAccountsButton; - BPopUpMenu* fAccountsMenu; + AccountsMenu* fAccountsMenu; + int64 fAccount; Server* fServer; }; diff --git a/application/windows/MainWindow.cpp b/application/windows/MainWindow.cpp index 5f40aee..b283daa 100644 --- a/application/windows/MainWindow.cpp +++ b/application/windows/MainWindow.cpp @@ -234,17 +234,12 @@ MainWindow::ImMessage(BMessage* msg) switch (im_what) { case IM_OWN_CONTACT_INFO: { - BString name; - if (msg->FindString("name", &name) == B_OK) - fStatusView->SetName(msg->FindString("name")); - int64 instance; if (msg->FindInt64("instance", &instance) == B_OK) { ProtocolLooper* looper = fServer->GetProtocolLooper(instance); if (looper != NULL) { Contact* contact = looper->GetOwnContact(); - contact->RegisterObserver(this); - fStatusView->SetAvatarIcon(contact->AvatarBitmap()); + contact->RegisterObserver(fStatusView); } } break; @@ -293,28 +288,6 @@ MainWindow::ImMessage(BMessage* msg) } -void -MainWindow::ObserveInteger(int32 what, int32 val) -{ - switch (what) { - case INT_ACCOUNT_STATUS: - fStatusView->SetStatus((UserStatus)val); - break; - } -} - - -void -MainWindow::ObservePointer(int32 what, void* ptr) -{ - if (what == PTR_AVATAR_BITMAP) { - BBitmap* bmp = (BBitmap*)ptr; - if (bmp != NULL) - fStatusView->SetAvatarIcon(bmp); - } -} - - void MainWindow::WorkspaceActivated(int32 workspace, bool active) { diff --git a/application/windows/MainWindow.h b/application/windows/MainWindow.h index 847efcb..413d71d 100644 --- a/application/windows/MainWindow.h +++ b/application/windows/MainWindow.h @@ -9,8 +9,6 @@ #include -#include "Observer.h" - class BSplitView; class BTextView; @@ -25,7 +23,7 @@ class Server; class StatusView; -class MainWindow: public BWindow, public Observer { +class MainWindow: public BWindow { public: MainWindow(); @@ -35,10 +33,6 @@ public: virtual void MessageReceived(BMessage* message); void ImMessage(BMessage* msg); - // Observer inheritance - void ObserveInteger(int32 what, int32 val); - void ObservePointer(int32 what, void* ptr); - virtual void WorkspaceActivated(int32 workspace, bool active);