1089 lines
30 KiB
C++
1089 lines
30 KiB
C++
//////////////////////////////////////////////////
|
|
// Blabber [BlabberMainWindow.cpp]
|
|
//////////////////////////////////////////////////
|
|
|
|
#include "MainWindow.h"
|
|
|
|
#include <gloox/jid.h>
|
|
|
|
#include "support/AppLocation.h"
|
|
|
|
#include "ui/AddBuddyWindow.h"
|
|
#include "ui/BuddyInfoWindow.h"
|
|
#include "ui/ChangeNameWindow.h"
|
|
#include "ui/ModalAlertFactory.h"
|
|
#include "ui/RegisterAccountWindow.h"
|
|
#include "ui/RotateChatFilter.h"
|
|
#include "ui/TalkView.h"
|
|
|
|
#include "jabber/BlabberSettings.h"
|
|
#include "jabber/CustomStatusWindow.h"
|
|
#include "jabber/GenericFunctions.h"
|
|
#include "jabber/JabberSpeak.h"
|
|
#include "jabber/Messages.h"
|
|
#include "jabber/MessageRepeater.h"
|
|
#include "jabber/PreferencesWindow.h"
|
|
#include "jabber/RosterItem.h"
|
|
#include "jabber/SendTalkWindow.h"
|
|
#include "jabber/TalkManager.h"
|
|
|
|
#include <Application.h>
|
|
#include <CardLayout.h>
|
|
#include <FindDirectory.h>
|
|
#include <GroupLayout.h>
|
|
#include <GroupView.h>
|
|
#include <LayoutBuilder.h>
|
|
#include <MenuBar.h>
|
|
#include <MenuItem.h>
|
|
#include <be_apps/NetPositive/NetPositive.h>
|
|
#include <Path.h>
|
|
#include <Roster.h>
|
|
#include <ScrollView.h>
|
|
#include <String.h>
|
|
|
|
#include <algorithm>
|
|
#include <cstdio>
|
|
#include <stdlib.h>
|
|
|
|
|
|
enum {
|
|
kCreateAccount = 'crea'
|
|
};
|
|
|
|
|
|
BlabberMainWindow *BlabberMainWindow::_instance = NULL;
|
|
|
|
BlabberMainWindow *BlabberMainWindow::Instance() {
|
|
BlabberSettings *settings = BlabberSettings::Instance();
|
|
|
|
if (_instance == NULL && !settings->Data("no-window-on-startup")) {
|
|
float main_window_width, main_window_height;
|
|
|
|
// determine what the width and height of the window should be
|
|
if (settings->Data("main-window-width") && settings->Data("main-window-height")) {
|
|
main_window_width = atof(settings->Data("main-window-width"));
|
|
main_window_height = atof(settings->Data("main-window-height"));
|
|
} else {
|
|
// default
|
|
main_window_width = 210;
|
|
main_window_height = 332;
|
|
}
|
|
|
|
// create window frame position
|
|
BRect frame(GenericFunctions::CenteredFrame(main_window_width, main_window_height));
|
|
|
|
// poition window to last known position
|
|
if (settings->Data("main-window-left") && settings->Data("main-window-top")) {
|
|
frame.OffsetTo(BPoint(atof(settings->Data("main-window-left")), atof(settings->Data("main-window-top"))));
|
|
}
|
|
|
|
// create window singleton
|
|
_instance = new BlabberMainWindow(frame);
|
|
}
|
|
|
|
return _instance;
|
|
}
|
|
|
|
BlabberMainWindow::~BlabberMainWindow() {
|
|
// remove self from message family
|
|
MessageRepeater::Instance()->RemoveTarget(this);
|
|
|
|
_instance = NULL;
|
|
}
|
|
|
|
void BlabberMainWindow::MessageReceived(BMessage *msg) {
|
|
switch (msg->what) {
|
|
case kCreateAccount:
|
|
{
|
|
(new RegisterAccountWindow(this))->Show();
|
|
break;
|
|
}
|
|
|
|
// transplanted from LoginWindow
|
|
case JAB_LOGIN: {
|
|
// must pass validation
|
|
if (!ValidateLogin()) {
|
|
break;
|
|
}
|
|
|
|
// switch out views
|
|
_login_login->MakeDefault(false);
|
|
BCardLayout* cl = (BCardLayout*)GetLayout();
|
|
cl->SetVisibleItem((int32)0);
|
|
|
|
// connect with current username or register new account
|
|
JabberSpeak::Instance()->SendConnect(_login_username->Text(), _login_password->Text(), _login_realname->Text());
|
|
|
|
break;
|
|
}
|
|
|
|
case B_ABOUT_REQUESTED: {
|
|
be_app->PostMessage(B_ABOUT_REQUESTED);
|
|
break;
|
|
}
|
|
|
|
case JAB_QUIT: {
|
|
be_app->PostMessage(B_QUIT_REQUESTED);
|
|
break;
|
|
}
|
|
|
|
case JAB_PREFERENCES: {
|
|
PreferencesWindow::Instance()->Show();
|
|
PreferencesWindow::Instance()->Activate();
|
|
break;
|
|
}
|
|
|
|
case JAB_CONNECT: {
|
|
_status_view->SetMessage("connecting");
|
|
JabberSpeak::Instance()->SendConnect("", "", "", true);
|
|
|
|
break;
|
|
}
|
|
|
|
case JAB_RECONNECTING: {
|
|
// we are connecting
|
|
_status_view->SetMessage("reconnecting");
|
|
|
|
break;
|
|
}
|
|
|
|
case JAB_LOGGED_IN: {
|
|
// we just logged in
|
|
_status_view->SetMessage("connected as " + JabberSpeak::Instance()->CurrentLogin());
|
|
|
|
// save these settings
|
|
BlabberSettings::Instance()->SetData("last-realname", _login_realname->Text());
|
|
BlabberSettings::Instance()->SetData("last-login", _login_username->Text());
|
|
BlabberSettings::Instance()->SetData("last-password", _login_password->Text());
|
|
BlabberSettings::Instance()->SetTag("auto-login", _login_auto_login->Value());
|
|
BlabberSettings::Instance()->WriteToFile();
|
|
|
|
break;
|
|
}
|
|
|
|
case JAB_DISCONNECT: {
|
|
JabberSpeak::Instance()->SendDisconnect();
|
|
_status_view->SetMessage("disconnecting");
|
|
JabberSpeak::Instance()->Reset();
|
|
|
|
break;
|
|
}
|
|
|
|
case JAB_DISCONNECTED: {
|
|
JRoster::Instance()->RefreshRoster();
|
|
|
|
break;
|
|
}
|
|
|
|
case JAB_RIV: {
|
|
string jabber_org = "http://github.com/haikuarchives/renga";
|
|
|
|
char *argv[] = {const_cast<char *>(jabber_org.c_str()), NULL};
|
|
if (!be_roster->IsRunning("text/html"))
|
|
be_roster->Launch("text/html", 1, argv);
|
|
else {
|
|
BMessenger messenger("text/html");
|
|
BMessage msg(B_NETPOSITIVE_OPEN_URL);
|
|
msg.AddString("be:url", jabber_org.c_str());
|
|
messenger.SendMessage(&msg);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case JAB_BE_USERS: {
|
|
string jabber_org = "http://home.t-online.de/home/sascha.offe/jabber.html";
|
|
|
|
char *argv[] = {const_cast<char *>(jabber_org.c_str()), NULL};
|
|
if (!be_roster->IsRunning("text/html"))
|
|
be_roster->Launch("text/html", 1, argv);
|
|
else {
|
|
BMessenger messenger("text/html");
|
|
BMessage msg(B_NETPOSITIVE_OPEN_URL);
|
|
msg.AddString("be:url", jabber_org.c_str());
|
|
messenger.SendMessage(&msg);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case JAB_JABBER_ORG: {
|
|
string jabber_org = "http://www.jabber.org";
|
|
|
|
char *argv[] = {const_cast<char *>(jabber_org.c_str()), NULL};
|
|
if (!be_roster->IsRunning("text/html"))
|
|
be_roster->Launch("text/html", 1, argv);
|
|
else {
|
|
BMessenger messenger("text/html");
|
|
BMessage msg(B_NETPOSITIVE_OPEN_URL);
|
|
msg.AddString("be:url", jabber_org.c_str());
|
|
messenger.SendMessage(&msg);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case JAB_JABBER_CENTRAL_ORG: {
|
|
string jabber_org = "http://www.jabbercentral.org";
|
|
|
|
char *argv[] = {const_cast<char *>(jabber_org.c_str()), NULL};
|
|
if (!be_roster->IsRunning("text/html"))
|
|
be_roster->Launch("text/html", 1, argv);
|
|
else {
|
|
BMessenger messenger("text/html");
|
|
BMessage msg(B_NETPOSITIVE_OPEN_URL);
|
|
msg.AddString("be:url", jabber_org.c_str());
|
|
messenger.SendMessage(&msg);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case JAB_JABBER_VIEW_COM: {
|
|
string jabber_org = "http://www.jabberview.com";
|
|
|
|
char *argv[] = {const_cast<char *>(jabber_org.c_str()), NULL};
|
|
if (!be_roster->IsRunning("text/html"))
|
|
be_roster->Launch("text/html", 1, argv);
|
|
else {
|
|
BMessenger messenger("text/html");
|
|
BMessage msg(B_NETPOSITIVE_OPEN_URL);
|
|
msg.AddString("be:url", jabber_org.c_str());
|
|
messenger.SendMessage(&msg);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case JAB_FAQ: {
|
|
string user_guide = "http://www.users.uswest.net/~jblanco/jabber-faq.html";
|
|
|
|
char *argv[] = {const_cast<char *>(user_guide.c_str()), NULL};
|
|
if (!be_roster->IsRunning("text/html"))
|
|
be_roster->Launch("text/html", 1, argv);
|
|
else {
|
|
BMessenger messenger("text/html");
|
|
BMessage msg(B_NETPOSITIVE_OPEN_URL);
|
|
msg.AddString("be:url", user_guide.c_str());
|
|
messenger.SendMessage(&msg);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case JAB_USER_GUIDE: {
|
|
string user_guide = AppLocation::Instance()->AbsolutePath("resources/user-guide/user_guide.html");
|
|
|
|
char *argv[] = {const_cast<char *>(user_guide.c_str()), NULL};
|
|
if (!be_roster->IsRunning("text/html"))
|
|
be_roster->Launch("text/html", 1, argv);
|
|
else {
|
|
BMessenger messenger("text/html");
|
|
BMessage msg(B_NETPOSITIVE_OPEN_URL);
|
|
msg.AddString("be:url", user_guide.c_str());
|
|
messenger.SendMessage(&msg);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case BLAB_UPDATE_ROSTER: {
|
|
// a message that the roster singleton was updated
|
|
_roster->UpdateRoster();
|
|
|
|
break;
|
|
}
|
|
|
|
case JAB_SUBSCRIBE_PRESENCE: {
|
|
RosterItem *item = _roster->CurrentItemSelection();
|
|
|
|
// if there was a user selected (shouldn't be otherwise)
|
|
if (item) {
|
|
// don't send subscription request if we have it already
|
|
if (!item->GetUserID()->HaveSubscriptionTo()) {
|
|
JabberSpeak::Instance()->SendSubscriptionRequest(item->GetUserID()->JabberHandle());
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case JAB_UNSUBSCRIBE_PRESENCE: {
|
|
RosterItem *item = _roster->CurrentItemSelection();
|
|
|
|
// if there was a user selected (shouldn't be otherwise)
|
|
if (item) {
|
|
// don't send unsubscription request if we don't have it already
|
|
if (item->GetUserID()->HaveSubscriptionTo()) {
|
|
JabberSpeak::Instance()->SendUnsubscriptionRequest(item->GetUserID()->Handle());
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case JAB_OPEN_CHAT_WITH_DOUBLE_CLICK: {
|
|
// works in combination with JAB_OPEN_CHAT case
|
|
if (!BlabberSettings::Instance()->Tag("enable-double-click")) {
|
|
break;
|
|
}
|
|
}
|
|
__attribute__ ((fallthrough));
|
|
|
|
case JAB_OPEN_CHAT: {
|
|
// if there's a current selection, begin chat with that user
|
|
RosterItem *item = _roster->CurrentItemSelection();
|
|
|
|
if (item != NULL) {
|
|
const UserID *user = item->GetUserID();
|
|
|
|
// open chat window
|
|
TalkManager::Instance()->CreateTalkSession(gloox::Message::Chat,
|
|
&user->JID(), "", "", NULL);
|
|
}
|
|
|
|
// if there's a current selection, begin chat with that group
|
|
BookmarkItem *bookmark = _roster->CurrentBookmarkSelection();
|
|
|
|
if (bookmark != NULL) {
|
|
const gloox::JID& group = bookmark->GetUserID();
|
|
const gloox::ConferenceListItem* info
|
|
= BookmarkManager::Instance().GetBookmark(group.full().c_str());
|
|
|
|
// open chat window
|
|
TalkManager::Instance()->CreateTalkSession(gloox::Message::Groupchat,
|
|
NULL, group.full(), info->nick, NULL);
|
|
|
|
// Enable autojoin if needed
|
|
BookmarkManager::Instance().SetBookmark(group.full().c_str(),
|
|
info->nick.c_str(), bookmark->Text(), true);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case JAB_SHOW_CHATLOG: {
|
|
BString path;
|
|
// try to get the chatlog path from message
|
|
if(B_OK != msg->FindString("path", &path)) {
|
|
// no path provided with message? try to open history for selected user...
|
|
RosterItem *item = _roster->CurrentItemSelection();
|
|
if (item != NULL) {
|
|
const UserID *user = item->GetUserID();
|
|
string chatlog_path = BlabberSettings::Instance()->Data("chatlog-path");
|
|
if(0 == chatlog_path.size()) {
|
|
BPath path;
|
|
find_directory(B_USER_DIRECTORY, &path);
|
|
chatlog_path = path.Path();
|
|
}
|
|
chatlog_path += "/" + user->JabberHandle();
|
|
path = chatlog_path.c_str();
|
|
}
|
|
}
|
|
// now attemt to open history file with default application for "text/x-jabber-chatlog" MIME type
|
|
if(path.Length() > 0) {
|
|
BEntry entry(path.String());
|
|
entry_ref ref;
|
|
entry.GetRef(&ref);
|
|
BMessage *msgRefs = new BMessage(B_REFS_RECEIVED);
|
|
msgRefs->AddRef("refs", &ref);
|
|
be_roster->Launch("text/plain", msgRefs);
|
|
//be_roster->Launch(path.String());
|
|
}
|
|
break;
|
|
}
|
|
|
|
case JAB_OPEN_NEW_CHAT: {
|
|
(new SendTalkWindow(gloox::Message::Chat))->Show();
|
|
break;
|
|
}
|
|
|
|
case JAB_OPEN_NEW_GROUP_CHAT: {
|
|
(new SendTalkWindow(gloox::Message::Groupchat))->Show();
|
|
break;
|
|
}
|
|
|
|
case JAB_OPEN_MESSAGE: {
|
|
// if there's a current selection, begin message with that user
|
|
RosterItem *item = _roster->CurrentItemSelection();
|
|
|
|
const UserID *user = item->GetUserID();
|
|
|
|
// open message window
|
|
TalkManager::Instance()->CreateTalkSession(gloox::Message::Normal, &user->JID(), "", "", NULL);
|
|
|
|
break;
|
|
}
|
|
|
|
case JAB_OPEN_NEW_MESSAGE: {
|
|
(new SendTalkWindow(gloox::Message::Normal))->Show();
|
|
break;
|
|
}
|
|
|
|
case JAB_OPEN_ADD_BUDDY_WINDOW: {
|
|
// open buddy window
|
|
AddBuddyWindow::Instance()->Show();
|
|
break;
|
|
}
|
|
|
|
case JAB_OPEN_EDIT_BUDDY_WINDOW: {
|
|
// pick out user to be edited from RosterView
|
|
RosterItem *item = _roster->CurrentItemSelection();
|
|
|
|
if (item != NULL) {
|
|
// open edit buddy window
|
|
(new ChangeNameWindow(item->GetUserID()->JID(), item->GetUserID()->FriendlyName().c_str()))->Show();
|
|
}
|
|
|
|
BookmarkItem *bookmark = _roster->CurrentBookmarkSelection();
|
|
|
|
if (bookmark != NULL) {
|
|
// open edit buddy window
|
|
(new ChangeNameWindow(bookmark->GetUserID(), bookmark->Text()))->Show();
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case JAB_USER_INFO: {
|
|
// pick out user to be analyzed
|
|
RosterItem *item = _roster->CurrentItemSelection();
|
|
|
|
if (item != NULL) {
|
|
// pick out user
|
|
UserID *user = const_cast<UserID *>(item->GetUserID());
|
|
|
|
// open edit buddy window
|
|
(new BuddyInfoWindow(user))->Show();
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case JAB_REMOVE_BUDDY: {
|
|
// pick out user to be removed from RosterView
|
|
RosterItem *item = _roster->CurrentItemSelection();
|
|
|
|
if (item != NULL) {
|
|
// pick out user
|
|
const UserID *user = item->GetUserID();
|
|
|
|
// remove the user
|
|
JabberSpeak::Instance()->RemoveFromRoster(user);
|
|
}
|
|
|
|
BookmarkItem *bookmark = _roster->CurrentBookmarkSelection();
|
|
if (bookmark)
|
|
BookmarkManager::Instance().RemoveBookmark(bookmark->GetUserID().full().c_str());
|
|
|
|
break;
|
|
}
|
|
|
|
case BLAB_AVAILABLE_FOR_CHAT: {
|
|
JabberSpeak::Instance()->SendPresence(gloox::Presence::Chat);
|
|
_chat_item->SetMarked(true);
|
|
BlabberSettings::Instance()->SetTag("last-used-custom-status", false);
|
|
BlabberSettings::Instance()->SetData("last-custom-exact-status", "chat");
|
|
BlabberSettings::Instance()->WriteToFile();
|
|
|
|
break;
|
|
}
|
|
|
|
case BLAB_DO_NOT_DISTURB: {
|
|
JabberSpeak::Instance()->SendPresence(gloox::Presence::DND);
|
|
_dnd_item->SetMarked(true);
|
|
BlabberSettings::Instance()->SetTag("last-used-custom-status", false);
|
|
BlabberSettings::Instance()->SetData("last-custom-exact-status", "dnd");
|
|
BlabberSettings::Instance()->WriteToFile();
|
|
|
|
break;
|
|
}
|
|
|
|
case BLAB_AWAY_TEMPORARILY: {
|
|
JabberSpeak::Instance()->SendPresence(gloox::Presence::Away);
|
|
_away_item->SetMarked(true);
|
|
BlabberSettings::Instance()->SetTag("last-used-custom-status", false);
|
|
BlabberSettings::Instance()->SetData("last-custom-exact-status", "away");
|
|
BlabberSettings::Instance()->WriteToFile();
|
|
|
|
break;
|
|
}
|
|
|
|
case BLAB_AWAY_EXTENDED: {
|
|
JabberSpeak::Instance()->SendPresence(gloox::Presence::XA);
|
|
_xa_item->SetMarked(true);
|
|
BlabberSettings::Instance()->SetTag("last-used-custom-status", false);
|
|
BlabberSettings::Instance()->SetData("last-custom-exact-status", "xa");
|
|
BlabberSettings::Instance()->WriteToFile();
|
|
|
|
break;
|
|
}
|
|
|
|
case BLAB_SCHOOL: {
|
|
JabberSpeak::Instance()->SendPresence(gloox::Presence::XA, "Off to School");
|
|
_school_item->SetMarked(true);
|
|
BlabberSettings::Instance()->SetTag("last-used-custom-status", false);
|
|
BlabberSettings::Instance()->SetData("last-custom-exact-status", "school");
|
|
BlabberSettings::Instance()->WriteToFile();
|
|
|
|
break;
|
|
}
|
|
|
|
case BLAB_WORK: {
|
|
JabberSpeak::Instance()->SendPresence(gloox::Presence::XA, "Busy at Work");
|
|
_work_item->SetMarked(true);
|
|
BlabberSettings::Instance()->SetTag("last-used-custom-status", false);
|
|
BlabberSettings::Instance()->SetData("last-custom-exact-status", "work");
|
|
BlabberSettings::Instance()->WriteToFile();
|
|
|
|
break;
|
|
}
|
|
|
|
case BLAB_LUNCH: {
|
|
JabberSpeak::Instance()->SendPresence(gloox::Presence::Away, "Lunch");
|
|
_lunch_item->SetMarked(true);
|
|
BlabberSettings::Instance()->SetTag("last-used-custom-status", false);
|
|
BlabberSettings::Instance()->SetData("last-custom-exact-status", "lunch");
|
|
BlabberSettings::Instance()->WriteToFile();
|
|
|
|
break;
|
|
}
|
|
|
|
case BLAB_DINNER: {
|
|
JabberSpeak::Instance()->SendPresence(gloox::Presence::Away, "Dinner");
|
|
_dinner_item->SetMarked(true);
|
|
BlabberSettings::Instance()->SetTag("last-used-custom-status", false);
|
|
BlabberSettings::Instance()->SetData("last-custom-exact-status", "dinner");
|
|
BlabberSettings::Instance()->WriteToFile();
|
|
|
|
break;
|
|
}
|
|
|
|
case BLAB_SLEEP: {
|
|
JabberSpeak::Instance()->SendPresence(gloox::Presence::XA, "Sleeping");
|
|
_sleep_item->SetMarked(true);
|
|
BlabberSettings::Instance()->SetTag("last-used-custom-status", false);
|
|
BlabberSettings::Instance()->SetData("last-custom-exact-status", "sleep");
|
|
BlabberSettings::Instance()->WriteToFile();
|
|
|
|
break;
|
|
}
|
|
|
|
case BLAB_CUSTOM_STATUS:
|
|
{
|
|
CustomStatusWindow::Instance()->Show();
|
|
CustomStatusWindow::Instance()->Activate();
|
|
break;
|
|
}
|
|
|
|
case kResetWindow:
|
|
{
|
|
JabberSpeak::Instance()->Reset();
|
|
ShowLogin();
|
|
|
|
break;
|
|
}
|
|
|
|
case JAB_ROTATE_CHAT_FORWARD:
|
|
{
|
|
int currentIndex = fTalkCards->VisibleIndex();
|
|
int itemCount = fTalkCards->CountItems();
|
|
|
|
if (++currentIndex >= itemCount)
|
|
currentIndex = 0;
|
|
|
|
if (currentIndex < itemCount) {
|
|
fTalkCards->SetVisibleItem(currentIndex);
|
|
TalkView* v = (TalkView*)fTalkCards->ItemAt(currentIndex)->View();
|
|
if (v->IsGroupChat()) {
|
|
int item = _roster->FindBookmark(gloox::JID(v->GetGroupRoom()));
|
|
_roster->Select(item);
|
|
} else {
|
|
int item = _roster->FindUser(v->GetUserID());
|
|
_roster->Select(item);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
case JAB_ROTATE_CHAT_BACKWARD:
|
|
{
|
|
int currentIndex = fTalkCards->VisibleIndex();
|
|
int itemCount = fTalkCards->CountItems();
|
|
|
|
if (--currentIndex < 0)
|
|
currentIndex = itemCount - 1;
|
|
|
|
if (currentIndex > 0) {
|
|
fTalkCards->SetVisibleItem(currentIndex);
|
|
TalkView* v = (TalkView*)fTalkCards->ItemAt(currentIndex)->View();
|
|
if (v->IsGroupChat()) {
|
|
int item = _roster->FindBookmark(gloox::JID(v->GetGroupRoom()));
|
|
_roster->Select(item);
|
|
} else {
|
|
int item = _roster->FindUser(v->GetUserID());
|
|
_roster->Select(item);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
case kAddTalkView:
|
|
{
|
|
TalkView* view;
|
|
msg->FindPointer("view", (void**)&view);
|
|
AddTalkView(view);
|
|
break;
|
|
}
|
|
|
|
case B_OBSERVER_NOTICE_CHANGE:
|
|
{
|
|
int32 orig_what = msg->FindInt32("be:observe_change_what");
|
|
switch (orig_what) {
|
|
case kAuthenticationFailed:
|
|
{
|
|
ShowLogin();
|
|
_login_username->MarkAsInvalid(true);
|
|
_login_password->MarkAsInvalid(true);
|
|
break;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
default:
|
|
BWindow::MessageReceived(msg);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void BlabberMainWindow::MenusBeginning() {
|
|
char buffer[1024];
|
|
|
|
// FILE menu
|
|
if (!_full_view->IsHidden()) {
|
|
_disconnect_item->SetEnabled(true);
|
|
} else {
|
|
_disconnect_item->SetEnabled(false);
|
|
}
|
|
|
|
// EDIT menu
|
|
if (RosterItem *item = _roster->CurrentItemSelection()) {
|
|
// if a item is selected
|
|
sprintf(buffer, "Edit %s", item->GetUserID()->FriendlyName().c_str());
|
|
_change_buddy_item->SetLabel(buffer);
|
|
_change_buddy_item->SetEnabled(true);
|
|
|
|
sprintf(buffer, "Remove %s", item->GetUserID()->FriendlyName().c_str());
|
|
_remove_buddy_item->SetLabel(buffer);
|
|
_remove_buddy_item->SetEnabled(true);
|
|
|
|
_user_info_item->SetEnabled(true);
|
|
} else {
|
|
sprintf(buffer, "Edit Buddy");
|
|
_change_buddy_item->SetLabel(buffer);
|
|
_change_buddy_item->SetEnabled(false);
|
|
|
|
sprintf(buffer, "Remove Buddy");
|
|
_remove_buddy_item->SetLabel(buffer);
|
|
_remove_buddy_item->SetEnabled(false);
|
|
|
|
_user_info_item->SetEnabled(false);
|
|
}
|
|
}
|
|
|
|
bool BlabberMainWindow::QuitRequested() {
|
|
// remember last coordinates
|
|
BlabberSettings::Instance()->SetFloatData("main-window-left", Frame().left);
|
|
BlabberSettings::Instance()->SetFloatData("main-window-top", Frame().top);
|
|
BlabberSettings::Instance()->SetFloatData("main-window-width", Bounds().Width());
|
|
BlabberSettings::Instance()->SetFloatData("main-window-height", Bounds().Height());
|
|
BlabberSettings::Instance()->WriteToFile();
|
|
|
|
// FIXME we are doing this from the wrong thread, but I see no better place.
|
|
// It needs to be done immediately here, so that closing the other windows
|
|
// doen't remove them from autojoin.
|
|
BookmarkManager::Instance().Disconnect();
|
|
|
|
be_app->PostMessage(B_QUIT_REQUESTED);
|
|
return true;
|
|
}
|
|
|
|
BlabberMainWindow::BlabberMainWindow(BRect frame)
|
|
: BWindow(frame, "Renga", B_DOCUMENT_WINDOW, B_AUTO_UPDATE_SIZE_LIMITS)
|
|
{
|
|
|
|
// editing filter for taksing
|
|
AddCommonFilter(new RotateChatFilter());
|
|
|
|
// add self to message family
|
|
MessageRepeater::Instance()->AddTarget(this);
|
|
|
|
// encompassing view
|
|
_full_view = new BGroupView("main-full", B_VERTICAL);
|
|
_full_view->SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
|
|
|
|
// status bar
|
|
_status_view = new StatusView();
|
|
_status_view->SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
|
|
|
|
// menubar
|
|
BMenuBar* menubar = new BMenuBar("menubar");
|
|
|
|
// FILE MENU
|
|
BMenu* file_menu = new BMenu("Window");
|
|
|
|
_disconnect_item = new BMenuItem("Log Out", new BMessage(JAB_DISCONNECT));
|
|
|
|
_about_item = new BMenuItem("About Renga" B_UTF8_ELLIPSIS, new BMessage(B_ABOUT_REQUESTED));
|
|
|
|
_quit_item = new BMenuItem("Quit", new BMessage(JAB_QUIT));
|
|
_quit_item->SetShortcut('Q', 0);
|
|
_preferences_item = new BMenuItem("Preferences" B_UTF8_ELLIPSIS, new BMessage(JAB_PREFERENCES));
|
|
_preferences_item->SetShortcut(',', 0);
|
|
|
|
file_menu->AddItem(_preferences_item);
|
|
file_menu->AddSeparatorItem();
|
|
file_menu->AddItem(_disconnect_item);
|
|
file_menu->AddSeparatorItem();
|
|
file_menu->AddItem(_quit_item);
|
|
file_menu->SetTargetForItems(MessageRepeater::Instance());
|
|
|
|
// EDIT MENU
|
|
BMenu* edit_menu = new BMenu("Buddy");
|
|
|
|
_add_buddy_item = new BMenuItem("Add New Buddy", new BMessage(JAB_OPEN_ADD_BUDDY_WINDOW));
|
|
_add_buddy_item->SetShortcut('N', 0);
|
|
|
|
_change_buddy_item = new BMenuItem("Edit Buddy", new BMessage(JAB_OPEN_EDIT_BUDDY_WINDOW));
|
|
_change_buddy_item->SetShortcut('E', 0);
|
|
|
|
_remove_buddy_item = new BMenuItem("Remove Buddy", new BMessage(JAB_REMOVE_BUDDY));
|
|
_remove_buddy_item->SetShortcut('T', 0);
|
|
|
|
_user_info_item = new BMenuItem("Get Buddy Info", new BMessage(JAB_USER_INFO));
|
|
_user_info_item->SetShortcut('G', 0);
|
|
|
|
edit_menu->AddItem(_add_buddy_item);
|
|
edit_menu->AddItem(_change_buddy_item);
|
|
edit_menu->AddItem(_remove_buddy_item);
|
|
edit_menu->AddSeparatorItem();
|
|
edit_menu->AddItem(_user_info_item);
|
|
edit_menu->SetTargetForItems(this);
|
|
|
|
// STATUS MENU
|
|
BMenu* status_menu = new BMenu("Status");
|
|
|
|
_chat_item = new BMenuItem("I'm available for chat.", new BMessage(BLAB_AVAILABLE_FOR_CHAT));
|
|
_away_item = new BMenuItem("I will be away temporarily.", new BMessage(BLAB_AWAY_TEMPORARILY));
|
|
_dnd_item = new BMenuItem("Do not disturb me.", new BMessage(BLAB_DO_NOT_DISTURB));
|
|
_xa_item = new BMenuItem("I will be away for an extended time period.", new BMessage(BLAB_AWAY_EXTENDED));
|
|
_school_item = new BMenuItem("Off to School", new BMessage(BLAB_SCHOOL));
|
|
_work_item = new BMenuItem("Busy at Work", new BMessage(BLAB_WORK));
|
|
_lunch_item = new BMenuItem("Lunch", new BMessage(BLAB_LUNCH));
|
|
_dinner_item = new BMenuItem("Dinner", new BMessage(BLAB_DINNER));
|
|
_sleep_item = new BMenuItem("Sleeping", new BMessage(BLAB_SLEEP));
|
|
_custom_item = new BMenuItem("Custom...", new BMessage(BLAB_CUSTOM_STATUS));
|
|
|
|
status_menu->AddItem(_chat_item);
|
|
status_menu->AddSeparatorItem();
|
|
status_menu->AddItem(_away_item);
|
|
status_menu->AddItem(_dnd_item);
|
|
status_menu->AddItem(_xa_item);
|
|
status_menu->AddSeparatorItem();
|
|
|
|
status_menu->AddItem(_school_item);
|
|
status_menu->AddItem(_work_item);
|
|
status_menu->AddItem(_lunch_item);
|
|
status_menu->AddItem(_dinner_item);
|
|
status_menu->AddItem(_sleep_item);
|
|
|
|
status_menu->AddSeparatorItem();
|
|
status_menu->AddItem(_custom_item);
|
|
|
|
status_menu->SetRadioMode(true);
|
|
_chat_item->SetMarked(true);
|
|
|
|
// TALK MENU
|
|
BMenu* talk_menu = new BMenu("Talk");
|
|
|
|
BMenuItem* rotate_chat_forward_item = new BMenuItem("Rotate Chat Forward", new BMessage(JAB_ROTATE_CHAT_FORWARD));
|
|
rotate_chat_forward_item->SetShortcut(B_UP_ARROW, B_SHIFT_KEY);
|
|
|
|
BMenuItem* rotate_chat_backward_item = new BMenuItem("Rotate Chat Backward", new BMessage(JAB_ROTATE_CHAT_BACKWARD));
|
|
rotate_chat_backward_item->SetShortcut(B_DOWN_ARROW, B_SHIFT_KEY);
|
|
|
|
_send_message_item = new BMenuItem("Send Message...", new BMessage(JAB_OPEN_NEW_MESSAGE));
|
|
_send_message_item->SetShortcut('M', 0);
|
|
|
|
_send_chat_item = new BMenuItem("Start Chat...", new BMessage(JAB_OPEN_NEW_CHAT));
|
|
|
|
_send_groupchat_item = new BMenuItem("Start Group Chat...", new BMessage(JAB_OPEN_NEW_GROUP_CHAT));
|
|
|
|
talk_menu->AddItem(rotate_chat_forward_item);
|
|
talk_menu->AddItem(rotate_chat_backward_item);
|
|
talk_menu->AddSeparatorItem();
|
|
talk_menu->AddItem(_send_message_item);
|
|
talk_menu->AddItem(_send_chat_item);
|
|
talk_menu->AddItem(_send_groupchat_item);
|
|
talk_menu->SetTargetForItems(this);
|
|
|
|
// HELP MENU
|
|
BMenu* help_menu = new BMenu("Help");
|
|
|
|
BMenuItem* user_guide_item = new BMenuItem("Renga Manual", new BMessage(JAB_USER_GUIDE));
|
|
BMenuItem* faq_item = new BMenuItem("Renga FAQ", new BMessage(JAB_FAQ));
|
|
|
|
help_menu->AddItem(user_guide_item);
|
|
help_menu->AddItem(faq_item);
|
|
help_menu->AddSeparatorItem();
|
|
help_menu->AddItem(_about_item);
|
|
|
|
help_menu->SetTargetForItems(this);
|
|
|
|
menubar->AddItem(file_menu);
|
|
menubar->AddItem(edit_menu);
|
|
menubar->AddItem(status_menu);
|
|
menubar->AddItem(talk_menu);
|
|
menubar->AddItem(help_menu);
|
|
|
|
|
|
// tabbed view
|
|
// roster view
|
|
_roster = new RosterView();
|
|
BScrollView* roster_scroller = new BScrollView(NULL, _roster, 0, false, true,
|
|
B_NO_BORDER);
|
|
_roster->TargetedByScrollView(roster_scroller);
|
|
|
|
// chat service
|
|
BLayoutBuilder::Group<>(_full_view, B_VERTICAL, 0)
|
|
.SetInsets(0, 0, 0, 0)
|
|
.Add(menubar)
|
|
.AddSplit(B_HORIZONTAL, 0)
|
|
.AddGroup(B_VERTICAL, 0, 0)
|
|
.Add(roster_scroller)
|
|
.Add(_status_view)
|
|
.End()
|
|
.AddCards()
|
|
.GetLayout(&fTalkCards)
|
|
.End()
|
|
.End()
|
|
.End();
|
|
|
|
///// NOW DO LOGIN STUFF
|
|
// encompassing view
|
|
_login_full_view = new BGroupView("login-full", B_VERTICAL);
|
|
_login_full_view->SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
|
|
|
|
// graphics
|
|
_login_bulb = new PictureView("bulb-normal");
|
|
|
|
// username/password controls
|
|
_login_realname = new BTextControl(NULL, "Nickname: ", NULL, NULL);
|
|
|
|
_login_username = new BTextControl(NULL, "Jabber ID: ", NULL, NULL);
|
|
|
|
_login_password = new BTextControl(NULL, "Password: ", NULL, NULL);
|
|
_login_password->TextView()->HideTyping(true);
|
|
|
|
BMessage* createAccount = new BMessage(kCreateAccount);
|
|
_login_new_account = new BButton("create", "Create a new account",
|
|
createAccount);
|
|
|
|
_login_auto_login = new BCheckBox(NULL, "Auto-login", NULL);
|
|
|
|
// login button
|
|
_login_login = new BButton("login", "Login", new BMessage(JAB_LOGIN));
|
|
_login_login->MakeDefault(false);
|
|
_login_login->SetTarget(this);
|
|
|
|
BStringView* appName = new BStringView("app name", "Renga");
|
|
BFont bigfont(be_plain_font);
|
|
bigfont.SetSize(bigfont.Size() * 3);
|
|
appName->SetFont(&bigfont);
|
|
|
|
BLayoutBuilder::Group<>(_login_full_view, B_HORIZONTAL)
|
|
.AddGlue()
|
|
.AddGroup(B_VERTICAL)
|
|
.SetInsets(B_USE_DEFAULT_SPACING)
|
|
.AddGrid()
|
|
.Add(_login_bulb, 0, 0, 1, 4)
|
|
.Add(appName, 1, 1)
|
|
.Add(new BStringView("", "XMPP client for Haiku"), 1, 2)
|
|
.End()
|
|
.Add(_login_new_account)
|
|
.AddGlue()
|
|
.AddGrid()
|
|
.AddTextControl(_login_realname, 0, 0)
|
|
.AddTextControl(_login_username, 0, 1)
|
|
.AddTextControl(_login_password, 0, 2)
|
|
.End()
|
|
.AddGroup(B_HORIZONTAL)
|
|
.Add(_login_auto_login)
|
|
.AddGlue()
|
|
.Add(_login_login)
|
|
.End()
|
|
.AddGlue()
|
|
.End()
|
|
.AddGlue()
|
|
.End();
|
|
|
|
// attach all-encompassing main view to window
|
|
BCardLayout* cl = new BCardLayout();
|
|
SetLayout(cl);
|
|
AddChild(_full_view);
|
|
AddChild(_login_full_view);
|
|
|
|
// login always hidden at start
|
|
cl->SetVisibleItem((int32)0);
|
|
|
|
// default
|
|
if(BlabberSettings::Instance()->Data("last-realname")) {
|
|
_login_realname->SetText(BlabberSettings::Instance()->Data("last-realname"));
|
|
} else {
|
|
_login_realname->SetText("Me");
|
|
}
|
|
|
|
if (BlabberSettings::Instance()->Data("last-login")) {
|
|
_login_username->SetText(BlabberSettings::Instance()->Data("last-login"));
|
|
} else {
|
|
_login_username->SetText("newuser@jabber.org");
|
|
}
|
|
|
|
_login_password->SetText(BlabberSettings::Instance()->Data("last-password"));
|
|
|
|
_login_auto_login->SetValue(BlabberSettings::Instance()->Tag("auto-login"));
|
|
|
|
// focus to start
|
|
if (BlabberSettings::Instance()->Data("last-login")) {
|
|
_login_password->MakeFocus(true);
|
|
} else {
|
|
_login_username->MakeFocus(true);
|
|
}
|
|
|
|
JabberSpeak::Instance()->StartWatchingAll(this);
|
|
|
|
// editing filter for taksing
|
|
AddCommonFilter(new RotateChatFilter());
|
|
}
|
|
|
|
|
|
bool BlabberMainWindow::ValidateLogin() {
|
|
// existance of username
|
|
if (!strcmp(_login_username->Text(), "")) {
|
|
ModalAlertFactory::Alert("Wait, you haven't specified your Jabber ID yet.\n(e.g. haikuFan@jabber.org)", "Doh!", NULL, NULL, B_WIDTH_FROM_LABEL, B_STOP_ALERT);
|
|
_login_username->MakeFocus(true);
|
|
|
|
return false;
|
|
}
|
|
|
|
// validity of username
|
|
std::string validate = UserID::WhyNotValidJabberHandle(_login_username->Text());
|
|
if (validate.size()) {
|
|
BString buffer;
|
|
buffer.SetToFormat("The Jabber ID you specified must not be yours because it's invalid for the following reason:\n\n%s\n\nIf you can't remember it, it's OK to create a new one by checking the \"Create a new Jabber Account!\" box.", validate.c_str());
|
|
|
|
ModalAlertFactory::Alert(buffer, "OK", NULL, NULL,
|
|
B_WIDTH_FROM_LABEL, B_STOP_ALERT);
|
|
_login_username->MakeFocus(true);
|
|
|
|
return false;
|
|
}
|
|
|
|
gloox::JID username(_login_username->Text());
|
|
|
|
// check existance of password
|
|
if (!strcmp(_login_password->Text(), "")) {
|
|
char buffer[1024];
|
|
sprintf(buffer, "You must specify a password so I can make sure it's you, %s.",
|
|
username.username().c_str());
|
|
|
|
ModalAlertFactory::Alert(buffer, "Sorry!", NULL, NULL,
|
|
B_WIDTH_FROM_LABEL, B_STOP_ALERT);
|
|
_login_password->MakeFocus(true);
|
|
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void BlabberMainWindow::ShowLogin() {
|
|
// reassign button as default
|
|
_login_login->MakeDefault(true);
|
|
|
|
// reset
|
|
_login_realname->SetText("");
|
|
_login_username->SetText("");
|
|
_login_password->SetText("");
|
|
|
|
_login_username->MarkAsInvalid(false);
|
|
_login_password->MarkAsInvalid(false);
|
|
|
|
// default
|
|
if(BlabberSettings::Instance()->Data("last-realname")) {
|
|
_login_realname->SetText(BlabberSettings::Instance()->Data("last-realname"));
|
|
} else {
|
|
_login_realname->SetText("Me");
|
|
}
|
|
|
|
if (BlabberSettings::Instance()->Data("last-login")) {
|
|
_login_username->SetText(BlabberSettings::Instance()->Data("last-login"));
|
|
} else {
|
|
_login_username->SetText("newuser@jabber.org");
|
|
}
|
|
|
|
_login_password->SetText(BlabberSettings::Instance()->Data("last-password"));
|
|
|
|
// focus to start
|
|
if (BlabberSettings::Instance()->Data("last-login")) {
|
|
_login_password->MakeFocus(true);
|
|
} else {
|
|
_login_username->MakeFocus(true);
|
|
}
|
|
|
|
BCardLayout* cl = (BCardLayout*)GetLayout();
|
|
cl->SetVisibleItem(1);
|
|
}
|
|
|
|
void BlabberMainWindow::SetCustomStatus(string status) {
|
|
char buffer[2048];
|
|
|
|
// create menued status message
|
|
sprintf(buffer, "[Custom] %s", status.c_str());
|
|
|
|
_custom_item->SetMarked(true);
|
|
_custom_item->SetLabel(buffer);
|
|
}
|
|
|
|
|
|
void
|
|
BlabberMainWindow::FlagBookmarkItem(const gloox::JID& room, uint32 flags)
|
|
{
|
|
int32 pos = _roster->FindBookmark(room);
|
|
if (pos < 0)
|
|
return;
|
|
|
|
auto* item = dynamic_cast<BookmarkItem*>(_roster->FullListItemAt(pos));
|
|
item->SetFlag(flags);
|
|
|
|
// Need to redo a FindItem because there is no FullListInvalidateItem, so we need to convert the
|
|
// FullList index returned by FindBookmark to a BListView index...
|
|
int32 listIndex = _roster->IndexOf(item);
|
|
// ... and this can fail if the item is in a collapsed part of the list
|
|
if (listIndex < 0)
|
|
return;
|
|
_roster->InvalidateItem(listIndex);
|
|
}
|
|
|
|
|
|
void
|
|
BlabberMainWindow::AddTalkView(TalkView* view)
|
|
{
|
|
if (view->Window() != this) {
|
|
fTalkCards->AddView(view);
|
|
}
|
|
|
|
fTalkCards->SetVisibleItem(fTalkCards->IndexOfView(view));
|
|
}
|