2010-05-07 04:47:10 -05:00
|
|
|
/*
|
2011-12-03 16:38:03 -06:00
|
|
|
* Copyright 2009-2011, Andrea Anzani. All rights reserved.
|
|
|
|
* Copyright 2009-2011, Pier Luigi Fiorini. All rights reserved.
|
2021-06-15 23:29:38 -05:00
|
|
|
* Copyright 2021, Jaidyn Levesque. All rights reserved.
|
2010-05-07 04:47:10 -05:00
|
|
|
* Distributed under the terms of the MIT License.
|
|
|
|
*
|
|
|
|
* Authors:
|
|
|
|
* Andrea Anzani, andrea.anzani@gmail.com
|
|
|
|
* Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
|
2021-06-15 23:29:38 -05:00
|
|
|
* Jaidyn Levesque, jadedctrl@teknik.io
|
2010-05-07 04:47:10 -05:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <Application.h>
|
|
|
|
#include <Alert.h>
|
2021-07-19 09:54:27 -05:00
|
|
|
#include <Catalog.h>
|
2021-05-25 13:57:53 -05:00
|
|
|
#include <LayoutBuilder.h>
|
|
|
|
#include <MenuBar.h>
|
2010-05-07 04:47:10 -05:00
|
|
|
#include <TranslationUtils.h>
|
|
|
|
|
2021-08-06 14:14:14 -05:00
|
|
|
#include "AccountDialog.h"
|
2011-12-14 17:36:27 -06:00
|
|
|
#include "AccountManager.h"
|
2021-08-06 12:21:17 -05:00
|
|
|
#include "AccountsWindow.h"
|
2021-06-20 12:44:20 -05:00
|
|
|
#include "AppMessages.h"
|
|
|
|
#include "AppPreferences.h"
|
2021-06-22 01:06:00 -05:00
|
|
|
#include "Cardie.h"
|
2021-08-06 14:14:14 -05:00
|
|
|
#include "ChatProtocolAddOn.h"
|
2021-06-20 12:44:20 -05:00
|
|
|
#include "ChatProtocolMessages.h"
|
2021-05-27 11:15:30 -05:00
|
|
|
#include "ConversationItem.h"
|
|
|
|
#include "ConversationListView.h"
|
2021-05-28 22:26:32 -05:00
|
|
|
#include "ConversationView.h"
|
2010-05-07 04:47:10 -05:00
|
|
|
#include "MainWindow.h"
|
2021-05-30 12:30:26 -05:00
|
|
|
#include "NotifyMessage.h"
|
Explicitly tie Conversations, Contacts, and Users to their ProtocolLoopers
Previously, all Conversations/Contacts/Users were stored in the Server,
each in their respective KeyMaps, identified solely by their
identifiers. This leads to the glaring problem of overlap― if the user
has multiple accounts, some users/rooms might be used or present in multiple
accounts at the same time.
Now, each accounts' Contacts, Conversations, and Users are stored in
its ProtocolLooper, making this overlap impossible. An oversight of only
allowing one user identifier to be stored (fMySelf) in Server was also fixed
this way.
This is the bulk of the work required for multi-account support― now,
the user can join the same XMPP room on two seperate accounts, and it
works perfectly.
2021-06-10 15:16:43 -05:00
|
|
|
#include "PreferencesWindow.h"
|
2021-08-06 14:14:14 -05:00
|
|
|
#include "ProtocolManager.h"
|
|
|
|
#include "ProtocolSettings.h"
|
2011-12-14 17:36:27 -06:00
|
|
|
#include "ReplicantStatusView.h"
|
2021-06-19 18:25:58 -05:00
|
|
|
#include "RosterEditWindow.h"
|
2021-05-26 07:48:25 -05:00
|
|
|
#include "RosterWindow.h"
|
2010-05-07 04:47:10 -05:00
|
|
|
#include "StatusView.h"
|
2021-06-18 01:13:02 -05:00
|
|
|
#include "TemplateWindow.h"
|
2010-05-07 04:47:10 -05:00
|
|
|
|
2012-09-25 16:45:29 -05:00
|
|
|
|
2021-07-19 09:54:27 -05:00
|
|
|
#undef B_TRANSLATION_CONTEXT
|
|
|
|
#define B_TRANSLATION_CONTEXT "MainWindow"
|
|
|
|
|
|
|
|
|
2010-05-19 17:28:26 -05:00
|
|
|
const uint32 kLogin = 'LOGI';
|
2010-05-12 13:15:21 -05:00
|
|
|
|
2010-05-07 04:47:10 -05:00
|
|
|
|
2010-05-16 16:02:50 -05:00
|
|
|
MainWindow::MainWindow()
|
2010-05-19 17:28:26 -05:00
|
|
|
:
|
2021-07-28 19:25:55 -05:00
|
|
|
BWindow(AppPreferences::Get()->MainWindowRect,
|
|
|
|
B_TRANSLATE_SYSTEM_NAME(APP_NAME), B_TITLED_WINDOW, 0),
|
2021-05-30 17:12:41 -05:00
|
|
|
fWorkspaceChanged(false),
|
2021-05-30 20:45:24 -05:00
|
|
|
fConversation(NULL),
|
2021-06-12 16:13:52 -05:00
|
|
|
fRosterWindow(NULL),
|
|
|
|
fServer(NULL)
|
2010-05-22 09:18:11 -05:00
|
|
|
{
|
2010-05-16 16:02:50 -05:00
|
|
|
// Filter messages using Server
|
|
|
|
fServer = new Server();
|
|
|
|
AddFilter(fServer);
|
2010-05-07 04:47:10 -05:00
|
|
|
|
2021-08-02 21:59:44 -05:00
|
|
|
_InitInterface();
|
|
|
|
|
2011-12-14 17:36:27 -06:00
|
|
|
//TODO check for errors here
|
2012-03-03 20:27:16 -06:00
|
|
|
ReplicantStatusView::InstallReplicant();
|
2010-05-07 04:47:10 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-05-16 16:02:50 -05:00
|
|
|
void
|
|
|
|
MainWindow::Start()
|
|
|
|
{
|
|
|
|
// Login all accounts
|
|
|
|
fServer->LoginAll();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-05-07 04:47:10 -05:00
|
|
|
bool
|
|
|
|
MainWindow::QuitRequested()
|
|
|
|
{
|
2015-10-01 23:17:54 -05:00
|
|
|
int32 button_index = 0;
|
2021-07-28 19:10:09 -05:00
|
|
|
if(!AppPreferences::Get()->DisableQuitConfirm)
|
2015-10-01 23:17:54 -05:00
|
|
|
{
|
2021-07-19 09:54:27 -05:00
|
|
|
BAlert* alert = new BAlert(B_TRANSLATE("Closing"),
|
|
|
|
B_TRANSLATE("Are you sure you want to quit?"),
|
|
|
|
B_TRANSLATE("Yes"), B_TRANSLATE("No"), NULL, B_WIDTH_AS_USUAL,
|
|
|
|
B_OFFSET_SPACING, B_WARNING_ALERT);
|
2015-10-01 23:17:54 -05:00
|
|
|
alert->SetShortcut(0, B_ESCAPE);
|
|
|
|
button_index = alert->Go();
|
|
|
|
}
|
|
|
|
|
2021-07-30 16:14:21 -05:00
|
|
|
AppPreferences::Get()->MainWindowListWeight = fSplitView->ItemWeight(0);
|
|
|
|
AppPreferences::Get()->MainWindowChatWeight = fSplitView->ItemWeight(1);
|
2021-07-31 11:15:51 -05:00
|
|
|
AppPreferences::Get()->MainWindowRect = Frame();
|
2021-07-28 19:25:55 -05:00
|
|
|
|
2015-09-29 03:59:40 -05:00
|
|
|
if(button_index == 0) {
|
|
|
|
fServer->Quit();
|
2021-06-20 12:44:20 -05:00
|
|
|
AppPreferences::Get()->Save();
|
2015-09-29 03:59:40 -05:00
|
|
|
ReplicantStatusView::RemoveReplicant();
|
|
|
|
be_app->PostMessage(B_QUIT_REQUESTED);
|
|
|
|
return true;
|
2021-06-11 17:24:04 -05:00
|
|
|
} else
|
2015-09-29 03:59:40 -05:00
|
|
|
return false;
|
2010-05-07 04:47:10 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
MainWindow::MessageReceived(BMessage* message)
|
|
|
|
{
|
2010-05-16 16:02:50 -05:00
|
|
|
switch (message->what) {
|
2021-06-20 12:44:20 -05:00
|
|
|
case APP_SHOW_SETTINGS:
|
2012-06-07 11:46:07 -05:00
|
|
|
{
|
Explicitly tie Conversations, Contacts, and Users to their ProtocolLoopers
Previously, all Conversations/Contacts/Users were stored in the Server,
each in their respective KeyMaps, identified solely by their
identifiers. This leads to the glaring problem of overlap― if the user
has multiple accounts, some users/rooms might be used or present in multiple
accounts at the same time.
Now, each accounts' Contacts, Conversations, and Users are stored in
its ProtocolLooper, making this overlap impossible. An oversight of only
allowing one user identifier to be stored (fMySelf) in Server was also fixed
this way.
This is the bulk of the work required for multi-account support― now,
the user can join the same XMPP room on two seperate accounts, and it
works perfectly.
2021-06-10 15:16:43 -05:00
|
|
|
PreferencesWindow* win = new PreferencesWindow();
|
|
|
|
win->Show();
|
2010-05-07 04:47:10 -05:00
|
|
|
break;
|
|
|
|
}
|
2021-08-06 12:21:17 -05:00
|
|
|
case APP_SHOW_ACCOUNTS:
|
|
|
|
{
|
|
|
|
AccountsWindow* win = new AccountsWindow();
|
|
|
|
win->Show();
|
|
|
|
break;
|
|
|
|
}
|
2021-08-06 14:14:14 -05:00
|
|
|
case APP_EDIT_ACCOUNT:
|
|
|
|
{
|
|
|
|
void* settings = NULL;
|
2021-08-07 17:37:16 -05:00
|
|
|
BString account = message->FindString("account");
|
2021-08-06 14:14:14 -05:00
|
|
|
message->FindPointer("settings", &settings);
|
|
|
|
|
2021-08-07 17:37:16 -05:00
|
|
|
if (account.IsEmpty() == false && settings != NULL) {
|
2021-08-06 14:14:14 -05:00
|
|
|
AccountDialog* win = new AccountDialog("Editing account",
|
|
|
|
(ProtocolSettings*)settings, account.String());
|
|
|
|
win->Show();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2021-08-07 17:37:16 -05:00
|
|
|
case APP_TOGGLE_ACCOUNT:
|
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2021-06-20 12:44:20 -05:00
|
|
|
case APP_NEW_CHAT:
|
2012-06-07 11:46:07 -05:00
|
|
|
{
|
2021-06-08 21:43:30 -05:00
|
|
|
BMessage* newMsg = new BMessage(IM_MESSAGE);
|
|
|
|
newMsg->AddInt32("im_what", IM_CREATE_CHAT);
|
|
|
|
|
2021-07-19 09:54:27 -05:00
|
|
|
fRosterWindow = new RosterWindow(B_TRANSLATE("Invite contact to "
|
|
|
|
"chat" B_UTF8_ELLIPSIS), newMsg, new BMessenger(this), fServer);
|
2021-05-30 17:12:41 -05:00
|
|
|
fRosterWindow->Show();
|
2010-05-16 16:02:50 -05:00
|
|
|
break;
|
|
|
|
}
|
2021-06-20 12:44:20 -05:00
|
|
|
case APP_NEW_ROOM:
|
2021-06-18 01:13:02 -05:00
|
|
|
{
|
|
|
|
BMessage* createMsg = new BMessage(IM_MESSAGE);
|
|
|
|
createMsg->AddInt32("im_what", IM_CREATE_ROOM);
|
2011-12-14 17:36:27 -06:00
|
|
|
|
2021-07-19 09:54:27 -05:00
|
|
|
TemplateWindow* win = new TemplateWindow(B_TRANSLATE("Create room"),
|
2021-07-05 13:40:59 -05:00
|
|
|
"create_room", createMsg, fServer);
|
2021-06-18 01:13:02 -05:00
|
|
|
win->Show();
|
|
|
|
break;
|
|
|
|
}
|
2021-06-20 12:44:20 -05:00
|
|
|
case APP_JOIN_ROOM:
|
2021-06-01 21:43:19 -05:00
|
|
|
{
|
2021-06-19 18:51:45 -05:00
|
|
|
BMessage* joinMsg = new BMessage(IM_MESSAGE);
|
|
|
|
joinMsg->AddInt32("im_what", IM_JOIN_ROOM);
|
|
|
|
|
2021-07-19 09:54:27 -05:00
|
|
|
TemplateWindow* win = new TemplateWindow(B_TRANSLATE("Join a room"),
|
2021-07-05 13:40:59 -05:00
|
|
|
"join_room", joinMsg, fServer);
|
2021-06-01 21:43:19 -05:00
|
|
|
win->Show();
|
|
|
|
break;
|
|
|
|
}
|
2021-06-20 12:44:20 -05:00
|
|
|
case APP_SEND_INVITE:
|
2021-06-08 21:43:30 -05:00
|
|
|
{
|
|
|
|
if (fConversation == NULL)
|
|
|
|
break;
|
|
|
|
BString chat_id = fConversation->GetId();
|
|
|
|
|
|
|
|
BMessage* invite = new BMessage(IM_MESSAGE);
|
|
|
|
invite->AddInt32("im_what", IM_ROOM_SEND_INVITE);
|
|
|
|
invite->AddString("chat_id", chat_id);
|
|
|
|
|
2021-06-19 00:11:02 -05:00
|
|
|
ProtocolLooper* plooper = fConversation->GetProtocolLooper();
|
|
|
|
BLooper* looper = (BLooper*)plooper;
|
2021-07-19 09:54:27 -05:00
|
|
|
fRosterWindow = new RosterWindow(B_TRANSLATE("Invite contact to "
|
|
|
|
"chat" B_UTF8_ELLIPSIS), invite, new BMessenger(looper), fServer,
|
2021-06-19 00:11:02 -05:00
|
|
|
plooper->GetInstance());
|
2021-06-08 21:43:30 -05:00
|
|
|
|
|
|
|
fRosterWindow->Show();
|
|
|
|
break;
|
|
|
|
}
|
2021-06-20 12:44:20 -05:00
|
|
|
case APP_EDIT_ROSTER:
|
2021-06-19 18:25:58 -05:00
|
|
|
{
|
2021-06-19 22:03:02 -05:00
|
|
|
RosterEditWindow::Get(fServer)->Show();
|
2021-06-19 18:25:58 -05:00
|
|
|
break;
|
|
|
|
}
|
2021-06-20 12:44:20 -05:00
|
|
|
case APP_MOVE_UP:
|
2021-05-30 20:45:24 -05:00
|
|
|
{
|
2021-08-12 15:43:52 -05:00
|
|
|
int32 index = fListView->CurrentSelection();
|
2021-05-30 20:45:24 -05:00
|
|
|
if (index > 0)
|
2021-08-12 15:43:52 -05:00
|
|
|
fListView->Select(index - 1);
|
2021-05-30 20:45:24 -05:00
|
|
|
break;
|
|
|
|
}
|
2021-06-20 12:44:20 -05:00
|
|
|
case APP_MOVE_DOWN:
|
2021-05-30 20:45:24 -05:00
|
|
|
{
|
2021-08-12 15:43:52 -05:00
|
|
|
int32 index = fListView->CurrentSelection();
|
|
|
|
int32 count = fListView->CountItems();
|
2021-05-30 20:45:24 -05:00
|
|
|
if (index < (count - 1))
|
2021-08-12 15:43:52 -05:00
|
|
|
fListView->Select(index + 1);
|
2021-05-30 20:45:24 -05:00
|
|
|
break;
|
|
|
|
}
|
2021-06-20 12:44:20 -05:00
|
|
|
case APP_REPLICANT_STATUS_SET:
|
2011-12-14 17:36:27 -06:00
|
|
|
{
|
|
|
|
int32 status;
|
|
|
|
message->FindInt32("status", &status);
|
|
|
|
AccountManager* accountManager = AccountManager::Get();
|
2021-06-20 12:44:20 -05:00
|
|
|
accountManager->SetStatus((UserStatus)status);
|
2011-12-14 17:36:27 -06:00
|
|
|
break;
|
|
|
|
}
|
2021-06-20 12:44:20 -05:00
|
|
|
case APP_REPLICANT_SHOW_WINDOW:
|
2011-12-14 17:36:27 -06:00
|
|
|
{
|
|
|
|
if (LockLooper()) {
|
|
|
|
SetWorkspaces(B_CURRENT_WORKSPACE);
|
|
|
|
|
|
|
|
if ((IsMinimized() || IsHidden())
|
|
|
|
|| fWorkspaceChanged) {
|
|
|
|
Minimize(false);
|
|
|
|
Show();
|
|
|
|
fWorkspaceChanged = false;
|
|
|
|
} else if ((!IsMinimized() || !IsHidden())
|
|
|
|
|| (!fWorkspaceChanged)) {
|
|
|
|
Minimize(true);
|
|
|
|
}
|
|
|
|
UnlockLooper();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2021-08-06 14:14:14 -05:00
|
|
|
case APP_ACCOUNT_DISABLED: {
|
2021-06-12 16:13:52 -05:00
|
|
|
_ToggleMenuItems();
|
2021-08-06 14:14:14 -05:00
|
|
|
_RefreshAccountsMenu();
|
2021-06-12 16:13:52 -05:00
|
|
|
break;
|
2021-08-06 14:14:14 -05:00
|
|
|
}
|
2010-05-07 04:47:10 -05:00
|
|
|
case IM_MESSAGE:
|
|
|
|
ImMessage(message);
|
|
|
|
break;
|
2010-05-12 13:57:19 -05:00
|
|
|
case B_ABOUT_REQUESTED:
|
|
|
|
be_app->PostMessage(message);
|
|
|
|
break;
|
2010-05-07 04:47:10 -05:00
|
|
|
default:
|
|
|
|
BWindow::MessageReceived(message);
|
2010-05-22 09:18:11 -05:00
|
|
|
}
|
2010-05-07 04:47:10 -05:00
|
|
|
}
|
|
|
|
|
2010-05-16 16:02:50 -05:00
|
|
|
|
2010-05-07 04:47:10 -05:00
|
|
|
void
|
|
|
|
MainWindow::ImMessage(BMessage* msg)
|
2010-05-22 09:18:11 -05:00
|
|
|
{
|
2010-05-07 04:47:10 -05:00
|
|
|
int32 im_what = msg->FindInt32("im_what");
|
2010-05-16 16:02:50 -05:00
|
|
|
switch (im_what) {
|
2010-05-07 04:47:10 -05:00
|
|
|
case IM_OWN_CONTACT_INFO:
|
2010-05-30 03:51:19 -05:00
|
|
|
{
|
2021-07-13 14:43:48 -05:00
|
|
|
int64 instance;
|
|
|
|
if (msg->FindInt64("instance", &instance) == B_OK) {
|
|
|
|
ProtocolLooper* looper = fServer->GetProtocolLooper(instance);
|
|
|
|
if (looper != NULL) {
|
|
|
|
Contact* contact = looper->GetOwnContact();
|
2021-08-03 13:19:25 -05:00
|
|
|
contact->RegisterObserver(fStatusView);
|
2021-07-13 14:43:48 -05:00
|
|
|
}
|
2010-05-07 04:47:10 -05:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2021-06-04 16:32:18 -05:00
|
|
|
case IM_ROOM_JOINED:
|
2021-06-02 16:53:03 -05:00
|
|
|
case IM_ROOM_PARTICIPANTS:
|
2021-06-18 01:30:59 -05:00
|
|
|
case IM_ROOM_CREATED:
|
|
|
|
case IM_CHAT_CREATED:
|
2021-05-27 11:15:30 -05:00
|
|
|
case IM_MESSAGE_RECEIVED:
|
|
|
|
case IM_MESSAGE_SENT:
|
|
|
|
{
|
|
|
|
_EnsureConversationItem(msg);
|
|
|
|
break;
|
|
|
|
}
|
2021-06-04 16:32:18 -05:00
|
|
|
case IM_ROOM_LEFT:
|
|
|
|
{
|
|
|
|
ConversationItem* item = _EnsureConversationItem(msg);
|
|
|
|
if (item == NULL)
|
|
|
|
break;
|
|
|
|
|
2021-06-11 20:33:28 -05:00
|
|
|
delete item->GetConversation();
|
2021-06-04 16:32:18 -05:00
|
|
|
break;
|
|
|
|
}
|
2021-08-08 21:01:42 -05:00
|
|
|
case IM_USER_AVATAR_SET:
|
|
|
|
case IM_USER_STATUS_SET:
|
2021-05-30 17:12:41 -05:00
|
|
|
case IM_CONTACT_INFO:
|
|
|
|
case IM_EXTENDED_CONTACT_INFO:
|
2021-08-08 21:01:42 -05:00
|
|
|
case IM_ROSTER_CONTACT_REMOVED: {
|
2021-06-19 18:25:58 -05:00
|
|
|
if (fRosterWindow != NULL)
|
|
|
|
fRosterWindow->PostMessage(msg);
|
2021-06-19 22:03:02 -05:00
|
|
|
if (RosterEditWindow::Check() == true)
|
|
|
|
RosterEditWindow::Get(fServer)->PostMessage(msg);
|
2021-05-30 17:12:41 -05:00
|
|
|
break;
|
2021-07-28 22:11:42 -05:00
|
|
|
}
|
|
|
|
case IM_PROTOCOL_READY: {
|
|
|
|
if (fConversation == NULL)
|
|
|
|
fChatView->MessageReceived(msg);
|
2021-08-02 21:59:44 -05:00
|
|
|
fStatusView->MessageReceived(msg);
|
2021-08-06 14:14:14 -05:00
|
|
|
_ToggleMenuItems();
|
|
|
|
_RefreshAccountsMenu();
|
2021-06-12 16:13:52 -05:00
|
|
|
break;
|
2021-07-28 22:11:42 -05:00
|
|
|
}
|
2021-08-02 21:59:44 -05:00
|
|
|
case IM_PROTOCOL_DISABLE:
|
|
|
|
fStatusView->MessageReceived(msg);
|
|
|
|
break;
|
2010-05-07 04:47:10 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-05-27 11:15:30 -05:00
|
|
|
void
|
2021-05-30 12:30:26 -05:00
|
|
|
MainWindow::WorkspaceActivated(int32 workspace, bool active)
|
2021-05-27 11:15:30 -05:00
|
|
|
{
|
2021-05-30 12:30:26 -05:00
|
|
|
if (active)
|
|
|
|
fWorkspaceChanged = false;
|
2021-05-27 11:15:30 -05:00
|
|
|
else
|
2021-05-30 12:30:26 -05:00
|
|
|
fWorkspaceChanged = true;
|
2021-05-27 11:15:30 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-12-14 17:36:27 -06:00
|
|
|
void
|
2021-05-30 12:30:26 -05:00
|
|
|
MainWindow::SetConversation(Conversation* chat)
|
2011-12-14 17:36:27 -06:00
|
|
|
{
|
2021-08-12 15:43:52 -05:00
|
|
|
fConversation = chat;
|
2021-05-30 20:45:24 -05:00
|
|
|
if (chat != NULL) {
|
2021-08-12 15:43:52 -05:00
|
|
|
SetConversationView(chat->GetView());
|
2021-06-06 18:06:46 -05:00
|
|
|
|
|
|
|
BString title(chat->GetName());
|
2021-06-22 01:06:00 -05:00
|
|
|
title << " ― " << APP_NAME;
|
2021-06-06 18:06:46 -05:00
|
|
|
SetTitle(title.String());
|
2021-05-30 20:45:24 -05:00
|
|
|
}
|
2021-08-12 15:43:52 -05:00
|
|
|
else {
|
|
|
|
SetConversationView(fBackupChatView);
|
2021-06-22 01:06:00 -05:00
|
|
|
SetTitle(APP_NAME);
|
2021-08-12 15:43:52 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
MainWindow::SetConversationView(ConversationView* chatView)
|
|
|
|
{
|
|
|
|
// Save split weights
|
|
|
|
float weightChat = fRightView->ItemWeight((int32)0);
|
|
|
|
float weightSend = fRightView->ItemWeight((int32)1);
|
|
|
|
float horizChat, horizList, vertChat, vertSend;
|
|
|
|
fChatView->GetWeights(&horizChat, &horizList, &vertChat, &vertSend);
|
|
|
|
|
|
|
|
fRightView->RemoveChild(fRightView->FindView("chatView"));
|
|
|
|
fChatView = chatView;
|
2021-05-30 12:30:26 -05:00
|
|
|
|
|
|
|
fRightView->AddChild(fChatView, 9);
|
2021-05-30 13:45:08 -05:00
|
|
|
|
2021-06-16 05:03:10 -05:00
|
|
|
// Remove "Protocol" menu
|
|
|
|
BMenuItem* chatMenuItem = fMenuBar->FindItem("Protocol");
|
|
|
|
BMenu* chatMenu;
|
|
|
|
if (chatMenuItem != NULL && (chatMenu = chatMenuItem->Submenu()) != NULL)
|
|
|
|
fMenuBar->RemoveItem(chatMenu);
|
|
|
|
|
|
|
|
// Add and populate "Protocol" menu, if appropriate
|
|
|
|
if (fConversation != NULL) {
|
|
|
|
ProtocolLooper* looper = fConversation->GetProtocolLooper();
|
2021-06-20 01:24:34 -05:00
|
|
|
BObjectList<BMessage> menuItems = looper->Protocol()->MenuBarItems();
|
2021-06-16 05:03:10 -05:00
|
|
|
for (int i = 0; i < menuItems.CountItems(); i++) {
|
|
|
|
BMessage* itemMsg = menuItems.ItemAt(i);
|
|
|
|
BMessage* msg = new BMessage(*itemMsg);
|
|
|
|
BMessage toSend;
|
|
|
|
msg->FindMessage("_msg", &toSend);
|
|
|
|
toSend.AddString("chat_id", fConversation->GetId());
|
|
|
|
toSend.AddInt64("instance", looper->GetInstance());
|
|
|
|
msg->ReplaceMessage("_msg", &toSend);
|
|
|
|
|
|
|
|
BMenuItem* item = new BMenuItem(msg);
|
|
|
|
if (item == NULL)
|
|
|
|
continue;
|
|
|
|
if (msg->GetBool("x_to_protocol", true) == true)
|
|
|
|
item->SetTarget(looper);
|
|
|
|
else
|
|
|
|
item->SetTarget(this);
|
|
|
|
chatMenu->AddItem(item);
|
|
|
|
}
|
|
|
|
}
|
2021-07-30 16:14:21 -05:00
|
|
|
|
2021-07-31 11:15:51 -05:00
|
|
|
// Apply saved weights
|
2021-07-30 16:14:21 -05:00
|
|
|
fSplitView->SetItemWeight(0, AppPreferences::Get()->MainWindowListWeight, true);
|
|
|
|
fSplitView->SetItemWeight(1, AppPreferences::Get()->MainWindowChatWeight, true);
|
2021-07-31 11:15:51 -05:00
|
|
|
fChatView->SetWeights(horizChat, horizList, vertChat, vertSend);
|
|
|
|
if (weightChat * weightSend != 0) {
|
|
|
|
fRightView->SetItemWeight(0, weightChat, true);
|
|
|
|
fRightView->SetItemWeight(1, weightSend, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Save ChatView weights to settings
|
|
|
|
AppPreferences::Get()->ChatViewHorizChatWeight = horizChat;
|
|
|
|
AppPreferences::Get()->ChatViewHorizListWeight = horizList;
|
|
|
|
AppPreferences::Get()->ChatViewVertChatWeight = vertChat;
|
|
|
|
AppPreferences::Get()->ChatViewVertSendWeight = vertSend;
|
2021-05-30 12:30:26 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-06-11 20:33:28 -05:00
|
|
|
void
|
|
|
|
MainWindow::RemoveConversation(Conversation* chat)
|
|
|
|
{
|
2021-08-12 15:43:52 -05:00
|
|
|
SetConversation(NULL);
|
|
|
|
|
|
|
|
int32 index = fListView->IndexOf(chat->GetListItem());
|
2021-06-11 20:33:28 -05:00
|
|
|
if (index > 0)
|
|
|
|
index--;
|
|
|
|
|
|
|
|
fListView->RemoveConversation(chat);
|
|
|
|
|
2021-08-12 15:43:52 -05:00
|
|
|
if (fListView->CountItems() > 0)
|
|
|
|
fListView->Select(index);
|
2021-07-28 19:33:39 -05:00
|
|
|
_ToggleMenuItems();
|
2021-06-11 20:33:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-07-25 14:42:38 -05:00
|
|
|
void
|
|
|
|
MainWindow::SortConversation(Conversation* chat)
|
|
|
|
{
|
|
|
|
fListView->SortConversation(chat);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-05-30 12:30:26 -05:00
|
|
|
void
|
|
|
|
MainWindow::_InitInterface()
|
|
|
|
{
|
|
|
|
// Left side of window, Roomlist + Status
|
|
|
|
fListView = new ConversationListView("roomList");
|
2021-08-02 21:59:44 -05:00
|
|
|
fStatusView = new StatusView("statusView", fServer);
|
2021-07-30 16:14:21 -05:00
|
|
|
fSplitView = new BSplitView(B_HORIZONTAL, 0);
|
2021-05-30 12:30:26 -05:00
|
|
|
|
|
|
|
// Right-side of window, Chat + Textbox
|
|
|
|
fRightView = new BSplitView(B_VERTICAL, 0);
|
2021-08-12 15:43:52 -05:00
|
|
|
fBackupChatView = new ConversationView();
|
|
|
|
fChatView = fBackupChatView;
|
2021-05-30 12:30:26 -05:00
|
|
|
|
2021-07-31 11:15:51 -05:00
|
|
|
// Load weights from settings
|
|
|
|
float horizChat, horizList, vertChat, vertSend;
|
|
|
|
horizChat = AppPreferences::Get()->ChatViewHorizChatWeight;
|
|
|
|
horizList = AppPreferences::Get()->ChatViewHorizListWeight;
|
|
|
|
vertChat = AppPreferences::Get()->ChatViewVertChatWeight;
|
|
|
|
vertSend = AppPreferences::Get()->ChatViewVertSendWeight;
|
|
|
|
fChatView->SetWeights(horizChat, horizList, vertChat, vertSend);
|
|
|
|
|
2021-05-30 12:30:26 -05:00
|
|
|
BLayoutBuilder::Group<>(this, B_VERTICAL)
|
2021-06-12 16:13:52 -05:00
|
|
|
.Add((fMenuBar = _CreateMenuBar()))
|
2021-05-30 12:30:26 -05:00
|
|
|
.AddGroup(B_HORIZONTAL)
|
|
|
|
.SetInsets(5, 5, 0, 10)
|
2021-07-30 16:14:21 -05:00
|
|
|
.AddSplit(fSplitView)
|
2021-05-30 12:30:26 -05:00
|
|
|
.AddGroup(B_VERTICAL)
|
|
|
|
.Add(fListView, 1)
|
|
|
|
.Add(fStatusView)
|
|
|
|
.End()
|
|
|
|
.Add(fRightView, 5)
|
|
|
|
.End()
|
|
|
|
.End()
|
|
|
|
.End();
|
|
|
|
|
|
|
|
SetConversation(NULL);
|
2021-06-12 16:13:52 -05:00
|
|
|
_ToggleMenuItems();
|
2021-05-30 12:30:26 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BMenuBar*
|
|
|
|
MainWindow::_CreateMenuBar()
|
|
|
|
{
|
|
|
|
BMenuBar* menuBar = new BMenuBar("MenuBar");
|
|
|
|
|
2021-05-31 10:50:43 -05:00
|
|
|
// Program
|
2021-07-19 09:54:27 -05:00
|
|
|
BMenu* programMenu = new BMenu(B_TRANSLATE("Program"));
|
|
|
|
programMenu->AddItem(new BMenuItem(B_TRANSLATE("About" B_UTF8_ELLIPSIS),
|
2021-05-30 12:30:26 -05:00
|
|
|
new BMessage(B_ABOUT_REQUESTED)));
|
2021-07-19 09:54:27 -05:00
|
|
|
programMenu->AddItem(new BMenuItem(B_TRANSLATE("Preferences" B_UTF8_ELLIPSIS),
|
2021-06-20 12:44:20 -05:00
|
|
|
new BMessage(APP_SHOW_SETTINGS), ',', B_COMMAND_KEY));
|
2021-05-30 12:30:26 -05:00
|
|
|
programMenu->AddItem(new BSeparatorItem());
|
2021-07-19 09:54:27 -05:00
|
|
|
programMenu->AddItem(new BMenuItem(B_TRANSLATE("Quit"),
|
2021-05-30 12:30:26 -05:00
|
|
|
new BMessage(B_QUIT_REQUESTED), 'Q', B_COMMAND_KEY));
|
|
|
|
programMenu->SetTargetForItems(this);
|
|
|
|
|
2021-05-31 10:50:43 -05:00
|
|
|
// Chat
|
2021-07-19 09:54:27 -05:00
|
|
|
BMenu* chatMenu = new BMenu(B_TRANSLATE("Chat"));
|
|
|
|
chatMenu->AddItem(new BMenuItem(B_TRANSLATE("Join room" B_UTF8_ELLIPSIS),
|
2021-06-20 12:44:20 -05:00
|
|
|
new BMessage(APP_JOIN_ROOM), 'J', B_COMMAND_KEY));
|
2021-05-31 10:50:43 -05:00
|
|
|
chatMenu->AddSeparatorItem();
|
2021-07-19 09:54:27 -05:00
|
|
|
chatMenu->AddItem(new BMenuItem(B_TRANSLATE("New room" B_UTF8_ELLIPSIS),
|
2021-06-20 12:44:20 -05:00
|
|
|
new BMessage(APP_NEW_ROOM), 'N', B_COMMAND_KEY));
|
2021-07-19 09:54:27 -05:00
|
|
|
chatMenu->AddItem(new BMenuItem(B_TRANSLATE("New chat" B_UTF8_ELLIPSIS),
|
2021-06-20 12:44:20 -05:00
|
|
|
new BMessage(APP_NEW_CHAT), 'M', B_COMMAND_KEY));
|
2021-05-30 12:30:26 -05:00
|
|
|
chatMenu->SetTargetForItems(this);
|
|
|
|
|
2021-06-19 18:25:58 -05:00
|
|
|
// Roster
|
2021-07-19 09:54:27 -05:00
|
|
|
BMenu* rosterMenu = new BMenu(B_TRANSLATE("Roster"));
|
|
|
|
rosterMenu->AddItem(new BMenuItem(B_TRANSLATE("Edit roster" B_UTF8_ELLIPSIS),
|
2021-06-20 12:44:20 -05:00
|
|
|
new BMessage(APP_EDIT_ROSTER), 'R', B_COMMAND_KEY));
|
2021-06-19 18:25:58 -05:00
|
|
|
rosterMenu->AddSeparatorItem();
|
2021-07-19 09:54:27 -05:00
|
|
|
rosterMenu->AddItem(new BMenuItem(B_TRANSLATE("Invite user" B_UTF8_ELLIPSIS),
|
2021-06-20 12:44:20 -05:00
|
|
|
new BMessage(APP_SEND_INVITE), 'I', B_COMMAND_KEY));
|
2021-06-19 18:25:58 -05:00
|
|
|
rosterMenu->SetTargetForItems(this);
|
|
|
|
|
2021-05-31 10:50:43 -05:00
|
|
|
// Window
|
2021-07-19 09:54:27 -05:00
|
|
|
BMenu* windowMenu = new BMenu(B_TRANSLATE("Window"));
|
|
|
|
windowMenu->AddItem(new BMenuItem(B_TRANSLATE("Up"),
|
2021-06-20 12:44:20 -05:00
|
|
|
new BMessage(APP_MOVE_UP), B_UP_ARROW, B_COMMAND_KEY));
|
2021-07-19 09:54:27 -05:00
|
|
|
windowMenu->AddItem(new BMenuItem(B_TRANSLATE("Down"),
|
2021-06-20 12:44:20 -05:00
|
|
|
new BMessage(APP_MOVE_DOWN), B_DOWN_ARROW, B_COMMAND_KEY));
|
2021-05-31 10:50:43 -05:00
|
|
|
windowMenu->SetTargetForItems(this);
|
2021-05-30 20:45:24 -05:00
|
|
|
|
2021-05-30 12:30:26 -05:00
|
|
|
menuBar->AddItem(programMenu);
|
2021-08-06 14:14:14 -05:00
|
|
|
menuBar->AddItem(_CreateAccountsMenu());
|
2021-05-30 12:30:26 -05:00
|
|
|
menuBar->AddItem(chatMenu);
|
2021-06-19 18:25:58 -05:00
|
|
|
menuBar->AddItem(rosterMenu);
|
2021-05-30 20:45:24 -05:00
|
|
|
menuBar->AddItem(windowMenu);
|
2021-06-12 16:13:52 -05:00
|
|
|
|
2021-05-30 12:30:26 -05:00
|
|
|
return menuBar;
|
2011-12-14 17:36:27 -06:00
|
|
|
}
|
2021-05-26 07:48:25 -05:00
|
|
|
|
|
|
|
|
2021-08-06 14:14:14 -05:00
|
|
|
BMenu*
|
|
|
|
MainWindow::_CreateAccountsMenu()
|
|
|
|
{
|
|
|
|
BMenu* accountsMenu = new BMenu(B_TRANSLATE("Accounts"));
|
|
|
|
ProtocolManager* pm = ProtocolManager::Get();
|
|
|
|
|
2021-08-07 17:37:16 -05:00
|
|
|
bool hasAccounts = false;
|
2021-08-06 14:14:14 -05:00
|
|
|
for (uint32 i = 0; i < pm->CountProtocolAddOns(); i++) {
|
|
|
|
ChatProtocolAddOn* addOn = pm->ProtocolAddOnAt(i);
|
|
|
|
ProtocolSettings* settings = new ProtocolSettings(addOn);
|
|
|
|
|
2021-08-07 17:37:16 -05:00
|
|
|
if (_PopulateWithAccounts(accountsMenu, settings) == true)
|
|
|
|
hasAccounts = true;
|
2021-08-06 14:14:14 -05:00
|
|
|
}
|
|
|
|
|
2021-08-07 17:37:16 -05:00
|
|
|
if (hasAccounts == true)
|
|
|
|
accountsMenu->AddSeparatorItem();
|
2021-08-06 14:14:14 -05:00
|
|
|
accountsMenu->AddItem(
|
|
|
|
new BMenuItem(B_TRANSLATE("Manage accounts" B_UTF8_ELLIPSIS),
|
|
|
|
new BMessage(APP_SHOW_ACCOUNTS), '.', B_COMMAND_KEY));
|
|
|
|
accountsMenu->SetTargetForItems(this);
|
|
|
|
return accountsMenu;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
MainWindow::_RefreshAccountsMenu()
|
|
|
|
{
|
|
|
|
_ReplaceMenu(B_TRANSLATE("Accounts"), _CreateAccountsMenu());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-06-12 16:13:52 -05:00
|
|
|
void
|
|
|
|
MainWindow::_ToggleMenuItems()
|
|
|
|
{
|
2021-07-19 09:54:27 -05:00
|
|
|
BMenuItem* chatMenuItem = fMenuBar->FindItem(B_TRANSLATE("Chat"));
|
2021-07-28 19:33:39 -05:00
|
|
|
BMenuItem* rosterMenuItem = fMenuBar->FindItem(B_TRANSLATE("Roster"));
|
2021-06-12 16:13:52 -05:00
|
|
|
BMenu* chatMenu = chatMenuItem->Submenu();
|
2021-07-28 19:33:39 -05:00
|
|
|
BMenu* rosterMenu = rosterMenuItem->Submenu();
|
|
|
|
|
|
|
|
if (chatMenu == NULL || rosterMenu == NULL)
|
2021-06-12 16:13:52 -05:00
|
|
|
return;
|
|
|
|
|
2021-07-28 19:33:39 -05:00
|
|
|
bool enabled = (fServer != NULL && fServer->GetAccounts().CountItems() > 0);
|
2021-06-12 16:13:52 -05:00
|
|
|
|
|
|
|
for (int i = 0; i < chatMenu->CountItems(); i++)
|
|
|
|
chatMenu->ItemAt(i)->SetEnabled(enabled);
|
2021-07-28 19:33:39 -05:00
|
|
|
|
|
|
|
for (int i = 0; i < rosterMenu->CountItems(); i++)
|
|
|
|
rosterMenu->ItemAt(i)->SetEnabled(enabled);
|
|
|
|
|
|
|
|
BMenuItem* windowMenuItem = fMenuBar->FindItem(B_TRANSLATE("Window"));
|
|
|
|
BMenu* windowMenu = windowMenuItem->Submenu();
|
2021-08-12 15:43:52 -05:00
|
|
|
enabled = (fListView->CountItems() > 0);
|
2021-07-28 19:33:39 -05:00
|
|
|
|
|
|
|
for (int i = 0; i < windowMenu->CountItems(); i++)
|
|
|
|
windowMenu->ItemAt(i)->SetEnabled(enabled);
|
2021-06-12 16:13:52 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-05-27 11:15:30 -05:00
|
|
|
ConversationItem*
|
|
|
|
MainWindow::_EnsureConversationItem(BMessage* msg)
|
|
|
|
{
|
|
|
|
ChatMap chats = fServer->Conversations();
|
|
|
|
|
|
|
|
BString chat_id = msg->FindString("chat_id");
|
Explicitly tie Conversations, Contacts, and Users to their ProtocolLoopers
Previously, all Conversations/Contacts/Users were stored in the Server,
each in their respective KeyMaps, identified solely by their
identifiers. This leads to the glaring problem of overlap― if the user
has multiple accounts, some users/rooms might be used or present in multiple
accounts at the same time.
Now, each accounts' Contacts, Conversations, and Users are stored in
its ProtocolLooper, making this overlap impossible. An oversight of only
allowing one user identifier to be stored (fMySelf) in Server was also fixed
this way.
This is the bulk of the work required for multi-account support― now,
the user can join the same XMPP room on two seperate accounts, and it
works perfectly.
2021-06-10 15:16:43 -05:00
|
|
|
Conversation* chat = fServer->ConversationById(chat_id, msg->FindInt64("instance"));
|
2021-06-11 17:24:04 -05:00
|
|
|
ConversationItem* item = chat->GetListItem();
|
2021-05-27 11:15:30 -05:00
|
|
|
|
|
|
|
if (chat != NULL) {
|
2021-06-11 17:24:04 -05:00
|
|
|
if (fListView->HasItem(item))
|
|
|
|
fListView->InvalidateItem(fListView->IndexOf(item));
|
2021-07-28 19:33:39 -05:00
|
|
|
else if (item != NULL) {
|
2021-06-11 17:24:04 -05:00
|
|
|
fListView->AddConversation(chat);
|
2021-07-28 19:33:39 -05:00
|
|
|
_ToggleMenuItems();
|
|
|
|
}
|
2021-05-30 20:45:24 -05:00
|
|
|
|
2021-08-12 15:43:52 -05:00
|
|
|
if (fListView->CountItems() == 1)
|
|
|
|
fListView->Select(0);
|
2021-05-27 11:15:30 -05:00
|
|
|
return item;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
2021-08-06 14:14:14 -05:00
|
|
|
|
|
|
|
|
2021-08-07 17:37:16 -05:00
|
|
|
bool
|
2021-08-06 14:14:14 -05:00
|
|
|
MainWindow::_PopulateWithAccounts(BMenu* menu, ProtocolSettings* settings)
|
|
|
|
{
|
|
|
|
if (!settings)
|
2021-08-07 17:37:16 -05:00
|
|
|
return false;
|
2021-08-06 14:14:14 -05:00
|
|
|
BObjectList<BString> accounts = settings->Accounts();
|
|
|
|
|
|
|
|
// Add accounts to menu
|
|
|
|
for (int32 i = 0; i < accounts.CountItems(); i++) {
|
|
|
|
BString* account = accounts.ItemAt(i);
|
|
|
|
BMenu* accMenu = new BMenu(account->String());
|
|
|
|
|
2021-08-07 17:37:16 -05:00
|
|
|
BString toggleLabel = B_TRANSLATE("Enable");
|
|
|
|
bool isActive = false;
|
|
|
|
int64 instance = fServer->GetActiveAccounts().ValueFor(*account, &isActive);
|
|
|
|
if (isActive == true)
|
|
|
|
toggleLabel = B_TRANSLATE("Disable");
|
|
|
|
|
|
|
|
BMessage* toggleMsg = new BMessage(APP_TOGGLE_ACCOUNT);
|
|
|
|
toggleMsg->AddPointer("settings", settings);
|
|
|
|
toggleMsg->AddString("account", *account);
|
|
|
|
if (isActive == true)
|
|
|
|
toggleMsg->AddInt64("instance", instance);
|
|
|
|
|
2021-08-06 14:14:14 -05:00
|
|
|
BMessage* editMsg = new BMessage(APP_EDIT_ACCOUNT);
|
|
|
|
editMsg->AddPointer("settings", settings);
|
|
|
|
editMsg->AddString("account", *account);
|
|
|
|
|
2021-08-07 17:37:16 -05:00
|
|
|
accMenu->AddItem(new BMenuItem(toggleLabel.String(), toggleMsg));
|
|
|
|
|
2021-08-06 14:14:14 -05:00
|
|
|
accMenu->AddItem(
|
|
|
|
new BMenuItem(B_TRANSLATE("Modify account" B_UTF8_ELLIPSIS),
|
|
|
|
editMsg));
|
2021-08-07 17:37:16 -05:00
|
|
|
|
2021-08-06 14:14:14 -05:00
|
|
|
menu->AddItem(accMenu);
|
|
|
|
}
|
2021-08-07 17:37:16 -05:00
|
|
|
return (accounts.CountItems() > 0);
|
2021-08-06 14:14:14 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
MainWindow::_ReplaceMenu(const char* name, BMenu* newMenu)
|
|
|
|
{
|
|
|
|
BMenuItem* old = fMenuBar->FindItem(name);
|
|
|
|
if (old == NULL || newMenu == NULL)
|
|
|
|
return;
|
|
|
|
int32 index = fMenuBar->IndexOf(old);
|
|
|
|
fMenuBar->RemoveItem(index);
|
|
|
|
fMenuBar->AddItem(newMenu, index);
|
|
|
|
}
|