Compare commits
37 Enmetoj
Author | SHA1 | Date | |
---|---|---|---|
Jaidyn Ann | 4284a8bb23 | ||
Alexander von Gluck IV | f78034cb84 | ||
Alexander von Gluck IV | 1a0ee401be | ||
Alexander von Gluck IV | 4964605432 | ||
Alexander von Gluck IV | 53a5c5ed1a | ||
Alexander von Gluck IV | d4b934093d | ||
Alexander von Gluck IV | 8f5762219e | ||
Jaidyn Ann | 8e3c961c29 | ||
Jaidyn Ann | 887d7d120d | ||
Alexander von Gluck IV | 4489f80507 | ||
Alexander von Gluck IV | 3f7201038d | ||
Alexander von Gluck IV | 1168785a62 | ||
Jaidyn Ann | dce82c2ba2 | ||
Jaidyn Ann | e092128200 | ||
Jaidyn Ann | b7b45a8db0 | ||
Jaidyn Ann | ce4d3c2a26 | ||
Jaidyn Ann | 6f01818e8a | ||
Jaidyn Ann | eb60c94d68 | ||
Jaidyn Ann | dd5add390a | ||
Jaidyn Ann | 8d50a6b9a4 | ||
Jaidyn Ann | 866899eaad | ||
Jaidyn Ann | 4ad75cd807 | ||
Jaidyn Ann | 06df963434 | ||
Jaidyn Ann | 8456e00bd8 | ||
Jaidyn Ann | 604082466e | ||
Jaidyn Ann | 2f69f2fa04 | ||
Jaidyn Ann | 3689f6cee3 | ||
Jaidyn Ann | e2d801b84b | ||
Jaidyn Ann | 6a160ced88 | ||
Jaidyn Ann | 8cb98ccf4b | ||
Jaidyn Ann | f19bcba62a | ||
Jaidyn Ann | 5dbbb3a8ad | ||
Jaidyn Ann | 10b63e4138 | ||
Jaidyn Ann | bcb92de53c | ||
Jaidyn Ann | c24c3187ad | ||
begasus | 115631a91d | ||
Jaidyn Ann | aaea63de1a |
|
@ -2,6 +2,8 @@ LIBPATHS = $(OBJ_DIR)
|
|||
PROTOCOL_DIR = $(OBJ_DIR)/chat-o-matic/
|
||||
|
||||
DEBUG_ENABLED ?= false
|
||||
DEFINES := VERSION="\"0.0.2\"" \
|
||||
DEFINES = VERSION="\"0.0.2\"" \
|
||||
BUILD_DATE="\"$(shell date +"%Y-%m-%d %H:%M")\"" \
|
||||
DEBUG_ENABLED=$(DEBUG_ENABLED)
|
||||
DEBUG_ENABLED=$(DEBUG_ENABLED) \
|
||||
APP_NAME="\"$(APP_NAME)"\" \
|
||||
APP_SIGNATURE="\"$(APP_SIGNATURE)"\"
|
|
@ -0,0 +1,2 @@
|
|||
APP_NAME ?= Chat-O-Matic
|
||||
APP_SIGNATURE ?= application/x-vnd.chat-o-matic
|
3
Makefile
|
@ -12,6 +12,9 @@ irc:
|
|||
xmpp:
|
||||
$(MAKE) -f protocols/xmpp/Makefile
|
||||
|
||||
matrix:
|
||||
$(MAKE) -f protocols/matrix/Makefile
|
||||
|
||||
purple:
|
||||
ifneq ($(shell uname -m), x86_gcc2)
|
||||
$(MAKE) -f protocols/purple/Makefile
|
||||
|
|
|
@ -14,6 +14,8 @@ Protocols natively supported include IRC and XMPP.
|
|||
Protocols generally supported through libpurple include GroupWise, Zephyr, and
|
||||
[others through plugins](https://pidgin.im/plugins/?type=Protocol).
|
||||
|
||||
You can find the user documentation [here](http://htmlpreview.github.io/?https://github.com/JadedCtrl/Chat-O-Matic/master/documentation/Documentation.html).
|
||||
|
||||
|
||||
## Building
|
||||
You can make Chat-O-Matic and its protocols with:
|
||||
|
|
|
@ -31,11 +31,13 @@ Account::Account(bigtime_t instanceId, ChatProtocol* cayap,
|
|||
fProtocol->Init(this);
|
||||
|
||||
// Find user's settings path
|
||||
BPath path(AccountPath(addOnSignature, fProtocol->Signature()));
|
||||
BPath path = AccountPath(addOnSignature, fProtocol->Signature());
|
||||
if (path.InitCheck() == B_OK) {
|
||||
path.Append(name);
|
||||
|
||||
fProtocol->SetName(name);
|
||||
fProtocol->SetAccountCachePath(AccountCachePath(name));
|
||||
fProtocol->SetAddOnCachePath(AddOnCachePath(addOnSignature));
|
||||
|
||||
// Load settings file
|
||||
BFile file(path.Path(), B_READ_ONLY);
|
||||
|
|
|
@ -8,6 +8,9 @@
|
|||
//! Show settings window
|
||||
const uint32 APP_SHOW_SETTINGS = 'RPST';
|
||||
|
||||
//! Show documentation
|
||||
const uint32 APP_SHOW_HELP = 'Rhlp';
|
||||
|
||||
//! Show accounts window
|
||||
const uint32 APP_SHOW_ACCOUNTS = 'RPac';
|
||||
|
||||
|
@ -23,6 +26,9 @@ const uint32 APP_NEW_ROOM = 'CYnr';
|
|||
//! Join a chat
|
||||
const uint32 APP_JOIN_ROOM = 'CYjr';
|
||||
|
||||
//! Room directory
|
||||
const uint32 APP_ROOM_DIRECTORY = 'CYrd';
|
||||
|
||||
//! Invite user to current chat
|
||||
const uint32 APP_SEND_INVITE = 'CYin';
|
||||
|
||||
|
@ -59,6 +65,9 @@ const uint32 APP_USER_INFO = 'CYuw';
|
|||
//! Display a "room info" window
|
||||
const uint32 APP_ROOM_INFO = 'CYrw';
|
||||
|
||||
//! Open the room's logs with TextSearch
|
||||
const uint32 APP_ROOM_SEARCH = 'CYrs';
|
||||
|
||||
//! Toggle a specific flag for a room
|
||||
const uint32 APP_ROOM_FLAG = 'Rlag';
|
||||
|
||||
|
|
|
@ -10,7 +10,9 @@
|
|||
|
||||
#include "Conversation.h"
|
||||
#include "MainWindow.h"
|
||||
#include "ProtocolLooper.h"
|
||||
#include "TheApp.h"
|
||||
#include "User.h"
|
||||
|
||||
|
||||
#undef B_TRANSLATION_CONTEXT
|
||||
|
|
|
@ -12,10 +12,11 @@
|
|||
#include <libsupport/KeyMap.h>
|
||||
#include <libsupport/List.h>
|
||||
|
||||
#include "Maps.h"
|
||||
|
||||
class Conversation;
|
||||
class User;
|
||||
|
||||
typedef KeyMap<BString, User*> UserMap;
|
||||
|
||||
|
||||
enum cmd_arg_type
|
||||
|
@ -61,7 +62,4 @@ private:
|
|||
List<int32> fArgTypes;
|
||||
};
|
||||
|
||||
|
||||
typedef KeyMap<BString, ChatCommand*> CommandMap;
|
||||
|
||||
#endif // CHAT_COMMAND_H
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
/*
|
||||
* Copyright 2009-2011, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _APP_H
|
||||
#define _APP_H
|
||||
|
||||
#define APP_SIGNATURE "application/x-vnd.chat-o-matic"
|
||||
#define APP_NAME "Chat-O-Matic"
|
||||
|
||||
#endif // _APP_H
|
|
@ -1,5 +1,3 @@
|
|||
#include "ChatOMatic.h"
|
||||
|
||||
resource app_signature APP_SIGNATURE;
|
||||
|
||||
resource app_version {
|
||||
|
@ -18,3 +16,18 @@ resource app_flags B_SINGLE_LAUNCH;
|
|||
|
||||
resource file_types message;
|
||||
|
||||
resource vector_icon {
|
||||
$"6E636966040500020106033D835C3C19B2BA8B0B3C20794769624A510E00FFFF"
|
||||
$"FFB4FFE405FFFFA405020106023D835C3C19B2BA8B0B3C20794769624A510E00"
|
||||
$"FFE405FFFFA405020106033D429E3C5148BB5ADA3C5C1B4A23AA46EC1800FFFF"
|
||||
$"FFB47FE583FF04B10C0902093F404644383C273F2E3A244122482245224D2755"
|
||||
$"245126572256245725582A5828592C5A315C2F5B345D3C5E385E425E4957475C"
|
||||
$"4D4E02043F4044433D3FBC95BE953B3D333D3D493844424E4A5148534A4A0403"
|
||||
$"3B2F4E2F4E2D4E2A4D2F532D522F530003334F334F364F345337533755325636"
|
||||
$"59325602085645C8FEC3AFCA30C0E55E3A5E405EBA4D52B58359B71B4AB38537"
|
||||
$"B51D3EB31FBA16B69933353130363E4A4641444D475346C657C27B554BCB01C6"
|
||||
$"35584F5A4F080239BA0539BA6B0802BD1CBC1DBD2FBCA908023E37423904032E"
|
||||
$"4535473C4739473F4540070A000100123FFFFE2FDACEAFDACE3FFFFE3AB6A5B8"
|
||||
$"4CC101178400040A010100000A020101000A000202031001178210040A000104"
|
||||
$"1001178400040A030104000A000407050608100117821004"
|
||||
};
|
||||
|
|
|
@ -88,9 +88,11 @@ public:
|
|||
//! Protocol icon
|
||||
virtual BBitmap* Icon() const { return NULL; }
|
||||
|
||||
//! Add-on's path
|
||||
virtual void SetAddOnPath(BPath path) = 0;
|
||||
//! Pertinent paths
|
||||
virtual BPath AddOnPath() = 0;
|
||||
virtual void SetAddOnPath(BPath path) = 0;
|
||||
virtual void SetAccountCachePath(BPath path) { };
|
||||
virtual void SetAddOnCachePath(BPath path) { };
|
||||
|
||||
//! Name of account file (leaf)
|
||||
virtual const char* GetName() = 0;
|
||||
|
|
|
@ -27,6 +27,13 @@ ChatProtocolAddOn::ChatProtocolAddOn(image_id image, const char* path, int32 sub
|
|||
}
|
||||
|
||||
|
||||
ChatProtocolAddOn::~ChatProtocolAddOn()
|
||||
{
|
||||
delete fIcon;
|
||||
unload_add_on(fImage);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ChatProtocolAddOn::InitCheck() const
|
||||
{
|
||||
|
@ -52,7 +59,7 @@ ChatProtocol*
|
|||
ChatProtocolAddOn::ProtocolAt(int32 i) const
|
||||
{
|
||||
ChatProtocol* proto = fGetProtocol(i);
|
||||
proto->SetAddOnPath(BPath(fPath.String()));
|
||||
proto->SetAddOnPath(fPath.String());
|
||||
return proto;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ class ChatProtocolAddOn {
|
|||
public:
|
||||
ChatProtocolAddOn(image_id image, const char* path,
|
||||
int32 subProto=0);
|
||||
~ChatProtocolAddOn();
|
||||
|
||||
status_t InitCheck() const;
|
||||
|
||||
|
|
|
@ -262,8 +262,8 @@ enum im_what_code {
|
|||
|
||||
/*! Quietly add user(s) to the chat →App
|
||||
Shouldn't be sent automatically on joining a room.
|
||||
Requires: String "chat_id", StringList "user_id"
|
||||
Accepts: StringList "user_name" */
|
||||
Requires: String "chat_id", Strings "user_id"
|
||||
Accepts: Strings "user_name" */
|
||||
IM_ROOM_PARTICIPANTS = 159,
|
||||
|
||||
/*! User has explicitly joined →App
|
||||
|
@ -405,6 +405,29 @@ enum im_what_code {
|
|||
IM_ROOM_PARTICIPANT_STOPPED_TYPING = 211,
|
||||
|
||||
|
||||
/*
|
||||
* Room directory messages
|
||||
*/
|
||||
|
||||
/*! Request a list of rooms →Protocol */
|
||||
IM_GET_ROOM_DIRECTORY = 230,
|
||||
|
||||
/*! Send a room in the directory →App
|
||||
This can be used to send either a list of publically available rooms
|
||||
or a list of "hidden"/"disabled" rooms, one-by-one.
|
||||
|
||||
A room listed thanks to this message might be joined through
|
||||
IM_JOIN_ROOM. Since IM_JOIN_ROOM accepts slots from the template, you
|
||||
must fill in IM_ROOM_DIRECTORY messages with any required custom slots
|
||||
you use for room-joining― the message you send will be actually be
|
||||
copied and sent back verbatim (with im_what changed to IM_JOIN_ROOM)
|
||||
to join.
|
||||
Requires: Strings "chat_id"
|
||||
Allows: String "chat_name", String "subject", String "category",
|
||||
int32 "user_count" */
|
||||
IM_ROOM_DIRECTORY = 231,
|
||||
|
||||
|
||||
/*
|
||||
* Misc. UI messages
|
||||
*/
|
||||
|
|
|
@ -35,8 +35,5 @@ Contact::_EnsureCachePath()
|
|||
{
|
||||
if (fCachePath.InitCheck() == B_OK)
|
||||
return;
|
||||
fCachePath.SetTo(ContactCachePath(fLooper->Protocol()->GetName(),
|
||||
fID.String()));
|
||||
fCachePath = ContactCachePath(fLooper->Protocol()->GetName(), fID.String());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2021, Jaidyn Levesque <jadedctrl@teknik.io>
|
||||
* Copyright 2021-2022, Jaidyn Levesque <jadedctrl@teknik.io>
|
||||
* All rights reserved. Distributed under the terms of the MIT license.
|
||||
*/
|
||||
|
||||
|
@ -14,7 +14,6 @@
|
|||
|
||||
#include "AppConstants.h"
|
||||
#include "AppPreferences.h"
|
||||
#include "ChatOMatic.h"
|
||||
#include "ChatProtocolMessages.h"
|
||||
#include "RenderView.h"
|
||||
#include "ChatCommand.h"
|
||||
|
@ -26,6 +25,7 @@
|
|||
#include "NotifyMessage.h"
|
||||
#include "ProtocolLooper.h"
|
||||
#include "ProtocolManager.h"
|
||||
#include "Role.h"
|
||||
#include "Server.h"
|
||||
#include "TheApp.h"
|
||||
#include "Utils.h"
|
||||
|
@ -147,10 +147,10 @@ Conversation::ImMessage(BMessage* msg)
|
|||
|
||||
// Misc. features Caya contributors planned on adding
|
||||
BWindow* mainWin = ((TheApp*)be_app)->GetMainWindow();
|
||||
if (win == NULL && AppPreferences::Get()->MarkUnreadWindow == true)
|
||||
if (winFocus == false && AppPreferences::Get()->MarkUnreadWindow == true)
|
||||
mainWin->SetTitle(BString(mainWin->Title()).Prepend("[!]"));
|
||||
|
||||
if (win == NULL && AppPreferences::Get()->MoveToCurrentWorkspace)
|
||||
if (winFocus == false && AppPreferences::Get()->MoveToCurrentWorkspace)
|
||||
mainWin->SetWorkspaces(B_CURRENT_WORKSPACE);
|
||||
|
||||
if (win == NULL && AppPreferences::Get()->RaiseOnMessageReceived)
|
||||
|
@ -158,9 +158,9 @@ Conversation::ImMessage(BMessage* msg)
|
|||
|
||||
|
||||
// If unattached, highlight the ConversationItem
|
||||
if (win == NULL && mentioned == true)
|
||||
if ((win == NULL || GetView()->IsHidden() == true) && mentioned == true)
|
||||
NotifyInteger(INT_NEW_MENTION, fNotifyMentionCount);
|
||||
else if (win == NULL)
|
||||
else if (win == NULL || GetView()->IsHidden())
|
||||
NotifyInteger(INT_NEW_MESSAGE, fNotifyMessageCount);
|
||||
|
||||
break;
|
||||
|
@ -187,7 +187,7 @@ Conversation::ImMessage(BMessage* msg)
|
|||
|
||||
BString name = CommandName(body);
|
||||
BString args = CommandArgs(body);
|
||||
ChatCommand* cmd = _GetServer()->CommandById(name, fLooper->GetInstance());
|
||||
ChatCommand* cmd = Server::Get()->CommandById(name, fLooper->GetInstance());
|
||||
|
||||
if (cmd == NULL) {
|
||||
if (name == "me")
|
||||
|
@ -320,7 +320,7 @@ Conversation::ObserveString(int32 what, BString str)
|
|||
void
|
||||
Conversation::ObserveInteger(int32 what, int32 value)
|
||||
{
|
||||
if (what == INT_WINDOW_FOCUSED) {
|
||||
if (what == INT_CONV_VIEW_SELECTED) {
|
||||
fNotifyMessageCount = 0;
|
||||
fNotifyMentionCount = 0;
|
||||
}
|
||||
|
@ -576,6 +576,10 @@ Conversation::_LogChatMessage(BMessage* msg)
|
|||
BFile logFile(fCachePath.Path(), B_READ_WRITE | B_OPEN_AT_END | B_CREATE_FILE);
|
||||
WriteAttributeMessage(&logFile, "Chat:logs", &logMsg);
|
||||
|
||||
BString mime = BString("text/plain");
|
||||
logFile.WriteAttr("BEOS:TYPE", B_MIME_STRING_TYPE, 0, mime.String(),
|
||||
mime.CountChars() + 1);
|
||||
|
||||
// Plain-text logs
|
||||
// Gotta make sure the formatting's pretty!
|
||||
BString date;
|
||||
|
@ -633,8 +637,7 @@ Conversation::_EnsureCachePath()
|
|||
{
|
||||
if (fCachePath.InitCheck() == B_OK)
|
||||
return;
|
||||
fCachePath.SetTo(RoomCachePath(fLooper->Protocol()->GetName(),
|
||||
fID.String()));
|
||||
fCachePath = RoomCachePath(fLooper->Protocol()->GetName(), fID.String());
|
||||
}
|
||||
|
||||
|
||||
|
@ -653,7 +656,7 @@ Conversation::_EnsureUser(BMessage* msg, bool implicit)
|
|||
user = serverUser;
|
||||
// Not anywhere; create user
|
||||
else if (user == NULL) {
|
||||
user = new User(id, _GetServer()->Looper());
|
||||
user = new User(id, Server::Get()->Looper());
|
||||
user->SetProtocolLooper(fLooper);
|
||||
fLooper->AddUser(user);
|
||||
}
|
||||
|
@ -757,10 +760,3 @@ Conversation::_SortConversationList()
|
|||
if (fUsers.CountItems() <= 2 || fUsers.CountItems() == 3)
|
||||
((TheApp*)be_app)->GetMainWindow()->SortConversation(this);
|
||||
}
|
||||
|
||||
|
||||
Server*
|
||||
Conversation::_GetServer()
|
||||
{
|
||||
return ((TheApp*)be_app)->GetMainWindow()->GetServer();
|
||||
}
|
||||
|
|
|
@ -10,22 +10,18 @@
|
|||
#include <Path.h>
|
||||
#include <StringList.h>
|
||||
|
||||
#include <libsupport/KeyMap.h>
|
||||
|
||||
#include "Maps.h"
|
||||
#include "Notifier.h"
|
||||
#include "Observer.h"
|
||||
#include "Role.h"
|
||||
#include "Server.h"
|
||||
#include "User.h"
|
||||
|
||||
class BBitmap;
|
||||
class Contact;
|
||||
class ConversationItem;
|
||||
class ConversationView;
|
||||
class ProtocolLooper;
|
||||
class Role;
|
||||
class Server;
|
||||
|
||||
|
||||
typedef KeyMap<BString, User*> UserMap;
|
||||
typedef KeyMap<BString, Role*> RoleMap;
|
||||
class User;
|
||||
|
||||
|
||||
class Conversation : public Notifier, public Observer {
|
||||
|
@ -76,7 +72,11 @@ public:
|
|||
void SetFlags(int32 flags);
|
||||
int32 DisallowedFlags() { return fDisallowedFlags; }
|
||||
|
||||
BPath CachePath() { return fCachePath; }
|
||||
|
||||
private:
|
||||
typedef KeyMap<BString, Role*> RoleMap;
|
||||
|
||||
void _WarnUser(BString message);
|
||||
|
||||
void _LogChatMessage(BMessage* msg);
|
||||
|
@ -94,8 +94,6 @@ private:
|
|||
|
||||
void _SortConversationList();
|
||||
|
||||
Server* _GetServer();
|
||||
|
||||
BMessenger fMessenger;
|
||||
ProtocolLooper* fLooper;
|
||||
ConversationView* fChatView;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
include Make.pre
|
||||
|
||||
## Haiku Generic Makefile v2.6 ##
|
||||
|
||||
## Fill in this file to specify the project being created, and the referenced
|
||||
|
@ -8,7 +10,7 @@
|
|||
## file:///system/develop/documentation/makefile-engine.html
|
||||
|
||||
# The name of the binary.
|
||||
NAME = Chat-O-Matic
|
||||
NAME = $(APP_NAME)
|
||||
|
||||
# The type of binary, must be one of:
|
||||
# APP: Application
|
||||
|
@ -18,7 +20,7 @@ NAME = Chat-O-Matic
|
|||
TYPE = APP
|
||||
|
||||
# If you plan to use localization, specify the application's MIME signature.
|
||||
APP_MIME_SIG = application/x-vnd.chat-o-matic
|
||||
APP_MIME_SIG = $(APP_SIGNATURE)
|
||||
|
||||
# The following lines tell Pe and Eddie where the SRCS, RDEFS, and RSRCS are
|
||||
# so that Pe and Eddie can fill them in for you.
|
||||
|
@ -64,6 +66,7 @@ SRCS = \
|
|||
application/views/InviteDialogue.cpp \
|
||||
application/views/ReplicantStatusView.cpp \
|
||||
application/views/ReplicantMenuItem.cpp \
|
||||
application/views/RoomListRow.cpp \
|
||||
application/views/RosterItem.cpp \
|
||||
application/views/RosterListView.cpp \
|
||||
application/views/RosterView.cpp \
|
||||
|
@ -74,11 +77,11 @@ SRCS = \
|
|||
application/views/UserItem.cpp \
|
||||
application/views/UserListView.cpp \
|
||||
application/views/UserPopUp.cpp \
|
||||
application/windows/AboutWindow.cpp \
|
||||
application/windows/AccountsWindow.cpp \
|
||||
application/windows/ConversationInfoWindow.cpp \
|
||||
application/windows/MainWindow.cpp \
|
||||
application/windows/PreferencesWindow.cpp \
|
||||
application/windows/RoomListWindow.cpp \
|
||||
application/windows/RosterEditWindow.cpp \
|
||||
application/windows/RosterWindow.cpp \
|
||||
application/windows/TemplateWindow.cpp \
|
||||
|
@ -130,7 +133,7 @@ RSRCS =
|
|||
# - if your library does not follow the standard library naming scheme,
|
||||
# you need to specify the path to the library and it's name.
|
||||
# (e.g. for mylib.a, specify "mylib.a" or "path/mylib.a")
|
||||
LIBS = be expat interface localestub runview shared translation $(STDCPPLIBS)
|
||||
LIBS = be columnlistview expat interface localestub runview shared translation $(STDCPPLIBS)
|
||||
|
||||
|
||||
# Specify additional paths to directories following the standard libXXX.so
|
||||
|
@ -143,7 +146,9 @@ LIBPATHS =
|
|||
# Additional paths to look for system headers. These use the form
|
||||
# "#include <header>". Directories that contain the files in SRCS are
|
||||
# NOT auto-included here.
|
||||
SYSTEM_INCLUDE_PATHS = libs/
|
||||
SYSTEM_INCLUDE_PATHS = libs/ \
|
||||
$(shell findpaths -e B_FIND_PATH_HEADERS_DIRECTORY private/interface)
|
||||
|
||||
|
||||
# Additional paths paths to look for local headers. These use the form
|
||||
# #include "header". Directories that contain the files in SRCS are
|
||||
|
@ -166,7 +171,7 @@ LOCALES = en eo
|
|||
# use. For example, setting DEFINES to "DEBUG=1" will cause the compiler
|
||||
# option "-DDEBUG=1" to be used. Setting DEFINES to "DEBUG" would pass
|
||||
# "-DDEBUG" on the compiler's command line.
|
||||
DEFINES :=
|
||||
DEFINES =
|
||||
|
||||
# Specify the warning level. Either NONE (suppress all warnings),
|
||||
# ALL (enable all warnings), or leave blank (enable default warnings).
|
||||
|
@ -202,7 +207,6 @@ DRIVER_PATH =
|
|||
## Include the Makefile-Engine
|
||||
DEVEL_DIRECTORY := /boot/system/develop/
|
||||
include $(DEVEL_DIRECTORY)/etc/makefile-engine
|
||||
|
||||
include Makefile.common
|
||||
include Make.post
|
||||
|
||||
CC = g++
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright 2022, Jaidyn Levesque <jadedctrl@teknik.io>
|
||||
* All rights reserved. Distributed under the terms of the MIT license.
|
||||
*/
|
||||
#ifndef _MAPS_H
|
||||
#define _MAPS_H
|
||||
|
||||
#include <String.h>
|
||||
|
||||
#include "libsupport/KeyMap.h"
|
||||
|
||||
class ChatCommand;
|
||||
class Command;
|
||||
class Contact;
|
||||
class Conversation;
|
||||
class User;
|
||||
|
||||
|
||||
// Defining some commonly-used KeyMaps
|
||||
typedef KeyMap<BString, bigtime_t> AccountInstances;
|
||||
typedef KeyMap<BString, ChatCommand*> CommandMap;
|
||||
typedef KeyMap<BString, Conversation*> ChatMap;
|
||||
typedef KeyMap<BString, Contact*> RosterMap;
|
||||
typedef KeyMap<BString, User*> UserMap;
|
||||
|
||||
#endif // _MAPS_H
|
|
@ -21,7 +21,7 @@ enum {
|
|||
INT_NEW_MESSAGE,
|
||||
INT_NEW_MENTION,
|
||||
|
||||
INT_WINDOW_FOCUSED,
|
||||
INT_CONV_VIEW_SELECTED,
|
||||
INT_ACCOUNTS_UPDATED
|
||||
};
|
||||
|
||||
|
|
|
@ -13,12 +13,13 @@
|
|||
#include "ProtocolLooper.h"
|
||||
|
||||
#include <Bitmap.h>
|
||||
#include <Catalog.h>
|
||||
#include <String.h>
|
||||
|
||||
#include "Account.h"
|
||||
#include "AppMessages.h"
|
||||
#include "ChatOMatic.h"
|
||||
#include "ChatProtocolMessages.h"
|
||||
#include "Contact.h"
|
||||
#include "Conversation.h"
|
||||
#include "ConversationAccountItem.h"
|
||||
#include "ConversationView.h"
|
||||
|
@ -254,6 +255,10 @@ ProtocolLooper::LoadCommands()
|
|||
}
|
||||
|
||||
|
||||
#undef B_TRANSLATION_CONTEXT
|
||||
#define B_TRANSLATION_CONTEXT "Protocol system buffer"
|
||||
|
||||
|
||||
void
|
||||
ProtocolLooper::_InitChatView()
|
||||
{
|
||||
|
|
|
@ -11,10 +11,9 @@
|
|||
#include <ObjectList.h>
|
||||
#include <String.h>
|
||||
|
||||
#include <libsupport/KeyMap.h>
|
||||
|
||||
#include "ChatProtocol.h"
|
||||
#include "ChatCommand.h"
|
||||
#include "Maps.h"
|
||||
|
||||
class Contact;
|
||||
class Conversation;
|
||||
|
@ -23,11 +22,6 @@ class ConversationView;
|
|||
class User;
|
||||
|
||||
|
||||
typedef KeyMap<BString, Conversation*> ChatMap;
|
||||
typedef KeyMap<BString, Contact*> RosterMap;
|
||||
typedef KeyMap<BString, User*> UserMap;
|
||||
|
||||
|
||||
class ProtocolLooper : public BLooper {
|
||||
public:
|
||||
ProtocolLooper(ChatProtocol* protocol, int64 instance);
|
||||
|
|
|
@ -47,10 +47,18 @@ ProtocolManager::Init(BDirectory dir, BHandler* target)
|
|||
if (id < 0)
|
||||
continue;
|
||||
|
||||
// If add-on's API version fits then load accounts…
|
||||
// Refuse to load add-on under some circumstances…
|
||||
ChatProtocolAddOn* addOn = new ChatProtocolAddOn(id, path.Path());
|
||||
if (addOn->Version() != APP_VERSION || ProtocolAddOn(addOn->Signature()) != NULL) {
|
||||
if (addOn->Version() != APP_VERSION)
|
||||
printf("%s not loaded, due to insufficient version (%i v %i).\n",
|
||||
addOn->Signature(), addOn->Version(), APP_VERSION);
|
||||
else if (ProtocolAddOn(addOn->Signature()) != NULL)
|
||||
printf("%s not loaded, due to another instance already having been loaded.\n",
|
||||
addOn->Signature());
|
||||
delete addOn;
|
||||
continue;
|
||||
}
|
||||
ret = true;
|
||||
|
||||
// If add-on has multiple protocols, also load them
|
||||
|
@ -132,7 +140,7 @@ ProtocolManager::AddAccount(ChatProtocolAddOn* addOn, const char* account,
|
|||
{
|
||||
// If already active, don't double-dip!
|
||||
bool active = false;
|
||||
_Server()->GetActiveAccounts().ValueFor(BString(account), &active);
|
||||
Server::Get()->GetActiveAccounts().ValueFor(BString(account), &active);
|
||||
if (active == true)
|
||||
return;
|
||||
|
||||
|
@ -157,7 +165,7 @@ ProtocolManager::AddAccount(ChatProtocolAddOn* addOn, const char* account,
|
|||
|
||||
fProtocolMap.AddItem(instanceId, cayap);
|
||||
|
||||
_Server()->AddProtocolLooper(instanceId, cayap);
|
||||
Server::Get()->AddProtocolLooper(instanceId, cayap);
|
||||
}
|
||||
|
||||
|
||||
|
@ -181,7 +189,7 @@ ProtocolManager::DisableAccount(ProtocolSettings* settings, const char* account)
|
|||
{
|
||||
bool active = false;
|
||||
int64 instance
|
||||
= _Server()->GetActiveAccounts().ValueFor(BString(account), &active);
|
||||
= Server::Get()->GetActiveAccounts().ValueFor(BString(account), &active);
|
||||
if (active == false)
|
||||
return;
|
||||
|
||||
|
@ -206,7 +214,7 @@ ProtocolManager::ToggleAccount(ProtocolSettings* settings, const char* account)
|
|||
{
|
||||
bool active = false;
|
||||
int64 instance
|
||||
= _Server()->GetActiveAccounts().ValueFor(BString(account), &active);
|
||||
= Server::Get()->GetActiveAccounts().ValueFor(BString(account), &active);
|
||||
|
||||
if (active == true)
|
||||
DisableAccount(settings, account);
|
||||
|
@ -272,11 +280,3 @@ ProtocolManager::_MainWin()
|
|||
{
|
||||
return ((TheApp*)be_app)->GetMainWindow();
|
||||
}
|
||||
|
||||
|
||||
Server*
|
||||
ProtocolManager::_Server()
|
||||
{
|
||||
MainWindow* win = _MainWin();
|
||||
return win ? win->GetServer() : NULL;
|
||||
}
|
||||
|
|
|
@ -64,7 +64,6 @@ private:
|
|||
BEntry accountEntry, BHandler* target);
|
||||
|
||||
MainWindow* _MainWin();
|
||||
Server* _Server();
|
||||
|
||||
AddOnMap fAddOnMap;
|
||||
ProtocolMap fProtocolMap;
|
||||
|
|
|
@ -49,7 +49,7 @@ ProtocolSettings::Accounts() const
|
|||
{
|
||||
BObjectList<BString> list(true);
|
||||
|
||||
BPath path(AccountPath(fAddOn->Signature(), fAddOn->ProtoSignature()));
|
||||
BPath path = AccountPath(fAddOn->Signature(), fAddOn->ProtoSignature());
|
||||
|
||||
if (path.InitCheck() != B_OK)
|
||||
return list;
|
||||
|
@ -93,7 +93,7 @@ ProtocolSettings::Load(const char* account, BMessage** settings)
|
|||
status_t ret = B_ERROR;
|
||||
|
||||
// Find user's settings path
|
||||
BPath path(AccountPath(fAddOn->Signature(), fAddOn->ProtoSignature()));
|
||||
BPath path = AccountPath(fAddOn->Signature(), fAddOn->ProtoSignature());
|
||||
|
||||
if ((ret = path.InitCheck()) != B_OK)
|
||||
return ret;
|
||||
|
@ -127,7 +127,7 @@ status_t
|
|||
ProtocolSettings::Save(const char* account, BMessage settings)
|
||||
{
|
||||
// Find user's settings path
|
||||
BPath path(AccountPath(fAddOn->Signature(), fAddOn->ProtoSignature()));
|
||||
BPath path = AccountPath(fAddOn->Signature(), fAddOn->ProtoSignature());
|
||||
|
||||
status_t ret;
|
||||
if ((ret = path.InitCheck()) != B_OK)
|
||||
|
@ -146,7 +146,7 @@ ProtocolSettings::Rename(const char* from, const char* to)
|
|||
status_t ret = B_ERROR;
|
||||
|
||||
// Find user's settings path
|
||||
BPath path(AccountPath(fAddOn->Signature(), fAddOn->ProtoSignature()));
|
||||
BPath path = AccountPath(fAddOn->Signature(), fAddOn->ProtoSignature());
|
||||
|
||||
if ((ret = path.InitCheck()) != B_OK)
|
||||
return ret;
|
||||
|
@ -168,7 +168,7 @@ ProtocolSettings::Delete(const char* account)
|
|||
status_t ret = B_ERROR;
|
||||
|
||||
// Find user's settings path
|
||||
BPath path(AccountPath(fAddOn->Signature(), fAddOn->ProtoSignature()));
|
||||
BPath path = AccountPath(fAddOn->Signature(), fAddOn->ProtoSignature());
|
||||
|
||||
if ((ret = path.InitCheck()) != B_OK)
|
||||
return ret;
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include "Account.h"
|
||||
#include "AppMessages.h"
|
||||
#include "AppPreferences.h"
|
||||
#include "ChatOMatic.h"
|
||||
#include "ChatProtocol.h"
|
||||
#include "ConversationInfoWindow.h"
|
||||
#include "ConversationView.h"
|
||||
|
@ -49,6 +48,9 @@
|
|||
#define B_TRANSLATION_CONTEXT "Server"
|
||||
|
||||
|
||||
Server* Server::fInstance = NULL;
|
||||
|
||||
|
||||
Server::Server()
|
||||
:
|
||||
BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE)
|
||||
|
@ -83,6 +85,15 @@ Server::Server()
|
|||
}
|
||||
|
||||
|
||||
Server*
|
||||
Server::Get()
|
||||
{
|
||||
if (fInstance == NULL)
|
||||
fInstance = new Server();
|
||||
return fInstance;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Server::Quit()
|
||||
{
|
||||
|
@ -628,7 +639,7 @@ Server::ImMessage(BMessage* msg)
|
|||
// Join cached rooms
|
||||
BEntry entry;
|
||||
char fileName[B_FILE_NAME_LENGTH] = {'\0'};
|
||||
BDirectory dir(RoomsCachePath(looper->Protocol()->GetName()));
|
||||
BDirectory dir(RoomsCachePath(looper->Protocol()->GetName()).Path());
|
||||
|
||||
while (dir.GetNextEntry(&entry, true) == B_OK)
|
||||
if (entry.GetName(fileName) == B_OK) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright 2009-2011, Andrea Anzani. All rights reserved.
|
||||
* Copyright 2009-2011, Pier Luigi Fiorini. All rights reserved.
|
||||
* Copyright 2021-2022, Jaidyn Levesque. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _SERVER_H
|
||||
|
@ -25,14 +26,10 @@ class RosterItem;
|
|||
class ProtocolLooper;
|
||||
|
||||
|
||||
typedef KeyMap<bigtime_t, ProtocolLooper*> ProtocolLoopers;
|
||||
typedef KeyMap<BString, bigtime_t> AccountInstances;
|
||||
typedef KeyMap<BString, bool> BoolMap;
|
||||
|
||||
|
||||
class Server: public BMessageFilter, public Notifier {
|
||||
public:
|
||||
Server();
|
||||
static Server* Get();
|
||||
void Quit();
|
||||
void LoginAll();
|
||||
void Login(ProtocolLooper* looper);
|
||||
|
@ -70,6 +67,9 @@ public:
|
|||
BObjectList<BMessage> UserPopUpItems();
|
||||
|
||||
private:
|
||||
typedef KeyMap<BString, bool> BoolMap;
|
||||
typedef KeyMap<bigtime_t, ProtocolLooper*> ProtocolLoopers;
|
||||
|
||||
ProtocolLooper* _LooperFromMessage(BMessage* message);
|
||||
|
||||
Contact* _EnsureContact(BMessage* message);
|
||||
|
@ -87,6 +87,8 @@ private:
|
|||
|
||||
void _ReplicantStatusNotify(UserStatus status);
|
||||
|
||||
static Server* fInstance;
|
||||
|
||||
ProtocolLoopers fLoopers;
|
||||
AccountInstances fAccounts;
|
||||
BoolMap fAccountEnabled;
|
||||
|
|
|
@ -11,10 +11,8 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "ChatProtocolMessages.h"
|
||||
#include "MainWindow.h"
|
||||
#include "NotifyMessage.h"
|
||||
#include "Server.h"
|
||||
#include "TheApp.h"
|
||||
|
||||
|
||||
static StatusManager* fInstance = NULL;
|
||||
|
@ -52,14 +50,12 @@ StatusManager::SetNickname(BString nick, int64 instance)
|
|||
msg->AddString("user_name", nick);
|
||||
|
||||
// Send message
|
||||
TheApp* theApp = reinterpret_cast<TheApp*>(be_app);
|
||||
MainWindow* win = theApp->GetMainWindow();
|
||||
if (instance > -1) {
|
||||
msg->AddInt64("instance", instance);
|
||||
win->GetServer()->SendProtocolMessage(msg);
|
||||
Server::Get()->SendProtocolMessage(msg);
|
||||
}
|
||||
else
|
||||
win->GetServer()->SendAllProtocolMessage(msg);
|
||||
Server::Get()->SendAllProtocolMessage(msg);
|
||||
}
|
||||
|
||||
|
||||
|
@ -91,15 +87,12 @@ StatusManager::SetStatus(UserStatus status, const char* str, int64 instance)
|
|||
msg->AddString("message", str);
|
||||
|
||||
// Send message
|
||||
TheApp* theApp = reinterpret_cast<TheApp*>(be_app);
|
||||
MainWindow* win = theApp->GetMainWindow();
|
||||
|
||||
if (instance > -1) {
|
||||
msg->AddInt64("instance", instance);
|
||||
win->GetServer()->SendProtocolMessage(msg);
|
||||
Server::Get()->SendProtocolMessage(msg);
|
||||
}
|
||||
else
|
||||
win->GetServer()->SendAllProtocolMessage(msg);
|
||||
Server::Get()->SendAllProtocolMessage(msg);
|
||||
|
||||
// Notify status change
|
||||
fStatus = status;
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <AboutWindow.h>
|
||||
#include <Alert.h>
|
||||
#include <Catalog.h>
|
||||
#include <Path.h>
|
||||
|
@ -21,8 +22,6 @@
|
|||
|
||||
#include <librunview/Emoticor.h>
|
||||
|
||||
#include "AboutWindow.h"
|
||||
#include "ChatOMatic.h"
|
||||
#include "AppMessages.h"
|
||||
#include "FilePanel.h"
|
||||
#include "MainWindow.h"
|
||||
|
@ -90,7 +89,7 @@ TheApp::ReadyToRun()
|
|||
|
||||
if (win == false) {
|
||||
BString msg(B_TRANSLATE("No protocols found!\nPlease make sure %app% was installed correctly."));
|
||||
msg.ReplaceAll("%app%", APP_NAME);
|
||||
msg.ReplaceAll("%app%", B_TRANSLATE_SYSTEM_NAME(APP_NAME));
|
||||
BAlert* alert = new BAlert("", msg.String(), B_TRANSLATE("Ouch!"));
|
||||
alert->Go();
|
||||
PostMessage(B_QUIT_REQUESTED);
|
||||
|
@ -109,28 +108,21 @@ TheApp::AboutRequested()
|
|||
"2009-2010 Andrea Anzani",
|
||||
"2010-2015 Dario Casalinuovo",
|
||||
"2009-2010 Pier Luigi Fiorini",
|
||||
"2021 Jaidyn Levesque",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char* authors[] = {
|
||||
"Andrea Anzani",
|
||||
"Dario Casalinuovo",
|
||||
"Pier Luigi Fiorini",
|
||||
"Jaidyn Levesque",
|
||||
NULL
|
||||
};
|
||||
|
||||
BString extraInfo(B_TRANSLATE("%app% is released under the MIT License.\n"
|
||||
"Add-on and library licenses may vary.\n"
|
||||
"Built: %buildDate%"));
|
||||
extraInfo.ReplaceAll("%buildDate", BUILD_DATE);
|
||||
extraInfo.ReplaceAll("%buildDate%", BUILD_DATE);
|
||||
extraInfo.ReplaceAll("%app%", B_TRANSLATE_SYSTEM_NAME(APP_NAME));
|
||||
|
||||
AboutWindow* about = new AboutWindow(B_TRANSLATE_SYSTEM_NAME(APP_NAME),
|
||||
holders, authors, extraInfo.String());
|
||||
BAboutWindow* about = new BAboutWindow(B_TRANSLATE_SYSTEM_NAME(APP_NAME),
|
||||
APP_SIGNATURE);
|
||||
about->AddDescription(B_TRANSLATE("A multi-protocol chat program."));
|
||||
about->AddCopyright(2021, "Jaidyn Levesque", holders);
|
||||
about->AddExtraInfo(extraInfo);
|
||||
about->Show();
|
||||
delete about;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -227,8 +227,7 @@ User::_EnsureCachePath()
|
|||
{
|
||||
if (fCachePath.InitCheck() == B_OK)
|
||||
return;
|
||||
fCachePath.SetTo(UserCachePath(fLooper->Protocol()->GetName(),
|
||||
fID.String()));
|
||||
fCachePath = UserCachePath(fLooper->Protocol()->GetName(), fID.String());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -14,8 +14,7 @@
|
|||
#include <Path.h>
|
||||
#include <String.h>
|
||||
|
||||
#include <libsupport/KeyMap.h>
|
||||
|
||||
#include "Maps.h"
|
||||
#include "Notifier.h"
|
||||
#include "UserStatus.h"
|
||||
|
||||
|
@ -26,9 +25,6 @@ class ProtocolLooper;
|
|||
class UserPopUp;
|
||||
|
||||
|
||||
typedef KeyMap<BString, Conversation*> ChatMap;
|
||||
|
||||
|
||||
class User : public Notifier {
|
||||
public:
|
||||
User(BString id, BMessenger msgn);
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
#include <kernel/fs_attr.h>
|
||||
|
||||
#include "ChatOMatic.h"
|
||||
#include "Utils.h"
|
||||
|
||||
|
||||
|
@ -151,88 +150,104 @@ AccountPath(const char* signature, const char* subsignature)
|
|||
}
|
||||
|
||||
|
||||
const char*
|
||||
BPath
|
||||
CachePath()
|
||||
{
|
||||
BPath path(SettingsPath());
|
||||
if (path.InitCheck() != B_OK)
|
||||
return NULL;
|
||||
|
||||
path.Append("Cache");
|
||||
if (create_directory(path.Path(), 0755) != B_OK)
|
||||
return NULL;
|
||||
return path.Path();
|
||||
BPath path = SettingsPath();
|
||||
path.Append("Cache/");
|
||||
create_directory(path.Path(), 0755);
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
BPath
|
||||
AccountCachePath(const char* accountName)
|
||||
{
|
||||
BPath path(CachePath());
|
||||
path.Append("Accounts");
|
||||
if (path.InitCheck() != B_OK)
|
||||
return NULL;
|
||||
|
||||
BPath path = CachePath();
|
||||
path.Append("Accounts/");
|
||||
path.Append(accountName);
|
||||
if (create_directory(path.Path(), 0755) != B_OK)
|
||||
return NULL;
|
||||
return path.Path();
|
||||
create_directory(path.Path(), 0755);
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
BPath
|
||||
RoomsCachePath(const char* accountName)
|
||||
{
|
||||
BPath path(AccountCachePath(accountName));
|
||||
if (path.InitCheck() != B_OK)
|
||||
return NULL;
|
||||
|
||||
path.Append("Rooms");
|
||||
if (create_directory(path.Path(), 0755) != B_OK)
|
||||
return NULL;
|
||||
return path.Path();
|
||||
return RoomsCachePath(AccountCachePath(accountName));
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
BPath
|
||||
RoomsCachePath(BPath accPath)
|
||||
{
|
||||
accPath.Append("Rooms/");
|
||||
create_directory(accPath.Path(), 0755);
|
||||
return accPath;
|
||||
}
|
||||
|
||||
|
||||
BPath
|
||||
RoomCachePath(const char* accountName, const char* roomIdentifier)
|
||||
{
|
||||
BPath path(RoomsCachePath(accountName));
|
||||
if (path.InitCheck() != B_OK)
|
||||
return NULL;
|
||||
|
||||
path.Append(roomIdentifier);
|
||||
return path.Path();
|
||||
return RoomCachePath(AccountCachePath(accountName), roomIdentifier);
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
BPath
|
||||
RoomCachePath(BPath accPath, const char* roomIdentifier)
|
||||
{
|
||||
BPath path = RoomsCachePath(accPath);
|
||||
path.Append(roomIdentifier);
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
BPath
|
||||
UserCachePath(const char* accountName, const char* userIdentifier)
|
||||
{
|
||||
BPath path(AccountCachePath(accountName));
|
||||
if (path.InitCheck() != B_OK)
|
||||
return NULL;
|
||||
|
||||
path.Append("Users");
|
||||
if (create_directory(path.Path(), 0755) != B_OK)
|
||||
return NULL;
|
||||
path.Append(userIdentifier);
|
||||
return path.Path();
|
||||
return UserCachePath(AccountCachePath(accountName), userIdentifier);
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
BPath
|
||||
UserCachePath(BPath accPath, const char* userIdentifier)
|
||||
{
|
||||
accPath.Append("Users/");
|
||||
create_directory(accPath.Path(), 0755);
|
||||
|
||||
accPath.Append(userIdentifier);
|
||||
return accPath;
|
||||
}
|
||||
|
||||
|
||||
BPath
|
||||
ContactCachePath(const char* accountName, const char* userIdentifier)
|
||||
{
|
||||
BPath path(AccountCachePath(accountName));
|
||||
if (path.InitCheck() != B_OK)
|
||||
return NULL;
|
||||
path.Append("Contacts");
|
||||
return ContactCachePath(AccountCachePath(accountName), userIdentifier);
|
||||
}
|
||||
|
||||
if (create_directory(path.Path(), 0755) != B_OK)
|
||||
return NULL;
|
||||
path.Append(userIdentifier);
|
||||
return path.Path();
|
||||
|
||||
BPath
|
||||
ContactCachePath(BPath accPath, const char* userIdentifier)
|
||||
{
|
||||
accPath.Append("Contacts/");
|
||||
create_directory(accPath.Path(), 0755);
|
||||
|
||||
accPath.Append(userIdentifier);
|
||||
return accPath;
|
||||
}
|
||||
|
||||
|
||||
BPath
|
||||
AddOnCachePath(const char* signature)
|
||||
{
|
||||
BPath path = CachePath();
|
||||
path.Append("Add-Ons/");
|
||||
path.Append(signature);
|
||||
|
||||
create_directory(path.Path(), 0755);
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include <Resources.h>
|
||||
|
||||
#include "AppConstants.h"
|
||||
#include "Server.h"
|
||||
#include "UserStatus.h"
|
||||
|
||||
class BMenu;
|
||||
|
||||
|
@ -36,12 +36,17 @@ const char* SettingsPath();
|
|||
const char* AccountsPath();
|
||||
const char* AccountPath(const char* signature, const char* subsignature);
|
||||
|
||||
const char* CachePath();
|
||||
const char* AccountCachePath(const char* accountName);
|
||||
const char* RoomsCachePath(const char* accountName);
|
||||
const char* RoomCachePath(const char* accountName, const char* roomIdentifier);
|
||||
const char* UserCachePath(const char* accountName, const char* userIdentifier);
|
||||
const char* ContactCachePath(const char* accountName, const char* userIdentifier);
|
||||
BPath CachePath();
|
||||
BPath AccountCachePath(const char* accountName);
|
||||
BPath RoomsCachePath(const char* accountName);
|
||||
BPath RoomsCachePath(BPath accPath);
|
||||
BPath RoomCachePath(const char* accountName, const char* roomIdentifier);
|
||||
BPath RoomCachePath(BPath accPath, const char* roomIdentifier);
|
||||
BPath UserCachePath(const char* accountName, const char* userIdentifier);
|
||||
BPath UserCachePath(BPath accPath, const char* userIdentifier);
|
||||
BPath ContactCachePath(const char* accountName, const char* userIdentifier);
|
||||
BPath ContactCachePath(BPath accPath, const char* userIdentifier);
|
||||
BPath AddOnCachePath(const char* signature);
|
||||
|
||||
rgb_color TintColor(rgb_color color, int severity);
|
||||
rgb_color ForegroundColor(rgb_color background);
|
||||
|
@ -55,4 +60,3 @@ extern "C" status_t our_image(image_info& image);
|
|||
|
||||
|
||||
#endif // _APP_UTILS_H
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include "AppPreferences.h"
|
||||
|
||||
#include <Path.h>
|
||||
|
||||
#include "Utils.h"
|
||||
|
||||
|
||||
|
@ -44,6 +46,7 @@ AppPreferences::Load()
|
|||
HideDeskbar = settings.GetBool("HideDeskbar", false);
|
||||
DisableReplicant = settings.GetBool("DisableReplicant", true);
|
||||
DisableQuitConfirm = settings.GetBool("DisableQuitConfirm", false);
|
||||
MembershipUpdates = settings.GetBool("MembershipUpdates", true);
|
||||
IgnoreEmoticons = settings.GetBool("IgnoreEmoticons", true);
|
||||
HideOffline = settings.GetBool("HideOffline", false);
|
||||
|
||||
|
@ -56,6 +59,7 @@ AppPreferences::Load()
|
|||
ChatViewVertSendWeight = settings.GetFloat("ChatViewVertSendWeight", 1);
|
||||
|
||||
MainWindowRect = settings.GetRect("MainWindowRect", BRect(0, 0, 600, 400));
|
||||
RoomDirectoryRect = settings.GetRect("RoomDirectoryRect", BRect(0, 0, 630, 330));
|
||||
}
|
||||
|
||||
|
||||
|
@ -78,6 +82,7 @@ AppPreferences::Save()
|
|||
settings.AddBool("DisableReplicant", DisableReplicant);
|
||||
settings.AddBool("DisableQuitConfirm", DisableQuitConfirm);
|
||||
settings.AddBool("IgnoreEmoticons", IgnoreEmoticons);
|
||||
settings.AddBool("MembershipUpdates", MembershipUpdates);
|
||||
settings.AddBool("HideOffline", HideOffline);
|
||||
|
||||
settings.AddFloat("MainWindowListWeight", MainWindowListWeight);
|
||||
|
@ -89,6 +94,7 @@ AppPreferences::Save()
|
|||
settings.AddFloat("ChatViewVertSendWeight", ChatViewVertSendWeight);
|
||||
|
||||
settings.AddRect("MainWindowRect", MainWindowRect);
|
||||
settings.AddRect("RoomDirectoryRect", RoomDirectoryRect);
|
||||
|
||||
if (file.InitCheck() == B_OK)
|
||||
settings.Flatten(&file);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright 2010, Oliver Ruiz Dorantes. All rights reserved.
|
||||
* Copyright 2012, Casalinuovo Dario. All rights reserved.
|
||||
* Copyright 2021, Jaidyn Levesque <jadedctrl@teknik.io>
|
||||
* Copyright 2021-2022, Jaidyn Levesque <jadedctrl@teknik.io>
|
||||
* All rights reserved. Distributed under the terms of the MIT license.
|
||||
*/
|
||||
#ifndef _APP_PREFERENCES_H
|
||||
|
@ -33,6 +33,7 @@ public:
|
|||
bool DisableQuitConfirm;
|
||||
|
||||
bool IgnoreEmoticons;
|
||||
bool MembershipUpdates;
|
||||
|
||||
bool HideOffline;
|
||||
|
||||
|
@ -45,6 +46,7 @@ public:
|
|||
float ChatViewVertSendWeight;
|
||||
|
||||
BRect MainWindowRect;
|
||||
BRect RoomDirectoryRect;
|
||||
|
||||
private:
|
||||
const char* _PreferencesPath();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright 2010, Oliver Ruiz Dorantes. All rights reserved.
|
||||
* Copyright 2012, Dario Casalinuovo. All rights reserved.
|
||||
* Copyright 2021, Jaidyn Levesque. All rights reserved.
|
||||
* Copyright 2021-2022, Jaidyn Levesque. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
|||
|
||||
|
||||
const uint32 kIgnoreEmoticons = 'CBhe';
|
||||
const uint32 kMembershipUpdates = 'CBmu';
|
||||
|
||||
|
||||
PreferencesChatWindow::PreferencesChatWindow()
|
||||
|
@ -29,6 +30,9 @@ PreferencesChatWindow::PreferencesChatWindow()
|
|||
BBox* chatBox = new BBox("chatBox");
|
||||
chatBox->SetLabel(B_TRANSLATE("Chat settings"));
|
||||
|
||||
fMembershipUpdates = new BCheckBox("MembershipUpdates",
|
||||
B_TRANSLATE("Show join/part messages"), new BMessage(kMembershipUpdates));
|
||||
|
||||
fIgnoreEmoticons = new BCheckBox("IgnoreEmoticons",
|
||||
B_TRANSLATE("Ignore emoticons"), new BMessage(kIgnoreEmoticons));
|
||||
fIgnoreEmoticons->SetEnabled(false); // No emoticon support currently
|
||||
|
@ -38,6 +42,7 @@ PreferencesChatWindow::PreferencesChatWindow()
|
|||
|
||||
BLayoutBuilder::Group<>(chatBox, B_VERTICAL)
|
||||
.SetInsets(spacing, spacing * 2, spacing, spacing)
|
||||
.Add(fMembershipUpdates)
|
||||
.Add(fIgnoreEmoticons)
|
||||
.End();
|
||||
|
||||
|
@ -54,6 +59,8 @@ PreferencesChatWindow::AttachedToWindow()
|
|||
{
|
||||
fIgnoreEmoticons->SetTarget(this);
|
||||
fIgnoreEmoticons->SetValue(AppPreferences::Get()->IgnoreEmoticons);
|
||||
fMembershipUpdates->SetTarget(this);
|
||||
fMembershipUpdates->SetValue(AppPreferences::Get()->MembershipUpdates);
|
||||
}
|
||||
|
||||
|
||||
|
@ -62,8 +69,10 @@ PreferencesChatWindow::MessageReceived(BMessage* message)
|
|||
{
|
||||
switch (message->what) {
|
||||
case kIgnoreEmoticons:
|
||||
AppPreferences::Get()->IgnoreEmoticons
|
||||
= fIgnoreEmoticons->Value();
|
||||
AppPreferences::Get()->IgnoreEmoticons = fIgnoreEmoticons->Value();
|
||||
break;
|
||||
case kMembershipUpdates:
|
||||
AppPreferences::Get()->MembershipUpdates = fMembershipUpdates->Value();
|
||||
break;
|
||||
default:
|
||||
BView::MessageReceived(message);
|
||||
|
|
|
@ -19,6 +19,7 @@ public:
|
|||
|
||||
private:
|
||||
BCheckBox* fIgnoreEmoticons;
|
||||
BCheckBox* fMembershipUpdates;
|
||||
};
|
||||
|
||||
#endif // _PREFERENCES_BEHAVIOR_H
|
||||
|
|
|
@ -14,9 +14,7 @@
|
|||
|
||||
#include "AccountMenuItem.h"
|
||||
#include "ImageCache.h"
|
||||
#include "MainWindow.h"
|
||||
#include "Server.h"
|
||||
#include "TheApp.h"
|
||||
|
||||
|
||||
#undef B_TRANSLATION_CONTEXT
|
||||
|
@ -26,33 +24,23 @@
|
|||
int64 AccountsMenu::fDefaultSelection = -1;
|
||||
|
||||
|
||||
AccountsMenu::AccountsMenu(const char* name, BMessage msg, BMessage* allMsg,
|
||||
Server* server)
|
||||
AccountsMenu::AccountsMenu(const char* name, BMessage msg, BMessage* allMsg)
|
||||
:
|
||||
BPopUpMenu(name),
|
||||
fAccountMessage(msg),
|
||||
fAllMessage(allMsg),
|
||||
fServer(server)
|
||||
fAllMessage(allMsg)
|
||||
{
|
||||
_PopulateMenu();
|
||||
SetRadioMode(true);
|
||||
SetLabelFromMarked(true);
|
||||
fServer->RegisterObserver(this);
|
||||
}
|
||||
|
||||
|
||||
AccountsMenu::AccountsMenu(const char* name, BMessage msg, BMessage* allMsg)
|
||||
:
|
||||
AccountsMenu(name, msg, allMsg,
|
||||
((TheApp*)be_app)->GetMainWindow()->GetServer())
|
||||
{
|
||||
Server::Get()->RegisterObserver(this);
|
||||
}
|
||||
|
||||
|
||||
AccountsMenu::~AccountsMenu()
|
||||
{
|
||||
delete fAllMessage;
|
||||
fServer->UnregisterObserver(this);
|
||||
Server::Get()->UnregisterObserver(this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -80,7 +68,7 @@ AccountsMenu::_PopulateMenu()
|
|||
icon, 0, 0, false));
|
||||
}
|
||||
|
||||
AccountInstances accounts = fServer->GetActiveAccounts();
|
||||
AccountInstances accounts = Server::Get()->GetActiveAccounts();
|
||||
|
||||
// Add protocol item if not already in menu
|
||||
for (int i = 0; i < accounts.CountItems(); i++) {
|
||||
|
@ -98,7 +86,7 @@ AccountsMenu::_PopulateMenu()
|
|||
if (FindItem(label.String()) != NULL)
|
||||
continue;
|
||||
|
||||
ProtocolLooper* looper = fServer->GetProtocolLooper(instance);
|
||||
ProtocolLooper* looper = Server::Get()->GetProtocolLooper(instance);
|
||||
BBitmap* icon = _EnsureProtocolIcon(label.String(), looper);
|
||||
|
||||
BMessage* message = new BMessage(fAccountMessage);
|
||||
|
|
|
@ -10,13 +10,10 @@
|
|||
#include "Observer.h"
|
||||
|
||||
class ProtocolLooper;
|
||||
class Server;
|
||||
|
||||
|
||||
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();
|
||||
|
@ -24,7 +21,7 @@ public:
|
|||
virtual void ObserveInteger(int32 what, int32 value);
|
||||
|
||||
void SetDefaultSelection(BMenuItem* item);
|
||||
int64 GetDefaultSelection() { return fDefaultSelection; }
|
||||
static int64 GetDefaultSelection() { return fDefaultSelection; }
|
||||
|
||||
private:
|
||||
void _PopulateMenu();
|
||||
|
@ -37,7 +34,6 @@ private:
|
|||
BMessage fAccountMessage;
|
||||
BMessage* fAllMessage;
|
||||
static int64 fDefaultSelection;
|
||||
Server* fServer;
|
||||
};
|
||||
|
||||
#endif // _ACCOUNTS_MENU_H
|
||||
|
|
|
@ -71,7 +71,7 @@ ConversationItem::ObserveInteger(int32 what, int32 num)
|
|||
case INT_NEW_MENTION:
|
||||
fStatus |= kMentioned;
|
||||
break;
|
||||
case INT_WINDOW_FOCUSED:
|
||||
case INT_CONV_VIEW_SELECTED:
|
||||
fStatus = 0;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -15,10 +15,10 @@
|
|||
#include "Conversation.h"
|
||||
#include "ConversationAccountItem.h"
|
||||
#include "ConversationItem.h"
|
||||
#include "Flags.h"
|
||||
#include "MainWindow.h"
|
||||
#include "ProtocolLooper.h"
|
||||
#include "Server.h"
|
||||
#include "TheApp.h"
|
||||
|
||||
|
||||
#undef B_TRANSLATION_CONTEXT
|
||||
|
@ -167,8 +167,7 @@ ConversationListView::RemoveConversation(Conversation* chat)
|
|||
void
|
||||
ConversationListView::AddAccount(int64 instance)
|
||||
{
|
||||
Server* server = ((TheApp*)be_app)->GetMainWindow()->GetServer();
|
||||
ProtocolLooper* looper = server->GetProtocolLooper(instance);
|
||||
ProtocolLooper* looper = Server::Get()->GetProtocolLooper(instance);
|
||||
if (looper == NULL)
|
||||
return;
|
||||
AddItem(looper->GetListItem());
|
||||
|
@ -190,7 +189,7 @@ ConversationListView::RemoveAccount(int64 instance)
|
|||
}
|
||||
}
|
||||
if (CountItems() == 0)
|
||||
((TheApp*)be_app)->GetMainWindow()->SetConversation(NULL);
|
||||
((MainWindow*)Window())->SetConversation(NULL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -215,7 +214,6 @@ ConversationListView::_ConversationPopUp()
|
|||
Conversation* chat = item->GetConversation();
|
||||
ProtocolLooper* looper = chat->GetProtocolLooper();
|
||||
|
||||
Server* server = ((TheApp*)be_app)->GetMainWindow()->GetServer();
|
||||
_AddDefaultItems(menu, chat);
|
||||
BObjectList<BMessage> items = looper->Protocol()->ChatPopUpItems();
|
||||
|
||||
|
@ -302,7 +300,7 @@ ConversationListView::_BlankPopUp()
|
|||
{
|
||||
bool enabled = false;
|
||||
|
||||
Server* server = ((TheApp*)be_app)->GetMainWindow()->GetServer();
|
||||
Server* server = Server::Get();
|
||||
if (server != NULL && server->GetAccounts().CountItems() > 0)
|
||||
enabled = true;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright 2009-2011, Andrea Anzani. All rights reserved.
|
||||
* Copyright 2021, Jaidyn Levesque. All rights reserved.
|
||||
* Copyright 2021-2022, Jaidyn Levesque. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
|
@ -23,10 +23,11 @@
|
|||
|
||||
#include "AppMessages.h"
|
||||
#include "AppPreferences.h"
|
||||
#include "ChatOMatic.h"
|
||||
#include "ChatProtocolMessages.h"
|
||||
#include "Contact.h"
|
||||
#include "Conversation.h"
|
||||
#include "NotifyMessage.h"
|
||||
#include "ProtocolLooper.h"
|
||||
#include "ProtocolManager.h"
|
||||
#include "RenderView.h"
|
||||
#include "SendTextView.h"
|
||||
|
@ -68,7 +69,15 @@ ConversationView::AttachedToWindow()
|
|||
if (fSubjectTextView->Text() != fConversation->GetSubject())
|
||||
fSubjectTextView->SetText(fConversation->GetSubject());
|
||||
}
|
||||
NotifyInteger(INT_WINDOW_FOCUSED, 0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ConversationView::Show()
|
||||
{
|
||||
BView::Show();
|
||||
|
||||
NotifyInteger(INT_CONV_VIEW_SELECTED, 0);
|
||||
fSendView->MakeFocus(true);
|
||||
fSendView->Invalidate();
|
||||
}
|
||||
|
@ -125,7 +134,7 @@ ConversationView::ImMessage(BMessage* msg)
|
|||
case IM_MESSAGE_RECEIVED:
|
||||
{
|
||||
_AppendOrEnqueueMessage(msg);
|
||||
fReceiveView->ScrollToBottom();
|
||||
_ScrollToBottom();
|
||||
break;
|
||||
}
|
||||
case IM_MESSAGE_SENT:
|
||||
|
@ -133,25 +142,12 @@ ConversationView::ImMessage(BMessage* msg)
|
|||
{
|
||||
_AppendOrEnqueueMessage(msg);
|
||||
if (im_what == IM_MESSAGE_SENT)
|
||||
fReceiveView->ScrollToBottom();
|
||||
_ScrollToBottom();
|
||||
break;
|
||||
}
|
||||
case IM_ROOM_JOINED:
|
||||
{
|
||||
BMessage msg;
|
||||
msg.AddString("body", B_TRANSLATE("** You joined the room.\n"));
|
||||
_AppendOrEnqueueMessage(&msg);
|
||||
fReceiveView->ScrollToBottom();
|
||||
}
|
||||
case IM_ROOM_CREATED:
|
||||
{
|
||||
BMessage msg;
|
||||
msg.AddString("body", B_TRANSLATE("** You created the room.\n"));
|
||||
_AppendOrEnqueueMessage(&msg);
|
||||
fReceiveView->ScrollToBottom();
|
||||
}
|
||||
case IM_ROOM_PARTICIPANT_JOINED:
|
||||
{
|
||||
if (AppPreferences::Get()->MembershipUpdates == true)
|
||||
_UserMessage(B_TRANSLATE("%user% has joined the room.\n"),
|
||||
B_TRANSLATE("%user% has joined the room (%body%).\n"),
|
||||
msg);
|
||||
|
@ -159,6 +155,7 @@ ConversationView::ImMessage(BMessage* msg)
|
|||
}
|
||||
case IM_ROOM_PARTICIPANT_LEFT:
|
||||
{
|
||||
if (AppPreferences::Get()->MembershipUpdates == true)
|
||||
_UserMessage(B_TRANSLATE("%user% has left the room.\n"),
|
||||
B_TRANSLATE("%user% has left the room (%body%).\n"),
|
||||
msg);
|
||||
|
@ -309,10 +306,10 @@ void
|
|||
ConversationView::GetWeights(float* horizChat, float* horizList,
|
||||
float* vertChat, float* vertSend)
|
||||
{
|
||||
*horizChat = fHorizSplit->ItemWeight(0);
|
||||
*horizList = fHorizSplit->ItemWeight(1);
|
||||
*vertChat = fVertSplit->ItemWeight(0);
|
||||
*vertSend = fVertSplit->ItemWeight(1);
|
||||
*horizChat = fHorizSplit->ItemWeight((int32)0);
|
||||
*horizList = fHorizSplit->ItemWeight((int32)1);
|
||||
*vertChat = fVertSplit->ItemWeight((int32)0);
|
||||
*vertSend = fVertSplit->ItemWeight((int32)1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -387,10 +384,27 @@ ConversationView::_InitInterface()
|
|||
bool
|
||||
ConversationView::_AppendOrEnqueueMessage(BMessage* msg)
|
||||
{
|
||||
// Fill the message with user information not provided by protocol
|
||||
BString user_id = msg->FindString("user_id");
|
||||
if (msg->FindString("user_id", &user_id) == B_OK) {
|
||||
User* user = NULL;
|
||||
if (fConversation != NULL)
|
||||
user = fConversation->UserById(user_id);
|
||||
if (user != NULL) {
|
||||
if (msg->HasString("user_name") == false)
|
||||
if (user->GetName().IsEmpty() == false)
|
||||
msg->AddString("user_name", user->GetName());
|
||||
msg->AddColor("user_color", user->fItemColor);
|
||||
}
|
||||
if (msg->HasString("user_name") == false)
|
||||
msg->AddString("user_name", user_id);
|
||||
}
|
||||
|
||||
// Fill the message with receive time if not provided
|
||||
if (msg->HasInt64("when") == false)
|
||||
msg->AddInt64("when", (int64)time(NULL));
|
||||
|
||||
// If not attached to the chat window, then re-handle this message
|
||||
// If not attached to a chat window, then re-handle this message
|
||||
// later [AttachedToWindow()], since you can't edit an unattached
|
||||
// RenderView.
|
||||
if (Window() == NULL) {
|
||||
|
@ -423,31 +437,16 @@ ConversationView::_AppendMessage(BMessage* msg)
|
|||
}
|
||||
|
||||
// Otherwise, it's message time!
|
||||
int64 timeInt;
|
||||
BString user_id;
|
||||
int64 timeInt = msg->GetInt64("when", time(NULL));
|
||||
BString user_name = msg->FindString("user_name");
|
||||
rgb_color userColor = msg->GetColor("user_color", ui_color(B_PANEL_TEXT_COLOR));
|
||||
BString body;
|
||||
rgb_color userColor = ui_color(B_PANEL_TEXT_COLOR);
|
||||
|
||||
if (msg->FindString("body", &body) != B_OK)
|
||||
return;
|
||||
|
||||
if (msg->FindInt64("when", &timeInt) != B_OK)
|
||||
timeInt = (int64)time(NULL);
|
||||
|
||||
if (msg->FindString("user_id", &user_id) == B_OK) {
|
||||
User* user = NULL;
|
||||
if (fConversation != NULL
|
||||
&& (user = fConversation->UserById(user_id)) != NULL) {
|
||||
user_name = user->GetName();
|
||||
userColor = user->fItemColor;
|
||||
}
|
||||
else if (user_name.IsEmpty() == true)
|
||||
user_name = user_id;
|
||||
}
|
||||
|
||||
if (user_name.IsEmpty() == true) {
|
||||
fReceiveView->AppendGeneric(body);
|
||||
fReceiveView->AppendGeneric(body, timeInt);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -455,7 +454,7 @@ ConversationView::_AppendMessage(BMessage* msg)
|
|||
BString meMsg = "** ";
|
||||
meMsg << user_name.String() << " ";
|
||||
meMsg << body.RemoveFirst("/me ");
|
||||
fReceiveView->AppendGeneric(meMsg.String());
|
||||
fReceiveView->AppendGeneric(meMsg.String(), timeInt);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -516,6 +515,14 @@ ConversationView::_AppendMessage(BMessage* msg)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
ConversationView::_ScrollToBottom()
|
||||
{
|
||||
if (IsHidden() == false)
|
||||
fReceiveView->ScrollToBottom();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ConversationView::_EnableStartingFaces(BMessage* msg, int32 index, uint16* face,
|
||||
UInt16IntMap* indices, int32* next)
|
||||
|
@ -620,7 +627,7 @@ ConversationView::_UserMessage(const char* format, const char* bodyFormat,
|
|||
BMessage newMsg;
|
||||
newMsg.AddString("body", newBody);
|
||||
_AppendOrEnqueueMessage(&newMsg);
|
||||
fReceiveView->ScrollToBottom();
|
||||
_ScrollToBottom();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright 2009-2011, Andrea Anzani. All rights reserved.
|
||||
* Copyright 2021, Jaidyn Levesque. All rights reserved.
|
||||
* Copyright 2021-2022, Jaidyn Levesque. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _CHAT_VIEW_H
|
||||
|
@ -26,14 +26,13 @@ class UserListView;
|
|||
|
||||
const uint32 kClearText = 'CVct';
|
||||
|
||||
typedef KeyMap<uint16, int32> UInt16IntMap;
|
||||
|
||||
|
||||
class ConversationView : public BGroupView, public Observer, public Notifier {
|
||||
public:
|
||||
ConversationView(Conversation* chat = NULL);
|
||||
|
||||
virtual void AttachedToWindow();
|
||||
void Show();
|
||||
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
void ImMessage(BMessage* msg);
|
||||
|
@ -53,11 +52,15 @@ public:
|
|||
float vertChat, float vertSend);
|
||||
|
||||
private:
|
||||
typedef KeyMap<uint16, int32> UInt16IntMap;
|
||||
|
||||
void _InitInterface();
|
||||
|
||||
bool _AppendOrEnqueueMessage(BMessage* msg);
|
||||
void _AppendMessage(BMessage* msg);
|
||||
|
||||
void _ScrollToBottom();
|
||||
|
||||
// Helper functions for _AppendFormattedMessage()
|
||||
void _EnableStartingFaces(BMessage* msg, int32 index,
|
||||
uint16* face, UInt16IntMap* indices, int32* next);
|
||||
|
|
|
@ -18,10 +18,10 @@ RenderView::RenderView(const char* name)
|
|||
|
||||
|
||||
void
|
||||
RenderView::AppendGeneric(const char* message)
|
||||
RenderView::AppendGeneric(const char* message, int64 when)
|
||||
{
|
||||
if (BString(message).IsEmpty() == true) return;
|
||||
AppendTimestamp(time(NULL));
|
||||
AppendTimestamp(when);
|
||||
Append(message, ui_color(B_PANEL_TEXT_COLOR), B_BOLD_FACE);
|
||||
if (BString(message).EndsWith("\n") == false) Append("\n");
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ class RenderView : public RunView {
|
|||
public:
|
||||
RenderView(const char* name);
|
||||
|
||||
void AppendGeneric(const char* message);
|
||||
void AppendGeneric(const char* message, int64 when);
|
||||
void AppendUserstamp(const char* nick, rgb_color nameColor);
|
||||
void AppendTimestamp(time_t time = 0);
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
|
||||
#include "AppMessages.h"
|
||||
#include "AppPreferences.h"
|
||||
#include "ChatOMatic.h"
|
||||
#include "ChatProtocolMessages.h"
|
||||
#include "ReplicantMenuItem.h"
|
||||
#include "Utils.h"
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright 2021, Jaidyn Levesque <jadedctrl@teknik.io>
|
||||
* All rights reserved. Distributed under the terms of the MIT license.
|
||||
*/
|
||||
|
||||
#include "RoomListRow.h"
|
||||
|
||||
#include <ColumnTypes.h>
|
||||
|
||||
|
||||
RoomListRow::RoomListRow(BMessage* msg)
|
||||
:
|
||||
BRow(),
|
||||
fMessage(new BMessage(*msg)),
|
||||
fInstance(-1)
|
||||
{
|
||||
int64 proto = msg->FindInt64("instance");
|
||||
BString id = msg->FindString("chat_id");
|
||||
BString name = msg->GetString("chat_name", id);
|
||||
BString desc = msg->FindString("subject");
|
||||
BString category = msg->FindString("category");
|
||||
int32 user_n = msg->GetInt32("user_count", -1);
|
||||
|
||||
SetField(new BStringField(name), kNameColumn);
|
||||
SetField(new BStringField(desc), kDescColumn);
|
||||
SetField(new BStringField(category), kCatColumn);
|
||||
if (user_n > -1)
|
||||
SetField(new BIntegerField(user_n), kUserColumn);
|
||||
}
|
||||
|
||||
|
||||
RoomListRow::~RoomListRow()
|
||||
{
|
||||
delete fMessage;
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright 2021, Jaidyn Levesque <jadedctrl@teknik.io>
|
||||
* All rights reserved. Distributed under the terms of the MIT license.
|
||||
*/
|
||||
#ifndef _ROOM_LIST_ROW_H
|
||||
#define _ROOM_LIST_ROW_H
|
||||
|
||||
#include <ColumnListView.h>
|
||||
|
||||
|
||||
enum {
|
||||
kNameColumn,
|
||||
kDescColumn,
|
||||
kCatColumn,
|
||||
kUserColumn
|
||||
};
|
||||
|
||||
|
||||
class RoomListRow : public BRow {
|
||||
public:
|
||||
RoomListRow(BMessage* msg);
|
||||
~RoomListRow();
|
||||
|
||||
BMessage* Message() { return fMessage; }
|
||||
int64 Instance() { return fInstance; }
|
||||
|
||||
private:
|
||||
int64 fInstance;
|
||||
BMessage* fMessage;
|
||||
};
|
||||
|
||||
#endif // _ROOM_LIST_ROW_H
|
|
@ -20,10 +20,10 @@
|
|||
|
||||
#include "AppMessages.h"
|
||||
#include "AppPreferences.h"
|
||||
#include "ChatOMatic.h"
|
||||
#include "ChatProtocolMessages.h"
|
||||
#include "RosterItem.h"
|
||||
#include "RosterListView.h"
|
||||
#include "Server.h"
|
||||
|
||||
|
||||
#undef B_TRANSLATION_CONTEXT
|
||||
|
@ -33,11 +33,10 @@
|
|||
const uint32 kSearchContact = 'RWSC';
|
||||
|
||||
|
||||
RosterView::RosterView(const char* title, Server* server, bigtime_t account)
|
||||
RosterView::RosterView(const char* title, bigtime_t account)
|
||||
:
|
||||
BGroupView(title, B_VERTICAL, B_USE_DEFAULT_SPACING),
|
||||
fAccount(-1),
|
||||
fServer(server),
|
||||
fManualItem(new BStringItem("")),
|
||||
fManualStr("Select user %user%" B_UTF8_ELLIPSIS)
|
||||
{
|
||||
|
@ -122,7 +121,7 @@ RosterView::ImMessage(BMessage* msg)
|
|||
|| user_id.IsEmpty() == true)
|
||||
return;
|
||||
|
||||
Contact* contact = fServer->ContactById(user_id, instance);
|
||||
Contact* contact = Server::Get()->ContactById(user_id, instance);
|
||||
if (contact == NULL)
|
||||
return;
|
||||
|
||||
|
@ -190,7 +189,7 @@ RosterView::ImMessage(BMessage* msg)
|
|||
|| msg->FindInt64("instance", &instance) != B_OK
|
||||
|| user_id.IsEmpty() == true)
|
||||
return;
|
||||
Contact* contact = fServer->ContactById(user_id, instance);
|
||||
Contact* contact = Server::Get()->ContactById(user_id, instance);
|
||||
if (contact == NULL)
|
||||
return;
|
||||
RosterItem* rosterItem = contact->GetRosterItem();
|
||||
|
@ -209,7 +208,7 @@ RosterView::ImMessage(BMessage* msg)
|
|||
|| user_id.IsEmpty() == true)
|
||||
return;
|
||||
|
||||
Contact* contact = fServer->ContactById(user_id, instance);
|
||||
Contact* contact = Server::Get()->ContactById(user_id, instance);
|
||||
if (contact == NULL)
|
||||
return;
|
||||
|
||||
|
@ -269,9 +268,9 @@ RosterView::_RosterMap()
|
|||
{
|
||||
RosterMap contacts;
|
||||
if (fAccount < 0)
|
||||
contacts = fServer->Contacts();
|
||||
contacts = Server::Get()->Contacts();
|
||||
else {
|
||||
ProtocolLooper* looper = fServer->GetProtocolLooper(fAccount);
|
||||
ProtocolLooper* looper = Server::Get()->GetProtocolLooper(fAccount);
|
||||
contacts = looper->Contacts();
|
||||
}
|
||||
return contacts;
|
||||
|
|
|
@ -14,18 +14,17 @@
|
|||
|
||||
#include <GroupView.h>
|
||||
|
||||
#include "Server.h"
|
||||
#include "Maps.h"
|
||||
|
||||
class BStringItem;
|
||||
class BTextControl;
|
||||
class RosterItem;
|
||||
class RosterListView;
|
||||
class Server;
|
||||
|
||||
|
||||
class RosterView : public BGroupView {
|
||||
public:
|
||||
RosterView(const char* title, Server* server, bigtime_t account = -1);
|
||||
RosterView(const char* title, bigtime_t account = -1);
|
||||
|
||||
void MessageReceived(BMessage* message);
|
||||
void ImMessage(BMessage* msg);
|
||||
|
@ -46,7 +45,6 @@ public:
|
|||
private:
|
||||
RosterMap _RosterMap();
|
||||
|
||||
Server* fServer;
|
||||
RosterListView* fListView;
|
||||
BTextControl* fSearchBox;
|
||||
bigtime_t fAccount;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#include <iostream>
|
||||
/*
|
||||
* Copyright 2021, Jaidyn Levesque <jadedctrl@teknik.io>
|
||||
* All rights reserved. Distributed under the terms of the MIT license.
|
||||
|
@ -10,9 +9,7 @@
|
|||
#include <Window.h>
|
||||
|
||||
#include "AppMessages.h"
|
||||
#include "MainWindow.h"
|
||||
#include "Server.h"
|
||||
#include "TheApp.h"
|
||||
|
||||
|
||||
SendTextView::SendTextView(const char* name, ConversationView* convView)
|
||||
|
@ -38,22 +35,27 @@ SendTextView::KeyDown(const char* bytes, int32 numBytes)
|
|||
fCurrentIndex = 0;
|
||||
fCurrentWord.SetTo("");
|
||||
|
||||
if ((bytes[0] == B_UP_ARROW) && (modifiers == 0)) {
|
||||
for (int i = 0; i < numBytes; i++) {
|
||||
if ((bytes[i] == B_UP_ARROW) && (modifiers == 0)) {
|
||||
_UpHistory();
|
||||
return;
|
||||
}
|
||||
else if ((bytes[0] == B_DOWN_ARROW) && (modifiers == 0)) {
|
||||
else if ((bytes[i] == B_DOWN_ARROW) && (modifiers == 0)) {
|
||||
_DownHistory();
|
||||
return;
|
||||
}
|
||||
|
||||
if ((bytes[0] == B_ENTER) && (modifiers & B_COMMAND_KEY))
|
||||
if ((bytes[i] == B_ENTER)
|
||||
&& ((modifiers & B_COMMAND_KEY) || (modifiers & B_SHIFT_KEY))) {
|
||||
Insert("\n");
|
||||
else if ((bytes[0] == B_ENTER) && (modifiers == 0)) {
|
||||
return;
|
||||
}
|
||||
else if (bytes[i] == B_ENTER) {
|
||||
_AppendHistory();
|
||||
fChatView->MessageReceived(new BMessage(APP_CHAT));
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
BTextView::KeyDown(bytes, numBytes);
|
||||
}
|
||||
|
||||
|
@ -122,8 +124,7 @@ SendTextView::_CommandNames()
|
|||
if (fCurrentIndex == 0) {
|
||||
int64 instance = fChatView->GetConversation()->GetProtocolLooper()->GetInstance();
|
||||
BStringList cmdNames;
|
||||
CommandMap cmds =
|
||||
((TheApp*)be_app)->GetMainWindow()->GetServer()->Commands(instance);
|
||||
CommandMap cmds = Server::Get()->Commands(instance);
|
||||
|
||||
for (int i = 0; i < cmds.CountItems(); i++)
|
||||
cmdNames.Add(cmds.KeyAt(i));
|
||||
|
|
|
@ -36,10 +36,9 @@ const int32 kSelectAccount = 'SVsa';
|
|||
const int32 kSetNick = 'SVsn';
|
||||
|
||||
|
||||
StatusView::StatusView(const char* name, Server* server)
|
||||
StatusView::StatusView(const char* name)
|
||||
:
|
||||
BView(name, B_WILL_DRAW),
|
||||
fServer(server),
|
||||
fAccount(-1)
|
||||
{
|
||||
// Nick name
|
||||
|
@ -85,7 +84,7 @@ StatusView::StatusView(const char* name, Server* server)
|
|||
|
||||
// Changing the account used
|
||||
fAccountsMenu = new AccountsMenu("statusAccountsMenu",
|
||||
BMessage(kSelectAccount), new BMessage(kSelectAccount), fServer);
|
||||
BMessage(kSelectAccount), new BMessage(kSelectAccount));
|
||||
fAccountsButton = new MenuButton("statusAccountsButton", "", new BMessage());
|
||||
fAccountsButton->SetMenu(fAccountsMenu);
|
||||
|
||||
|
@ -195,9 +194,9 @@ StatusView::_SetToAccount()
|
|||
{
|
||||
int64 instance = fAccount;
|
||||
if (instance == -1)
|
||||
instance = fServer->GetActiveAccounts().ValueAt(0);
|
||||
instance = Server::Get()->GetActiveAccounts().ValueAt(0);
|
||||
|
||||
ProtocolLooper* looper = fServer->GetProtocolLooper(instance);
|
||||
ProtocolLooper* looper = Server::Get()->GetProtocolLooper(instance);
|
||||
if (looper == NULL || looper->GetOwnContact() == NULL)
|
||||
return;
|
||||
Contact* contact = looper->GetOwnContact();
|
||||
|
|
|
@ -17,11 +17,10 @@ class AccountsMenu;
|
|||
class BitmapView;
|
||||
class EnterTextView;
|
||||
class MenuButton;
|
||||
class Server;
|
||||
|
||||
class StatusView : public BView, public Observer {
|
||||
public:
|
||||
StatusView(const char* name, Server* server);
|
||||
StatusView(const char* name);
|
||||
|
||||
virtual void AttachedToWindow();
|
||||
virtual void MessageReceived(BMessage* msg);
|
||||
|
@ -45,8 +44,6 @@ private:
|
|||
MenuButton* fAccountsButton;
|
||||
AccountsMenu* fAccountsMenu;
|
||||
int64 fAccount;
|
||||
|
||||
Server* fServer;
|
||||
};
|
||||
|
||||
#endif // _STATUS_VIEW_H
|
||||
|
|
|
@ -13,11 +13,9 @@
|
|||
#include "AppMessages.h"
|
||||
#include "ChatProtocolMessages.h"
|
||||
#include "Conversation.h"
|
||||
#include "MainWindow.h"
|
||||
#include "ProtocolLooper.h"
|
||||
#include "Role.h"
|
||||
#include "Server.h"
|
||||
#include "TheApp.h"
|
||||
#include "User.h"
|
||||
#include "UserInfoWindow.h"
|
||||
#include "UserItem.h"
|
||||
|
@ -108,8 +106,7 @@ UserListView::_UserPopUp()
|
|||
|
||||
Role* selected_role = fChat->GetRole(selected_user->GetId());
|
||||
|
||||
Server* server = ((TheApp*)be_app)->GetMainWindow()->GetServer();
|
||||
BObjectList<BMessage> items = server->UserPopUpItems();
|
||||
BObjectList<BMessage> items = Server::Get()->UserPopUpItems();
|
||||
BObjectList<BMessage> protoItems = fChat->GetProtocolLooper()->Protocol()->UserPopUpItems();
|
||||
items.AddList(&protoItems);
|
||||
|
||||
|
|
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
* Copyright 2010-2011, Pier Luigi Fiorini. All rights reserved.
|
||||
* Copyright 2007-2009, Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
|
||||
* Ryan Leavengood, leavengood@gmail.com
|
||||
*/
|
||||
|
||||
#include <Alert.h>
|
||||
#include <Catalog.h>
|
||||
#include <Font.h>
|
||||
#include <String.h>
|
||||
#include <TextView.h>
|
||||
|
||||
#include "AboutWindow.h"
|
||||
|
||||
|
||||
#undef B_TRANSLATION_CONTEXT
|
||||
#define B_TRANSLATION_CONTEXT "About window"
|
||||
|
||||
|
||||
AboutWindow::AboutWindow(const char* appName, const char** holders,
|
||||
const char** authors, const char* extraInfo)
|
||||
{
|
||||
fAppName = new BString(appName);
|
||||
|
||||
// Build the text to display
|
||||
int32 i;
|
||||
BString text(appName);
|
||||
text << "\n\n";
|
||||
for (i = 0; holders[i]; i++)
|
||||
text << B_TRANSLATE("Copyright " B_UTF8_COPYRIGHT " ") << holders[i]
|
||||
<< "\n";
|
||||
|
||||
text << B_TRANSLATE("\nWritten by:\n");
|
||||
for (int32 i = 0; authors[i]; i++) {
|
||||
text << " " << authors[i] << "\n";
|
||||
}
|
||||
// The extra information is optional
|
||||
if (extraInfo != NULL)
|
||||
text << "\n" << extraInfo << "\n";
|
||||
|
||||
fText = new BString(text);
|
||||
}
|
||||
|
||||
|
||||
AboutWindow::~AboutWindow()
|
||||
{
|
||||
delete fText;
|
||||
delete fAppName;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AboutWindow::Show()
|
||||
{
|
||||
BAlert* alert = new BAlert(B_TRANSLATE("About" B_UTF8_ELLIPSIS),
|
||||
fText->String(), B_TRANSLATE("Close"));
|
||||
BTextView* view = alert->TextView();
|
||||
BFont font;
|
||||
view->SetStylable(true);
|
||||
view->GetFont(&font);
|
||||
font.SetFace(B_BOLD_FACE);
|
||||
font.SetSize(font.Size() * 1.7f);
|
||||
view->SetFontAndColor(0, fAppName->Length(), &font);
|
||||
alert->Go();
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
* Copyright 2010-2011, Pier Luigi Fiorini. All rights reserved.
|
||||
* Copyright 2007-2009, Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _ABOUT_WINDOW_H
|
||||
#define _ABOUT_WINDOW_H
|
||||
|
||||
#include <String.h>
|
||||
|
||||
class AboutWindow {
|
||||
public:
|
||||
AboutWindow(const char* appName, const char** holders,
|
||||
const char** authors, const char* extraInfo = NULL);
|
||||
virtual ~AboutWindow();
|
||||
|
||||
void Show();
|
||||
|
||||
private:
|
||||
BString* fAppName;
|
||||
BString* fText;
|
||||
};
|
||||
|
||||
#endif // _ABOUT_WINDOW_H
|
|
@ -27,9 +27,7 @@
|
|||
#include "ChatProtocolMessages.h"
|
||||
#include "ProtocolManager.h"
|
||||
#include "ProtocolSettings.h"
|
||||
#include "MainWindow.h"
|
||||
#include "Server.h"
|
||||
#include "TheApp.h"
|
||||
|
||||
|
||||
#undef B_TRANSLATION_CONTEXT
|
||||
|
@ -288,8 +286,7 @@ int64
|
|||
AccountsWindow::_AccountInstance(const char* account)
|
||||
{
|
||||
bool found = false;
|
||||
AccountInstances accs =
|
||||
((TheApp*)be_app)->GetMainWindow()->GetServer()->GetAccounts();
|
||||
AccountInstances accs = Server::Get()->GetAccounts();
|
||||
int64 instance = accs.ValueFor(BString(account), &found);
|
||||
|
||||
if (found == false)
|
||||
|
|
|
@ -1,29 +1,34 @@
|
|||
/*
|
||||
* Copyright 2009-2011, Andrea Anzani. All rights reserved.
|
||||
* Copyright 2009-2011, Pier Luigi Fiorini. All rights reserved.
|
||||
* Copyright 2021, Jaidyn Levesque. All rights reserved.
|
||||
* Copyright 2021-2022, Jaidyn Levesque. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Andrea Anzani, andrea.anzani@gmail.com
|
||||
* Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
|
||||
* Jaidyn Levesque, jadedctrl@teknik.io
|
||||
* Humdinger, humdingerb@gmail.com
|
||||
*/
|
||||
|
||||
#include <Application.h>
|
||||
#include <Alert.h>
|
||||
#include <Beep.h>
|
||||
#include <CardLayout.h>
|
||||
#include <Catalog.h>
|
||||
#include <LayoutBuilder.h>
|
||||
#include <MenuBar.h>
|
||||
#include <PathFinder.h>
|
||||
#include <Roster.h>
|
||||
#include <ScrollView.h>
|
||||
#include <TranslationUtils.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "AccountDialog.h"
|
||||
#include "AccountsWindow.h"
|
||||
#include "AppMessages.h"
|
||||
#include "AppPreferences.h"
|
||||
#include "ChatOMatic.h"
|
||||
#include "ChatProtocolAddOn.h"
|
||||
#include "ChatProtocolMessages.h"
|
||||
#include "ConversationItem.h"
|
||||
|
@ -35,8 +40,10 @@
|
|||
#include "ProtocolManager.h"
|
||||
#include "ProtocolSettings.h"
|
||||
#include "ReplicantStatusView.h"
|
||||
#include "RoomListWindow.h"
|
||||
#include "RosterEditWindow.h"
|
||||
#include "RosterWindow.h"
|
||||
#include "Server.h"
|
||||
#include "StatusManager.h"
|
||||
#include "StatusView.h"
|
||||
#include "TemplateWindow.h"
|
||||
|
@ -55,12 +62,10 @@ MainWindow::MainWindow()
|
|||
B_TRANSLATE_SYSTEM_NAME(APP_NAME), B_TITLED_WINDOW, 0),
|
||||
fWorkspaceChanged(false),
|
||||
fConversation(NULL),
|
||||
fRosterWindow(NULL),
|
||||
fServer(NULL)
|
||||
fRosterWindow(NULL)
|
||||
{
|
||||
// Filter messages using Server
|
||||
fServer = new Server();
|
||||
AddFilter(fServer);
|
||||
AddFilter(Server::Get());
|
||||
|
||||
_InitInterface();
|
||||
|
||||
|
@ -80,7 +85,16 @@ MainWindow::Start()
|
|||
MessageReceived(new BMessage(APP_SHOW_ACCOUNTS));
|
||||
|
||||
// Login all accounts
|
||||
fServer->LoginAll();
|
||||
Server::Get()->LoginAll();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::Show()
|
||||
{
|
||||
if (fChatLayout->CountItems() == 0)
|
||||
SetConversation(NULL);
|
||||
BWindow::Show();
|
||||
}
|
||||
|
||||
|
||||
|
@ -98,12 +112,20 @@ MainWindow::QuitRequested()
|
|||
button_index = alert->Go();
|
||||
}
|
||||
|
||||
AppPreferences::Get()->MainWindowListWeight = fSplitView->ItemWeight(0);
|
||||
AppPreferences::Get()->MainWindowChatWeight = fSplitView->ItemWeight(1);
|
||||
AppPreferences::Get()->MainWindowRect = Frame();
|
||||
_SaveWeights();
|
||||
|
||||
if (button_index == 0) {
|
||||
fServer->Quit();
|
||||
Server::Get()->Quit();
|
||||
|
||||
// ConversationViews will be removed by Server's deletion of Conversations,
|
||||
// but some special views (protocol logs, the blank ConversationView)
|
||||
// must be done manually
|
||||
for (int i = fChatLayout->CountItems() - 1; i >= 0; i--)
|
||||
fChatLayout->RemoveItem(i);
|
||||
fChatLayout->RemoveSelf();
|
||||
delete fChatLayout;
|
||||
|
||||
AppPreferences::Get()->Save();
|
||||
ReplicantStatusView::RemoveReplicant();
|
||||
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||
|
@ -160,7 +182,7 @@ MainWindow::MessageReceived(BMessage* message)
|
|||
newMsg->AddInt32("im_what", IM_CREATE_CHAT);
|
||||
|
||||
fRosterWindow = new RosterWindow(B_TRANSLATE("Invite contact to "
|
||||
"chat" B_UTF8_ELLIPSIS), newMsg, new BMessenger(this), fServer);
|
||||
"chat" B_UTF8_ELLIPSIS), newMsg, new BMessenger(this));
|
||||
fRosterWindow->Show();
|
||||
break;
|
||||
}
|
||||
|
@ -170,7 +192,7 @@ MainWindow::MessageReceived(BMessage* message)
|
|||
createMsg->AddInt32("im_what", IM_CREATE_ROOM);
|
||||
|
||||
TemplateWindow* win = new TemplateWindow(B_TRANSLATE("Create room"),
|
||||
"create_room", createMsg, fServer);
|
||||
"create_room", createMsg);
|
||||
win->Show();
|
||||
break;
|
||||
}
|
||||
|
@ -180,7 +202,7 @@ MainWindow::MessageReceived(BMessage* message)
|
|||
joinMsg->AddInt32("im_what", IM_JOIN_ROOM);
|
||||
|
||||
TemplateWindow* win = new TemplateWindow(B_TRANSLATE("Join a room"),
|
||||
"join_room", joinMsg, fServer);
|
||||
"join_room", joinMsg);
|
||||
win->Show();
|
||||
break;
|
||||
}
|
||||
|
@ -197,15 +219,35 @@ MainWindow::MessageReceived(BMessage* message)
|
|||
ProtocolLooper* plooper = fConversation->GetProtocolLooper();
|
||||
BLooper* looper = (BLooper*)plooper;
|
||||
fRosterWindow = new RosterWindow(B_TRANSLATE("Invite contact to "
|
||||
"chat" B_UTF8_ELLIPSIS), invite, new BMessenger(looper), fServer,
|
||||
"chat" B_UTF8_ELLIPSIS), invite, new BMessenger(looper),
|
||||
plooper->GetInstance());
|
||||
|
||||
fRosterWindow->Show();
|
||||
break;
|
||||
}
|
||||
case APP_ROOM_DIRECTORY:
|
||||
{
|
||||
RoomListWindow::Get()->Show();
|
||||
break;
|
||||
}
|
||||
case APP_ROOM_SEARCH:
|
||||
{
|
||||
if (fConversation != NULL) {
|
||||
entry_ref ref;
|
||||
BEntry entry(fConversation->CachePath().Path());
|
||||
if (entry.GetRef(&ref) != B_OK)
|
||||
break;
|
||||
|
||||
BMessage msg(B_REFS_RECEIVED);
|
||||
msg.AddRef("refs", &ref);
|
||||
BRoster roster;
|
||||
roster.Launch("application/x-vnd.Haiku.TextSearch", &msg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case APP_EDIT_ROSTER:
|
||||
{
|
||||
RosterEditWindow::Get(fServer)->Show();
|
||||
RosterEditWindow::Get()->Show();
|
||||
break;
|
||||
}
|
||||
case APP_MOVE_UP:
|
||||
|
@ -255,6 +297,29 @@ MainWindow::MessageReceived(BMessage* message)
|
|||
fListView->RemoveAccount(message->GetInt64("instance", -1));
|
||||
break;
|
||||
}
|
||||
case APP_SHOW_HELP:
|
||||
{
|
||||
// Borrowed from HaikuArchives/Calendar's _ShowHelp()
|
||||
BPathFinder pathFinder;
|
||||
BStringList paths;
|
||||
BPath path;
|
||||
BEntry entry;
|
||||
|
||||
status_t error = pathFinder.FindPaths(B_FIND_PATH_DOCUMENTATION_DIRECTORY,
|
||||
"packages/chat_o_matic", paths);
|
||||
|
||||
for (int i = 0; i < paths.CountStrings(); ++i) {
|
||||
if (error == B_OK && path.SetTo(paths.StringAt(i)) == B_OK
|
||||
&& path.Append("Documentation.html") == B_OK)
|
||||
{
|
||||
entry = path.Path();
|
||||
entry_ref ref;
|
||||
entry.GetRef(&ref);
|
||||
be_roster->Launch(&ref);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IM_MESSAGE:
|
||||
ImMessage(message);
|
||||
break;
|
||||
|
@ -276,7 +341,7 @@ MainWindow::ImMessage(BMessage* msg)
|
|||
{
|
||||
int64 instance;
|
||||
if (msg->FindInt64("instance", &instance) == B_OK) {
|
||||
ProtocolLooper* looper = fServer->GetProtocolLooper(instance);
|
||||
ProtocolLooper* looper = Server::Get()->GetProtocolLooper(instance);
|
||||
if (looper != NULL) {
|
||||
Contact* contact = looper->GetOwnContact();
|
||||
contact->RegisterObserver(fStatusView);
|
||||
|
@ -311,7 +376,7 @@ MainWindow::ImMessage(BMessage* msg)
|
|||
if (fRosterWindow != NULL)
|
||||
fRosterWindow->PostMessage(msg);
|
||||
if (RosterEditWindow::Check() == true)
|
||||
RosterEditWindow::Get(fServer)->PostMessage(msg);
|
||||
RosterEditWindow::Get()->PostMessage(msg);
|
||||
break;
|
||||
}
|
||||
case IM_PROTOCOL_READY: {
|
||||
|
@ -323,6 +388,10 @@ MainWindow::ImMessage(BMessage* msg)
|
|||
fListView->AddAccount(msg->GetInt64("instance", -1));
|
||||
break;
|
||||
}
|
||||
case IM_ROOM_DIRECTORY:
|
||||
if (RoomListWindow::Check() == true)
|
||||
RoomListWindow::Get()->PostMessage(msg);
|
||||
break;
|
||||
case IM_PROTOCOL_DISABLE:
|
||||
fStatusView->MessageReceived(msg);
|
||||
break;
|
||||
|
@ -343,79 +412,52 @@ MainWindow::WorkspaceActivated(int32 workspace, bool active)
|
|||
void
|
||||
MainWindow::SetConversation(Conversation* chat)
|
||||
{
|
||||
fConversation = chat;
|
||||
if (chat != NULL) {
|
||||
SetConversationView(chat->GetView());
|
||||
if (chat == NULL) {
|
||||
SetTitle(APP_NAME);
|
||||
SetConversationView(fBackupChatView);
|
||||
return;
|
||||
}
|
||||
|
||||
_EnsureConversationView(chat);
|
||||
|
||||
bool found = false;
|
||||
BLayoutItem* item = fChatList.ValueFor(chat, &found);
|
||||
if (found == false)
|
||||
return;
|
||||
|
||||
BString title(chat->GetName());
|
||||
title << " ― " << APP_NAME;
|
||||
SetTitle(title.String());
|
||||
}
|
||||
else {
|
||||
SetConversationView(fBackupChatView);
|
||||
SetTitle(APP_NAME);
|
||||
}
|
||||
|
||||
// Remove "Protocol" menu
|
||||
BMenuItem* chatMenuItem = fMenuBar->FindItem(B_TRANSLATE("Chat"));
|
||||
BMenuItem* protocolMenuItem = fMenuBar->FindItem(B_TRANSLATE("Protocol"));
|
||||
if (protocolMenuItem != NULL)
|
||||
fMenuBar->RemoveItem(protocolMenuItem);
|
||||
|
||||
// Populate new "Protocol" menu if need be
|
||||
BMenu* protocolMenu = _CreateProtocolMenu();
|
||||
if (protocolMenu != NULL)
|
||||
fMenuBar->AddItem(protocolMenu, fMenuBar->IndexOf(chatMenuItem) + 1);
|
||||
|
||||
_SaveWeights();
|
||||
fConversation = chat;
|
||||
fChatLayout->SetVisibleItem(item);
|
||||
_ApplyWeights();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::SetConversationView(ConversationView* chatView)
|
||||
MainWindow::SetConversationView(ConversationView* view)
|
||||
{
|
||||
// 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);
|
||||
int32 index = fChatLayout->IndexOfView(view);
|
||||
if (index < 0) {
|
||||
BLayoutItem* item = fChatLayout->AddView(view);
|
||||
fChatLayout->SetVisibleItem(item);
|
||||
} else
|
||||
fChatLayout->SetVisibleItem(index);
|
||||
|
||||
fRightView->RemoveChild(fRightView->FindView("chatView"));
|
||||
fChatView = chatView;
|
||||
|
||||
fRightView->AddChild(fChatView, 9);
|
||||
|
||||
// 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();
|
||||
BObjectList<BMessage> menuItems = looper->Protocol()->MenuBarItems();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// Apply saved weights
|
||||
fSplitView->SetItemWeight(0, AppPreferences::Get()->MainWindowListWeight, true);
|
||||
fSplitView->SetItemWeight(1, AppPreferences::Get()->MainWindowChatWeight, true);
|
||||
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;
|
||||
_ApplyWeights();
|
||||
}
|
||||
|
||||
|
||||
|
@ -424,6 +466,13 @@ MainWindow::RemoveConversation(Conversation* chat)
|
|||
{
|
||||
SetConversation(NULL);
|
||||
|
||||
bool found = false;
|
||||
BLayoutItem* item = fChatList.ValueFor(chat, &found);
|
||||
if (item != NULL)
|
||||
item->RemoveSelf();
|
||||
if (found == true)
|
||||
fChatList.RemoveItemFor(chat);
|
||||
|
||||
int32 index = fListView->IndexOf(chat->GetListItem());
|
||||
if (index > 0)
|
||||
index--;
|
||||
|
@ -448,24 +497,15 @@ MainWindow::_InitInterface()
|
|||
{
|
||||
// Left side of window, Roomlist + Status
|
||||
fListView = new ConversationListView("roomList");
|
||||
fStatusView = new StatusView("statusView", fServer);
|
||||
fStatusView = new StatusView("statusView");
|
||||
fSplitView = new BSplitView(B_HORIZONTAL, 0);
|
||||
|
||||
BScrollView* listScroll = new BScrollView("roomListScroll", fListView,
|
||||
true, false, B_NO_BORDER);
|
||||
|
||||
// Right-side of window, Chat + Textbox
|
||||
fRightView = new BSplitView(B_VERTICAL, 0);
|
||||
fChatLayout = new BCardLayout();
|
||||
fBackupChatView = new ConversationView();
|
||||
fChatView = fBackupChatView;
|
||||
|
||||
// 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);
|
||||
|
||||
BLayoutBuilder::Group<>(this, B_VERTICAL)
|
||||
.Add((fMenuBar = _CreateMenuBar()))
|
||||
|
@ -476,12 +516,11 @@ MainWindow::_InitInterface()
|
|||
.Add(listScroll, 1)
|
||||
.Add(fStatusView)
|
||||
.End()
|
||||
.Add(fRightView, 5)
|
||||
.Add(fChatLayout, 5)
|
||||
.End()
|
||||
.End()
|
||||
.End();
|
||||
|
||||
SetConversation(NULL);
|
||||
_ToggleMenuItems();
|
||||
}
|
||||
|
||||
|
@ -495,6 +534,8 @@ MainWindow::_CreateMenuBar()
|
|||
BMenu* programMenu = new BMenu(B_TRANSLATE("Program"));
|
||||
programMenu->AddItem(new BMenuItem(B_TRANSLATE("About" B_UTF8_ELLIPSIS),
|
||||
new BMessage(B_ABOUT_REQUESTED)));
|
||||
programMenu->AddItem(new BMenuItem(B_TRANSLATE("Help" B_UTF8_ELLIPSIS),
|
||||
new BMessage(APP_SHOW_HELP)));
|
||||
programMenu->AddItem(new BMenuItem(B_TRANSLATE("Preferences" B_UTF8_ELLIPSIS),
|
||||
new BMessage(APP_SHOW_SETTINGS), ',', B_COMMAND_KEY));
|
||||
programMenu->AddItem(new BSeparatorItem());
|
||||
|
@ -506,12 +547,17 @@ MainWindow::_CreateMenuBar()
|
|||
BMenu* chatMenu = new BMenu(B_TRANSLATE("Chat"));
|
||||
chatMenu->AddItem(new BMenuItem(B_TRANSLATE("Join room" B_UTF8_ELLIPSIS),
|
||||
new BMessage(APP_JOIN_ROOM), 'J', B_COMMAND_KEY));
|
||||
chatMenu->AddItem(new BMenuItem(B_TRANSLATE("Room directory" B_UTF8_ELLIPSIS),
|
||||
new BMessage(APP_ROOM_DIRECTORY)));
|
||||
chatMenu->SetTargetForItems(this);
|
||||
chatMenu->AddSeparatorItem();
|
||||
chatMenu->AddItem(new BMenuItem(B_TRANSLATE("New room" B_UTF8_ELLIPSIS),
|
||||
new BMessage(APP_NEW_ROOM), 'N', B_COMMAND_KEY));
|
||||
chatMenu->AddItem(new BMenuItem(B_TRANSLATE("New chat" B_UTF8_ELLIPSIS),
|
||||
new BMessage(APP_NEW_CHAT), 'M', B_COMMAND_KEY));
|
||||
chatMenu->SetTargetForItems(this);
|
||||
chatMenu->AddSeparatorItem();
|
||||
chatMenu->AddItem(new BMenuItem(B_TRANSLATE("Find" B_UTF8_ELLIPSIS),
|
||||
new BMessage(APP_ROOM_SEARCH), 'F', B_COMMAND_KEY));
|
||||
|
||||
// Roster
|
||||
BMenu* rosterMenu = new BMenu(B_TRANSLATE("Roster"));
|
||||
|
@ -572,6 +618,40 @@ MainWindow::_RefreshAccountsMenu()
|
|||
}
|
||||
|
||||
|
||||
BMenu*
|
||||
MainWindow::_CreateProtocolMenu()
|
||||
{
|
||||
if (fConversation == NULL)
|
||||
return NULL;
|
||||
|
||||
ProtocolLooper* looper = fConversation->GetProtocolLooper();
|
||||
BObjectList<BMessage> menuItems = looper->Protocol()->MenuBarItems();
|
||||
if (menuItems.CountItems() == 0)
|
||||
return NULL;
|
||||
|
||||
BMenu* menu = new BMenu(B_TRANSLATE("Protocol"));
|
||||
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);
|
||||
menu->AddItem(item);
|
||||
}
|
||||
return menu;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::_ToggleMenuItems()
|
||||
{
|
||||
|
@ -583,7 +663,8 @@ MainWindow::_ToggleMenuItems()
|
|||
if (chatMenu == NULL || rosterMenu == NULL)
|
||||
return;
|
||||
|
||||
bool enabled = (fServer != NULL && fServer->GetAccounts().CountItems() > 0);
|
||||
Server* server = Server::Get();
|
||||
bool enabled = (server != NULL && server->GetAccounts().CountItems() > 0);
|
||||
|
||||
for (int i = 0; i < chatMenu->CountItems(); i++)
|
||||
chatMenu->ItemAt(i)->SetEnabled(enabled);
|
||||
|
@ -603,13 +684,19 @@ MainWindow::_ToggleMenuItems()
|
|||
ConversationItem*
|
||||
MainWindow::_EnsureConversationItem(BMessage* msg)
|
||||
{
|
||||
ChatMap chats = fServer->Conversations();
|
||||
|
||||
BString chat_id = msg->FindString("chat_id");
|
||||
Conversation* chat = fServer->ConversationById(chat_id, msg->FindInt64("instance"));
|
||||
ConversationItem* item = chat->GetListItem();
|
||||
int64 conversation_id = msg->FindInt64("instance");
|
||||
Conversation* chat = Server::Get()->ConversationById(chat_id, conversation_id);
|
||||
if (chat == NULL) {
|
||||
printf("error: Conversation %" B_PRId64 " in '%s' not found!\n", conversation_id, chat_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (chat != NULL) {
|
||||
_EnsureConversationView(chat);
|
||||
|
||||
// Add conversation item if necessary, return it
|
||||
ConversationItem* item;
|
||||
if (chat != NULL && (item = chat->GetListItem()) != NULL) {
|
||||
if (fListView->HasItem(item))
|
||||
fListView->InvalidateItem(fListView->IndexOf(item));
|
||||
else if (item != NULL) {
|
||||
|
@ -625,6 +712,62 @@ MainWindow::_EnsureConversationItem(BMessage* msg)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::_EnsureConversationView(Conversation* chat)
|
||||
{
|
||||
// Add conversation's view if necessary
|
||||
bool added = false;
|
||||
fChatList.ValueFor(chat, &added);
|
||||
|
||||
if (added == false) {
|
||||
BLayoutItem* item = fChatLayout->AddView(chat->GetView());
|
||||
if (item != NULL)
|
||||
fChatList.AddItem(chat, item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::_ApplyWeights()
|
||||
{
|
||||
// Chat-list and chat-view splitter
|
||||
fSplitView->SetItemWeight(0, AppPreferences::Get()->MainWindowListWeight, true);
|
||||
fSplitView->SetItemWeight(1, AppPreferences::Get()->MainWindowChatWeight, true);
|
||||
|
||||
// Chat-view's weights
|
||||
float horizChat, horizList, vertChat, vertSend;
|
||||
horizChat = AppPreferences::Get()->ChatViewHorizChatWeight;
|
||||
horizList = AppPreferences::Get()->ChatViewHorizListWeight;
|
||||
vertChat = AppPreferences::Get()->ChatViewVertChatWeight;
|
||||
vertSend = AppPreferences::Get()->ChatViewVertSendWeight;
|
||||
|
||||
BLayoutItem* item = fChatLayout->VisibleItem();
|
||||
if (item != NULL)
|
||||
((ConversationView*)item->View())->SetWeights(horizChat, horizList, vertChat, vertSend);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::_SaveWeights()
|
||||
{
|
||||
// Chat-list and chat-view splitter
|
||||
AppPreferences::Get()->MainWindowListWeight = fSplitView->ItemWeight((int32)0);
|
||||
AppPreferences::Get()->MainWindowChatWeight = fSplitView->ItemWeight((int32)1);
|
||||
|
||||
// ChatView's weights
|
||||
float horizChat, horizList, vertChat, vertSend;
|
||||
BLayoutItem* item = fChatLayout->VisibleItem();
|
||||
if (item == NULL)
|
||||
return;
|
||||
((ConversationView*)item->View())->GetWeights(&horizChat, &horizList, &vertChat, &vertSend);
|
||||
|
||||
AppPreferences::Get()->ChatViewHorizChatWeight = horizChat;
|
||||
AppPreferences::Get()->ChatViewHorizListWeight = horizList;
|
||||
AppPreferences::Get()->ChatViewVertChatWeight = vertChat;
|
||||
AppPreferences::Get()->ChatViewVertSendWeight = vertSend;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
MainWindow::_PopulateWithAccounts(BMenu* menu, ProtocolSettings* settings)
|
||||
{
|
||||
|
@ -639,7 +782,7 @@ MainWindow::_PopulateWithAccounts(BMenu* menu, ProtocolSettings* settings)
|
|||
|
||||
BString toggleLabel = B_TRANSLATE("Enable");
|
||||
bool isActive = false;
|
||||
int64 instance = fServer->GetActiveAccounts().ValueFor(*account, &isActive);
|
||||
int64 instance = Server::Get()->GetActiveAccounts().ValueFor(*account, &isActive);
|
||||
if (isActive == true)
|
||||
toggleLabel = B_TRANSLATE("Disable");
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright 2021, Jaidyn Levesque. All rights reserved.
|
||||
* Copyright 2009-2011, Andrea Anzani. All rights reserved.
|
||||
* Copyright 2009-2011, Pier Luigi Fiorini. All rights reserved.
|
||||
* Copyright 2021-2022, Jaidyn Levesque. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _MAIN_WINDOW_H
|
||||
|
@ -9,8 +9,10 @@
|
|||
|
||||
#include <Window.h>
|
||||
|
||||
#include "Server.h"
|
||||
#include "libsupport/KeyMap.h"
|
||||
|
||||
class BCardLayout;
|
||||
class BLayoutItem;
|
||||
class BMenu;
|
||||
class BSplitView;
|
||||
class BTextView;
|
||||
|
@ -21,9 +23,7 @@ class ConversationListView;
|
|||
class ConversationView;
|
||||
class ProtocolSettings;
|
||||
class RosterItem;
|
||||
class RosterEditWindow;
|
||||
class RosterWindow;
|
||||
class Server;
|
||||
class StatusView;
|
||||
|
||||
|
||||
|
@ -32,6 +32,7 @@ public:
|
|||
MainWindow();
|
||||
|
||||
void Start();
|
||||
void Show();
|
||||
virtual bool QuitRequested();
|
||||
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
|
@ -41,43 +42,45 @@ public:
|
|||
bool active);
|
||||
|
||||
void SetConversation(Conversation* chat);
|
||||
void SetConversationView(ConversationView* chatView);
|
||||
void SetConversationView(ConversationView* view);
|
||||
void RemoveConversation(Conversation* chat);
|
||||
void SortConversation(Conversation* chat);
|
||||
|
||||
Server* GetServer() const { return fServer; }
|
||||
|
||||
private:
|
||||
void _InitInterface();
|
||||
|
||||
BMenuBar* _CreateMenuBar();
|
||||
BMenu* _CreateAccountsMenu();
|
||||
void _RefreshAccountsMenu();
|
||||
BMenu* _CreateProtocolMenu();
|
||||
|
||||
void _ToggleMenuItems();
|
||||
|
||||
ConversationItem*
|
||||
_EnsureConversationItem(BMessage* msg);
|
||||
void _EnsureConversationView(Conversation* chat);
|
||||
|
||||
void _ApplyWeights();
|
||||
void _SaveWeights();
|
||||
|
||||
bool _PopulateWithAccounts(BMenu* menu,
|
||||
ProtocolSettings* settings);
|
||||
void _ReplaceMenu(const char* name, BMenu* newMenu);
|
||||
|
||||
Server* fServer;
|
||||
RosterWindow* fRosterWindow;
|
||||
RosterEditWindow* fRosterEditWindow;
|
||||
bool fWorkspaceChanged;
|
||||
BMenuBar* fMenuBar;
|
||||
|
||||
KeyMap<Conversation*, BLayoutItem*> fChatList;
|
||||
|
||||
// Left panel, chat list
|
||||
ConversationListView* fListView;
|
||||
StatusView* fStatusView;
|
||||
BSplitView* fSplitView;
|
||||
|
||||
// Right panel, chat
|
||||
BSplitView* fRightView;
|
||||
BCardLayout* fChatLayout;
|
||||
Conversation* fConversation;
|
||||
ConversationView* fChatView;
|
||||
ConversationView* fBackupChatView;
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
* Copyright 2021, Jaidyn Levesque <jadedctrl@teknik.io>
|
||||
* All rights reserved. Distributed under the terms of the MIT license.
|
||||
*/
|
||||
|
||||
#include "RoomListWindow.h"
|
||||
|
||||
#include <Button.h>
|
||||
#include <Catalog.h>
|
||||
#include <ColumnListView.h>
|
||||
#include <ColumnTypes.h>
|
||||
#include <LayoutBuilder.h>
|
||||
#include <StringList.h>
|
||||
|
||||
#include "AccountsMenu.h"
|
||||
#include "AppPreferences.h"
|
||||
#include "ChatProtocolMessages.h"
|
||||
#include "RoomListRow.h"
|
||||
#include "Server.h"
|
||||
|
||||
|
||||
#undef B_TRANSLATION_CONTEXT
|
||||
#define B_TRANSLATION_CONTEXT "Room directory"
|
||||
|
||||
|
||||
const uint32 kSelectAcc = 'rlse';
|
||||
const uint32 kSelectAll = 'rlsa';
|
||||
const uint32 kJoinRoom = 'join';
|
||||
RoomListWindow* RoomListWindow::fInstance = NULL;
|
||||
|
||||
|
||||
RoomListWindow::RoomListWindow()
|
||||
:
|
||||
BWindow(AppPreferences::Get()->RoomDirectoryRect,
|
||||
B_TRANSLATE("Room directory"), B_FLOATING_WINDOW,
|
||||
B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS),
|
||||
fAccount(-1)
|
||||
{
|
||||
_InitInterface();
|
||||
CenterOnScreen();
|
||||
|
||||
BMessage* request = new BMessage(IM_MESSAGE);
|
||||
request->AddInt32("im_what", IM_GET_ROOM_DIRECTORY);
|
||||
Server::Get()->SendAllProtocolMessage(request);
|
||||
}
|
||||
|
||||
|
||||
RoomListWindow::~RoomListWindow()
|
||||
{
|
||||
fInstance = NULL;
|
||||
AppPreferences::Get()->RoomDirectoryRect = Bounds();
|
||||
_EmptyList();
|
||||
|
||||
for (int i = 0; i < fRows.CountItems(); i++) {
|
||||
BObjectList<RoomListRow>* list = fRows.ValueAt(i);
|
||||
if (list != NULL)
|
||||
delete list;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RoomListWindow*
|
||||
RoomListWindow::Get()
|
||||
{
|
||||
if (fInstance == NULL)
|
||||
fInstance = new RoomListWindow();
|
||||
return fInstance;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
RoomListWindow::Check()
|
||||
{
|
||||
return (fInstance != NULL);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RoomListWindow::MessageReceived(BMessage* msg)
|
||||
{
|
||||
switch (msg->what) {
|
||||
case IM_MESSAGE:
|
||||
{
|
||||
if (msg->GetInt32("im_what", -1) != IM_ROOM_DIRECTORY)
|
||||
break;
|
||||
|
||||
int64 instance;
|
||||
BString id;
|
||||
if (msg->FindInt64("instance", &instance) == B_OK
|
||||
&& msg->FindString("chat_id", &id) == B_OK) {
|
||||
RoomListRow* row = new RoomListRow(msg);
|
||||
|
||||
bool fnd = false;
|
||||
BObjectList<RoomListRow>* list = fRows.ValueFor(instance, &fnd);
|
||||
if (fnd == false || list == NULL) {
|
||||
list = new BObjectList<RoomListRow>(20, true);
|
||||
fRows.AddItem(instance, list);
|
||||
}
|
||||
list->AddItem(row);
|
||||
|
||||
if (fAccount == -1 || instance == fAccount)
|
||||
fListView->AddRow(row);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kSelectAll:
|
||||
{
|
||||
_EmptyList();
|
||||
for (int i = 0; i < fRows.CountItems(); i++) {
|
||||
BObjectList<RoomListRow>* list = fRows.ValueAt(i);
|
||||
if (list != NULL)
|
||||
for (int j = 0; j < list->CountItems(); j++) {
|
||||
RoomListRow* row = list->ItemAt(j);
|
||||
if (row != NULL)
|
||||
fListView->AddRow(row);
|
||||
}
|
||||
}
|
||||
fAccount = -1;
|
||||
break;
|
||||
}
|
||||
case kSelectAcc:
|
||||
{
|
||||
msg->PrintToStream();
|
||||
int64 instance;
|
||||
if (msg->FindInt64("instance", &instance) == B_OK) {
|
||||
bool fnd = false;
|
||||
BObjectList<RoomListRow>* list = fRows.ValueFor(instance, &fnd);
|
||||
if (fnd == false || list == NULL)
|
||||
break;
|
||||
|
||||
_EmptyList();
|
||||
for (int i = 0; i < list->CountItems(); i++) {
|
||||
RoomListRow* row = list->ItemAt(i);
|
||||
if (row != NULL)
|
||||
fListView->AddRow(row);
|
||||
}
|
||||
fAccount = instance;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kJoinRoom:
|
||||
{
|
||||
RoomListRow* row =
|
||||
(RoomListRow*)fListView->CurrentSelection();
|
||||
|
||||
if (row != NULL) {
|
||||
BMessage* joinMsg = row->Message();
|
||||
joinMsg->ReplaceInt32("im_what", IM_JOIN_ROOM);
|
||||
Server::Get()->SendProtocolMessage(joinMsg);
|
||||
Quit();
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
BWindow::MessageReceived(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RoomListWindow::_InitInterface()
|
||||
{
|
||||
float size = BFont().Size();
|
||||
BStringColumn* name = new BStringColumn(B_TRANSLATE("Name"), 130, 50, 300,
|
||||
B_TRUNCATE_END);
|
||||
BStringColumn* desc = new BStringColumn(B_TRANSLATE("Description"), 270,
|
||||
50, 5000, B_TRUNCATE_END);
|
||||
BStringColumn* category = new BStringColumn("Category", 90, 50, 300,
|
||||
B_TRUNCATE_END);
|
||||
BIntegerColumn* users = new BIntegerColumn("Users", 70, 10, 300);
|
||||
|
||||
fListView = new BColumnListView("roomList", B_NAVIGABLE, B_PLAIN_BORDER);
|
||||
fListView->SetInvocationMessage(new BMessage(kJoinRoom));
|
||||
fListView->SetSelectionMode(B_SINGLE_SELECTION_LIST);
|
||||
fListView->AddColumn(name, kNameColumn);
|
||||
fListView->AddColumn(desc, kDescColumn);
|
||||
fListView->AddColumn(category, kCatColumn);
|
||||
fListView->AddColumn(users, kUserColumn);
|
||||
|
||||
AccountsMenu* accsMenu = new AccountsMenu("accounts", BMessage(kSelectAcc),
|
||||
new BMessage(kSelectAll));
|
||||
BMenuField* accsField = new BMenuField(NULL, accsMenu);
|
||||
|
||||
fJoinButton = new BButton("joinRoom", B_TRANSLATE("Join"),
|
||||
new BMessage(kJoinRoom));
|
||||
|
||||
BLayoutBuilder::Group<>(this, B_VERTICAL)
|
||||
.SetInsets(B_USE_DEFAULT_SPACING)
|
||||
.Add(fListView)
|
||||
.AddGroup(B_HORIZONTAL)
|
||||
.Add(accsField)
|
||||
.AddGlue()
|
||||
.Add(fJoinButton)
|
||||
.End()
|
||||
.End();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RoomListWindow::_EmptyList()
|
||||
{
|
||||
BRow* row = fListView->RowAt((int32)0, NULL);
|
||||
while (row != NULL) {
|
||||
fListView->RemoveRow(row);
|
||||
row = fListView->RowAt((int32)0, NULL);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright 2021, Jaidyn Levesque <jadedctrl@teknik.io>
|
||||
* All rights reserved. Distributed under the terms of the MIT license.
|
||||
*/
|
||||
#ifndef _ROOM_LIST_WINDOW_H
|
||||
#define _ROOM_LIST_WINDOW_H
|
||||
|
||||
#include <ObjectList.h>
|
||||
#include <Window.h>
|
||||
|
||||
#include <libsupport/KeyMap.h>
|
||||
|
||||
class BButton;
|
||||
class BColumnListView;
|
||||
class RoomListRow;
|
||||
|
||||
|
||||
typedef KeyMap<int64, BObjectList<RoomListRow>*> RowMap;
|
||||
|
||||
|
||||
class RoomListWindow : public BWindow {
|
||||
public:
|
||||
RoomListWindow();
|
||||
~RoomListWindow();
|
||||
|
||||
static RoomListWindow* Get();
|
||||
static bool Check();
|
||||
|
||||
virtual void MessageReceived(BMessage* msg);
|
||||
|
||||
private:
|
||||
void _InitInterface();
|
||||
|
||||
void _EmptyList();
|
||||
|
||||
BButton* fJoinButton;
|
||||
BColumnListView* fListView;
|
||||
|
||||
RowMap fRows;
|
||||
int64 fAccount;
|
||||
|
||||
static RoomListWindow* fInstance;
|
||||
};
|
||||
|
||||
#endif // _ROOM_LIST_WINDOW_H
|
|
@ -24,9 +24,12 @@
|
|||
#include "AppMessages.h"
|
||||
#include "AppPreferences.h"
|
||||
#include "ChatProtocolMessages.h"
|
||||
#include "Maps.h"
|
||||
#include "ProtocolLooper.h"
|
||||
#include "RosterItem.h"
|
||||
#include "RosterListView.h"
|
||||
#include "RosterView.h"
|
||||
#include "Server.h"
|
||||
#include "TemplateWindow.h"
|
||||
|
||||
|
||||
|
@ -47,14 +50,13 @@ const char* kEditTitle = B_TRANSLATE("Editing contact");
|
|||
RosterEditWindow* RosterEditWindow::fInstance = NULL;
|
||||
|
||||
|
||||
RosterEditWindow::RosterEditWindow(Server* server)
|
||||
RosterEditWindow::RosterEditWindow()
|
||||
:
|
||||
BWindow(BRect(0, 0, 300, 400), B_TRANSLATE("Roster"), B_FLOATING_WINDOW,
|
||||
B_AUTO_UPDATE_SIZE_LIMITS),
|
||||
fServer(server),
|
||||
fEditingWindow(NULL)
|
||||
{
|
||||
fRosterView = new RosterView("buddyView", server);
|
||||
fRosterView = new RosterView("buddyView");
|
||||
fRosterView->SetInvocationMessage(new BMessage(kEditMember));
|
||||
fRosterView->SetManualString(BString("Add %user% as contact"
|
||||
B_UTF8_ELLIPSIS));
|
||||
|
@ -104,10 +106,10 @@ RosterEditWindow::~RosterEditWindow()
|
|||
|
||||
|
||||
RosterEditWindow*
|
||||
RosterEditWindow::Get(Server* server)
|
||||
RosterEditWindow::Get()
|
||||
{
|
||||
if (fInstance == NULL) {
|
||||
fInstance = new RosterEditWindow(server);
|
||||
fInstance = new RosterEditWindow();
|
||||
}
|
||||
return fInstance;
|
||||
}
|
||||
|
@ -172,7 +174,7 @@ RosterEditWindow::MessageReceived(BMessage* message)
|
|||
|
||||
fEditingWindow =
|
||||
new TemplateWindow(title, "roster",
|
||||
edit, fServer, instance);
|
||||
edit, instance);
|
||||
fEditingWindow->Show();
|
||||
|
||||
if (ritem == NULL) {
|
||||
|
@ -188,7 +190,7 @@ RosterEditWindow::MessageReceived(BMessage* message)
|
|||
add->AddInt32("im_what", IM_ROSTER_ADD_CONTACT);
|
||||
TemplateWindow* win =
|
||||
new TemplateWindow(B_TRANSLATE(kAddTitle), "roster",
|
||||
add, fServer);
|
||||
add);
|
||||
win->Show();
|
||||
break;
|
||||
}
|
||||
|
@ -216,7 +218,7 @@ RosterEditWindow::MessageReceived(BMessage* message)
|
|||
}
|
||||
case kSelAccount:
|
||||
{
|
||||
AccountInstances accounts = fServer->GetActiveAccounts();
|
||||
AccountInstances accounts = Server::Get()->GetActiveAccounts();
|
||||
|
||||
int index = message->FindInt32("index") - 1;
|
||||
if (index < 0 || index > (accounts.CountItems() - 1))
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
|
||||
#include <Window.h>
|
||||
|
||||
#include "Server.h"
|
||||
|
||||
class BMenuField;
|
||||
class RosterItem;
|
||||
class RosterView;
|
||||
|
@ -26,9 +24,9 @@ class TemplateWindow;
|
|||
the server with contact info, once a contact is selected. */
|
||||
class RosterEditWindow : public BWindow {
|
||||
public:
|
||||
RosterEditWindow(Server* server);
|
||||
RosterEditWindow();
|
||||
~RosterEditWindow();
|
||||
static RosterEditWindow* Get(Server* server);
|
||||
static RosterEditWindow* Get();
|
||||
static bool Check();
|
||||
|
||||
void MessageReceived(BMessage* message);
|
||||
|
@ -40,7 +38,6 @@ private:
|
|||
BString fEditingUser;
|
||||
TemplateWindow* fEditingWindow;
|
||||
|
||||
Server* fServer;
|
||||
RosterView* fRosterView;
|
||||
|
||||
static RosterEditWindow* fInstance;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "RosterItem.h"
|
||||
#include "RosterListView.h"
|
||||
#include "RosterView.h"
|
||||
#include "Server.h"
|
||||
|
||||
|
||||
const uint32 kSendMessage = 'RWSM';
|
||||
|
@ -33,20 +34,19 @@ const uint32 kSelNoAccount = 'RWNA';
|
|||
|
||||
|
||||
RosterWindow::RosterWindow(const char* title, BMessage* selectMsg,
|
||||
BMessenger* messenger, Server* server, bigtime_t instance)
|
||||
BMessenger* messenger, bigtime_t instance)
|
||||
:
|
||||
BWindow(BRect(0, 0, 300, 400), title, B_FLOATING_WINDOW,
|
||||
B_AUTO_UPDATE_SIZE_LIMITS),
|
||||
fTarget(messenger),
|
||||
fMessage(selectMsg),
|
||||
fServer(server)
|
||||
fMessage(selectMsg)
|
||||
{
|
||||
fRosterView = new RosterView("buddyView", server, instance),
|
||||
fRosterView = new RosterView("buddyView", instance);
|
||||
fRosterView->SetInvocationMessage(new BMessage(kSendMessage));
|
||||
|
||||
fOkButton = new BButton("OK", new BMessage(kSendMessage));
|
||||
|
||||
AccountInstances accounts = fServer->GetActiveAccounts();
|
||||
AccountInstances accounts = Server::Get()->GetActiveAccounts();
|
||||
|
||||
// If a specific instance is given, disallow selecting other accounts
|
||||
// In fact, don't even bother populating with them
|
||||
|
@ -119,7 +119,7 @@ RosterWindow::MessageReceived(BMessage* message)
|
|||
}
|
||||
case kSelAccount:
|
||||
{
|
||||
AccountInstances accounts = fServer->GetActiveAccounts();
|
||||
AccountInstances accounts = Server::Get()->GetActiveAccounts();
|
||||
|
||||
int index = message->FindInt32("index") - 1;
|
||||
if (index < 0 || index > (accounts.CountItems() - 1))
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
|
||||
#include <Window.h>
|
||||
|
||||
#include "Server.h"
|
||||
|
||||
class BMenuField;
|
||||
class RosterItem;
|
||||
class RosterView;
|
||||
|
@ -26,7 +24,7 @@ class RosterView;
|
|||
class RosterWindow : public BWindow {
|
||||
public:
|
||||
RosterWindow(const char* title, BMessage* selectMsg, BMessenger* messenger,
|
||||
Server* server, bigtime_t instance = -1);
|
||||
bigtime_t instance = -1);
|
||||
|
||||
void MessageReceived(BMessage* message);
|
||||
|
||||
|
@ -36,8 +34,6 @@ private:
|
|||
BButton* fOkButton;
|
||||
BMenuField* fAccountField;
|
||||
|
||||
Server* fServer;
|
||||
|
||||
RosterView* fRosterView;
|
||||
BMessenger* fTarget;
|
||||
BMessage* fMessage;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "AccountsMenu.h"
|
||||
#include "ChatProtocolMessages.h"
|
||||
#include "Server.h"
|
||||
#include "TemplateView.h"
|
||||
|
||||
|
||||
|
@ -33,11 +34,10 @@ const uint32 kAccSelected = 'JWas';
|
|||
|
||||
|
||||
TemplateWindow::TemplateWindow(const char* title, const char* templateType,
|
||||
BMessage* msg, Server* server, bigtime_t instance)
|
||||
BMessage* msg, bigtime_t instance)
|
||||
:
|
||||
BWindow(BRect(0, 0, 400, 100), title, B_FLOATING_WINDOW,
|
||||
B_NOT_RESIZABLE | B_AUTO_UPDATE_SIZE_LIMITS | B_CLOSE_ON_ESCAPE),
|
||||
fServer(server),
|
||||
fSelectedAcc(instance),
|
||||
fTemplate(NULL),
|
||||
fTemplateType(templateType),
|
||||
|
@ -51,11 +51,10 @@ TemplateWindow::TemplateWindow(const char* title, const char* templateType,
|
|||
|
||||
|
||||
TemplateWindow::TemplateWindow(const char* title, ProtocolTemplate* temp,
|
||||
BMessage* msg, Server* server, bigtime_t instance)
|
||||
BMessage* msg, bigtime_t instance)
|
||||
:
|
||||
BWindow(BRect(0, 0, 400, 100), title, B_FLOATING_WINDOW,
|
||||
B_NOT_RESIZABLE | B_AUTO_UPDATE_SIZE_LIMITS | B_CLOSE_ON_ESCAPE),
|
||||
fServer(server),
|
||||
fSelectedAcc(-1),
|
||||
fTemplate(temp),
|
||||
fMessage(msg)
|
||||
|
@ -99,7 +98,7 @@ TemplateWindow::MessageReceived(BMessage* msg)
|
|||
break;
|
||||
}
|
||||
|
||||
ProtocolLooper* looper = fServer->GetProtocolLooper(fSelectedAcc);
|
||||
ProtocolLooper* looper = Server::Get()->GetProtocolLooper(fSelectedAcc);
|
||||
if (looper == NULL)
|
||||
break;
|
||||
looper->PostMessage(settings);
|
||||
|
@ -131,7 +130,7 @@ void
|
|||
TemplateWindow::_InitInterface(bigtime_t instance)
|
||||
{
|
||||
fTemplateView = new TemplateView("template");
|
||||
AccountInstances accounts = fServer->GetActiveAccounts();
|
||||
AccountInstances accounts = Server::Get()->GetActiveAccounts();
|
||||
|
||||
if (instance > -1) {
|
||||
BMenu* accountMenu = new BMenu("accountMenu");
|
||||
|
@ -185,7 +184,7 @@ TemplateWindow::_LoadTemplate()
|
|||
if (fTemplateType.IsEmpty() == true)
|
||||
return;
|
||||
|
||||
ProtocolLooper* looper = fServer->GetProtocolLooper(fSelectedAcc);
|
||||
ProtocolLooper* looper = Server::Get()->GetProtocolLooper(fSelectedAcc);
|
||||
if (looper == NULL)
|
||||
return;
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include <Window.h>
|
||||
|
||||
#include "ProtocolTemplate.h"
|
||||
#include "Server.h"
|
||||
|
||||
class BAlert;
|
||||
class BMenu;
|
||||
|
@ -26,12 +25,12 @@ public:
|
|||
* via ChatProtocol::SettingsTemplate() */
|
||||
TemplateWindow(const char* title,
|
||||
const char* templateType, BMessage* msg,
|
||||
Server* server, bigtime_t instance = -1);
|
||||
bigtime_t instance = -1);
|
||||
|
||||
/*! Use only the given template. */
|
||||
TemplateWindow(const char* title,
|
||||
ProtocolTemplate* temp, BMessage* msg,
|
||||
Server* server, bigtime_t instance = -1);
|
||||
bigtime_t instance = -1);
|
||||
|
||||
virtual void MessageReceived(BMessage* msg);
|
||||
|
||||
|
@ -41,7 +40,6 @@ private:
|
|||
void _InitInterface(bigtime_t instance);
|
||||
void _LoadTemplate();
|
||||
|
||||
Server* fServer;
|
||||
int64 fSelectedAcc;
|
||||
BMenuField* fMenuField;
|
||||
|
||||
|
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 2.1 KiB |
|
@ -1,19 +1,16 @@
|
|||
|
||||
resource vector_icon array {
|
||||
$"6E6369660E05000200060237E670B8880E39469D39AE144A52234B0D2500C6D7"
|
||||
$"F5FF6B94DD03EC6666020006023B2B47BB18653D0FA53D225148297046CA1900"
|
||||
$"FFEC4BFFF0A506020006023B3049396B0ABA90833C646E4A101543299500FFFF"
|
||||
$"FFFFFFF289020006023C71E33A0C78BA15E43C7D2149055549455700E3EDFFFF"
|
||||
$"9EC2FF03FFACAC020006023A1DA6393F04BBB5BC3C6B074AEA3648091100F99B"
|
||||
$"05FFFCB23D03003CB00200060230B31E3A09B9BB024238A12F4BAB534AFF0B00"
|
||||
$"A3043CFFFFDCE603CD4D4D030D296402000602BD498B3E1159BF219BBE7D2F4B"
|
||||
$"E71F4AB31300C13E3EFFE27A7A0401740D0A06322E323E42464C3C4C2C3D260A"
|
||||
$"04322E323E424642350A04322E42354C2C3D260A04423542464C3C4C2C0A0338"
|
||||
$"423C4D3C440A08335C395C41544F5C555C6051594D3E510A0422422252325A32"
|
||||
$"490A04224232493C402D3A0A043249325A3C503C400A043E42C35DC27AC751BE"
|
||||
$"F3493A0A04C35DC27A4E495840C751BEF30A05424BC08BC7B74E5A4E49C35DC2"
|
||||
$"7A0A053E423E52C08BC7B7424BC35DC27A100A0D0105000A0001003010340117"
|
||||
$"8400040A0101012010340A0801032010340A0B01042020210A010107000A0001"
|
||||
$"00302C3401178400040A02010B000A0A010C000A090103202C340A06010A000A"
|
||||
$"0C0109000A0001001001178400040A030101000A040102000A07010300"
|
||||
$"6E636966040500020106033D835C3C19B2BA8B0B3C20794769624A510E00FFFF"
|
||||
$"FFB4FFE405FFFFA405020106023D835C3C19B2BA8B0B3C20794769624A510E00"
|
||||
$"FFE405FFFFA405020106033D429E3C5148BB5ADA3C5C1B4A23AA46EC1800FFFF"
|
||||
$"FFB47FE583FF04B10C0902093F404644383C273F2E3A244122482245224D2755"
|
||||
$"245126572256245725582A5828592C5A315C2F5B345D3C5E385E425E4957475C"
|
||||
$"4D4E02043F4044433D3FBC95BE953B3D333D3D493844424E4A5148534A4A0403"
|
||||
$"3B2F4E2F4E2D4E2A4D2F532D522F530003334F334F364F345337533755325636"
|
||||
$"59325602085645C8FEC3AFCA30C0E55E3A5E405EBA4D52B58359B71B4AB38537"
|
||||
$"B51D3EB31FBA16B69933353130363E4A4641444D475346C657C27B554BCB01C6"
|
||||
$"35584F5A4F080239BA0539BA6B0802BD1CBC1DBD2FBCA908023E37423904032E"
|
||||
$"4535473C4739473F4540070A000100123FFFFE2FDACEAFDACE3FFFFE3AB6A5B8"
|
||||
$"4CC101178400040A010100000A020101000A000202031001178210040A000104"
|
||||
$"1001178400040A030104000A000407050608100117821004"
|
||||
};
|
||||
|
|
After Width: | Height: | Size: 2.1 KiB |
|
@ -0,0 +1,25 @@
|
|||
|
||||
resource vector_icon {
|
||||
$"6E63696601050003020E2040204020C400206020C840216023602260B54C6026"
|
||||
$"CC3C26CC7926CC05B491CBF1B548CBFBB449CBEDB3BBCBE7B402CBEAB3BBC7DA"
|
||||
$"B3BB40B3BBC3CDB3BBBBB3B3BBB399B3BBB7A6B402B395B491B38EB449B392B5"
|
||||
$"48B38426B34426B37A26B3062320B54C2022202020212020B740204020BB8020"
|
||||
$"40204020402040020E5AB3445AB3445AB37ACAF2B38ECA37B384CB38B392CBC5"
|
||||
$"B399CB7EB395CBC5B7A6CBC540CBC5BBB3CBC5C3CDCBC5CBE7CBC5C7DACB7ECB"
|
||||
$"EACAF2CBF1CB38CBEDCA37CBFB5ACC3C5ACC055ACC795D60CA33605E6060605F"
|
||||
$"6060C840604060C40060BB80602060B7405F205D205E20CA33205AB3445AB306"
|
||||
$"5AB3445AB3445AB3445AB3440222BC52BB80BC52BB80BBF3BBB9BB7937BB8DBC"
|
||||
$"04BB35BC93BB1ABBD5BB1ABC7BBB1ABBA2BB1ABB3CBB1ABB6FBAB9BB3CB9F9BB"
|
||||
$"3CBA59BB3CB998BB3CB8D8BB3CB938BB3CB8D8BCC3B8D8BFD1B8D8BE4AB8D844"
|
||||
$"B8D8C466B8D8C2DFB943C466BA1BC466B9AFC466BA86C46635C466BAF2C46635"
|
||||
$"C35D35C14D35C25535BE7DBB9EBDD6BB64BE32BBFABD4EBD1BBD18BC60BD1BBE"
|
||||
$"68BD18BE8AC1A6BE8ABD7EBE8BC2913DC469BE8CC37DBEF7C466BFCAC45FBF60"
|
||||
$"C462C032C45BC103C455C09AC458C108C34AC114C136C10EC240C11EBF0FC151"
|
||||
$"BDCCC132BDFFC198BD4EC2BDBD18C205BD18C34BBD184ABD69C37BBD29C42CBD"
|
||||
$"E4C444C1A6C4403DC444C291C444C469C444C37DC4ADC466C580C45FC516C462"
|
||||
$"C5E8C45BC6B9C455C650C458C6BCC361C6C3C17AC6BFC26DC6CDBE09C62ABC3E"
|
||||
$"C6AEBCFCC59EBB7CC3A7BB20C4F1BB2EC26EBB13C114BC0BC1D9BB49C0EFBC2F"
|
||||
$"C0A7BC78C0CBBC53C089BC52C04EBC08C06CBC2DBFD1BB68BDF5BB1ABF12BB1A"
|
||||
$"BD29BB1ABC52BB80BCEBBB2BBC52BB80BC52BB80BC52BB80BC52BB80030A0001"
|
||||
$"00000A000101000A00010200"
|
||||
};
|
|
@ -0,0 +1,301 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<title>Chat-O-Matic Documentation</title>
|
||||
<link href='style.css' rel='stylesheet' type='text/css'>
|
||||
</head>
|
||||
<body>
|
||||
<div align="center">
|
||||
<h1>
|
||||
<img width=32px src="img/AppIcon.png" />
|
||||
Chat-O-Matic Documentation
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<p>Chat-O-Matic is a multi-protocol chat program based on
|
||||
<a href="https://github.com/Numerio/Caya">Caya</a>, which has its own roots in the
|
||||
<a href="http://www.eiman.tv/imkit/">IM kit</a> project. Several protocols are supported,
|
||||
including <abbr title="Internet Relay Chat">IRC</abbr>,
|
||||
<abbr title="Extensible Messaging and Presence Protocol">XMPP</abbr>, and more through
|
||||
libpurple.
|
||||
|
||||
<nav>
|
||||
<b>Contents</b>
|
||||
<ul>
|
||||
<li><a href="#window">Main window</a></li>
|
||||
<ul>
|
||||
<li><a href="#room_list">Room list</a></li>
|
||||
<ul>
|
||||
<li><a href="#room_flags">Room options</a></li>
|
||||
</ul>
|
||||
<li><a href="#room_header">Room header</a></li>
|
||||
<li><a href="#user_list">User list</a></li>
|
||||
<ul>
|
||||
<li><a href="#moderation">Moderation</a></li>
|
||||
</ul>
|
||||
<li><a href="#chat_input">Chat input</a></li>
|
||||
<ul>
|
||||
<li><a href="#commands">Commands</a></li>
|
||||
</ul>
|
||||
<li><a href="#status">Status area</a></li>
|
||||
<li><a href="#menu_bar">Menu-bar</a></li>
|
||||
</ul>
|
||||
<li><a href="#preferences">Preferences window</a></li>
|
||||
<li><a href="#roster">Roster windows</a></li>
|
||||
<li><a href="#rooms">Room creation/join windows</a></li>
|
||||
<li><a href="#room_dir">Room directory</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
|
||||
<section id="window">
|
||||
<h2>Main window</h2>
|
||||
|
||||
<img src="img/window.png" />
|
||||
|
||||
|
||||
<section id="room_list">
|
||||
<h3>Room list</h3>
|
||||
|
||||
<img src="img/chat-list.png" />
|
||||
<p>Lists all joined chats that are attached to the current window, ordered by account.
|
||||
Clicking a chat will select it, changing the text buffer,
|
||||
<a href="#user_list">user-list</a>, and <a href="#room_header">room header</a>. If you
|
||||
click on an <i>account's</i> list item, then that account's logs will be shown instead: This
|
||||
might include anything from <abbr title="Message of the Day">MOTDs</abbr> to error messages,
|
||||
depending on the protocol.</p>
|
||||
|
||||
<section id="room_flags">
|
||||
<h4>Room options</h4>
|
||||
<p>If you right-click on a room's list item, you can toggle several per-room options,
|
||||
including:</p>
|
||||
<table>
|
||||
<tr><th>Flag</th><th>Description</th><th>Default</th></tr>
|
||||
<tr><td>Auto-join</td>
|
||||
<td>If the room will be joined after every start-up</td><td>✓</td>
|
||||
</tr>
|
||||
<tr><td>Log messages</td>
|
||||
<td>Whether or not messages will be logged to disk</td><td>✓</td>
|
||||
</tr>
|
||||
<tr><td>Notify on every message</td>
|
||||
<td>Notify if any message is sent to the room</td><td>❌</td></tr>
|
||||
<tr><td>Notify on direct-messages</td>
|
||||
<td>Notify if the user is mentioned, or if message received in one-on-one
|
||||
chat</td><td>✓</td></tr>
|
||||
</table>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id="room_header">
|
||||
<h3>Room header</h3>
|
||||
|
||||
<img src="img/chat-header.png" />
|
||||
|
||||
<p>This little section displays a room's name, topic, and icon.</p>
|
||||
<p>If you have permission to, you can also change a room's topic by clicking on the topic
|
||||
text, typing what you'd like it to be, and hitting <span class="key">ENTER</span>. After
|
||||
hitting <span class="key">ENTER</span>, the text will change back to the previous topic,
|
||||
pending the protocol or server— after which it will update to the new topic.</p>
|
||||
<p>Here, the room name is “#haiku” and the topic “Open-source operating system […].”</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h3 id="user_list">User list</h3>
|
||||
|
||||
<img src="img/user-list.png" />
|
||||
|
||||
<p>This area has a calm, undemanding job— show a list of users in the room. On
|
||||
right-clicking a user item, you'll see a pop-up menu with at least <i>User info…</i>.
|
||||
|
||||
<section>
|
||||
<h4 id="moderation">Moderation</h4>
|
||||
<p>Depending on your user's permissions, you might see more than <i>User info…</i> in the
|
||||
user-list pop-up menus: <i>Ban user</i>, <i>Kick user</i>, <i>Mute user</i>,
|
||||
<i>Deafen user</i>, and their reciprocals (<i>Unmute user</i>, <i>Undeafen user</i>).</p>
|
||||
|
||||
<p>By moderating through this right-click menu, though, you can't attach a message—
|
||||
sometimes, for example, it's useful to give the victim a reason that you've kicked them
|
||||
in the shins. For that, you can moderate through <a href="#commands">commands</a> as well.</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h3 id="chat_input">Chat input</h3>
|
||||
|
||||
<img src="img/chat-input.png" />
|
||||
|
||||
<p>With the text-box, you can send messages and run commands. Type what you like, and hit
|
||||
<span class="key">ENTER</span> to send. If you're typing someone's username or nickname,
|
||||
hitting <span class="key">TAB</span> can auto-complete it.</p>
|
||||
<p>Messages don't necessarily have to be only one line long— hence why you can resize the
|
||||
text-box. <span class="key">ALT</span><span class="key">ENTER</span> starts a new line. If
|
||||
you get lost, <span class="key">Page↑</span> and <span class="key">Page↓</span> are your
|
||||
friends.</p>
|
||||
|
||||
<section>
|
||||
<h4 id="commands">Commands</h4>
|
||||
<p><i>Commands</i> let you perform some special action— they vary by protocol, but there are
|
||||
some standard ones you can expect to work:</p>
|
||||
<table>
|
||||
<tr><th>Command</th><th>Description</th></tr>
|
||||
<tr><td>/help</td><td>List all commands for the current protocol</td>
|
||||
<tr><td>/invite <i>USER</i></td><td>Invite a user to the current room</td>
|
||||
<tr><td>/kick <i>USER MESSAGE</i></td><td>Disconnect a user from the current room</td>
|
||||
<tr><td>/ban <i>USER MESSAGE</i></td><td>Disconnect a user and prevent them from re-joining</td>
|
||||
<tr><td>/unban <i>USER</i></td><td>Undo a user's ban</td>
|
||||
<tr><td>/deafen <i>USER</i></td><td>Prevent a user from receiving any messages</td>
|
||||
<tr><td>/undeafen <i>USER</i></td><td>Undo a user's deafening</td>
|
||||
<tr><td>/mute <i>USER</i></td><td>Prevent a user from sending messages</td>
|
||||
<tr><td>/unmute <i>USER</i></td><td>Undo a user's muting</td>
|
||||
</table>
|
||||
<p>As you might be able to tell, most of these are just aliases for
|
||||
<a href="#moderation">moderation</a> through the <a href="#user_list">user list</a>.</p>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h3 id="status">Status area</h3>
|
||||
|
||||
<img src="img/status-area.png" />
|
||||
|
||||
<p>In the status area, you can see your avatar (how cute!), change your nickname, and update
|
||||
your current status.</p>
|
||||
<p>Clicking on the nickname text-box (here it's “jaidedim”), you can then edit your nickname,
|
||||
hitting <span class="key">ENTER</span> to update. After hitting
|
||||
<span class="key">ENTER</span>, the text will change back to your previous nickname, pending
|
||||
the protocol or server— after which it will update to the new nickname.</p>
|
||||
<p>The status drop-down menu lets you change the status for the currently selected account
|
||||
(here it's “Available”).</p>
|
||||
<p>There is, next to the status menu, an account menu. By default “All” (the asterisk) is
|
||||
selected, meaning that any changes to status or nickname will apply to all accounts. If
|
||||
you'd like to change the nick or status of only a single account, you can select it from
|
||||
this menu.</p>
|
||||
</section>
|
||||
|
||||
|
||||
<section>
|
||||
<h3 id="menu_bar">Menu-bar</h3>
|
||||
|
||||
<img src="img/menu-bar.png" />
|
||||
|
||||
<p>In the <i>Program</i> menu, you'll find:
|
||||
<ul>
|
||||
<li>About…</li>
|
||||
<li><a href="#preferences">Preferences…</a></li>
|
||||
<li>Quit</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<p>In the <i>Accounts</i> menu, you'll find a list of your accounts for
|
||||
easy management. Through this menu, you can also select the <i>Accounts→Manage accounts…</i>
|
||||
item to see the account management window, which lets you add and remove accounts.</p>
|
||||
|
||||
<p>In the <i>Chat</i> menu, you'll find:
|
||||
<ul>
|
||||
<li>Join room…</li>
|
||||
<li><a href="#room_dir">Room directory…</a></li>
|
||||
<li>New room…</li>
|
||||
<li>New chat…</li>
|
||||
<li>Find…</li>
|
||||
</ul>
|
||||
<i>Chat→Find…</i> (<span class="key">ALT</span><span class="key">F</span>) will open a
|
||||
<b>TextSearch</b> window for searching the current room's logs (so long as logging
|
||||
<a href="#room_flags">is enabled</a>). The other items are related to
|
||||
<a href="#rooms">room creation/joining</a>.
|
||||
</p>
|
||||
|
||||
<p>In the <i>Roster</i> menu, you'll find:
|
||||
<ul>
|
||||
<li>Edit roster…</li>
|
||||
<li>Invite user…</li>
|
||||
</ul>
|
||||
|
||||
<p>In the <i>Window</i> menu, you'll find two items that make switching between rooms
|
||||
faster— <i>Window→Up</i> (<span class="key">ALT</span><span class="key">↑</span>) and
|
||||
<i>Window→Down</i> (<span class="key">ALT</span><span class="key">↓</span>).</p>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
|
||||
<section>
|
||||
<h2 id="preferences">Preferences window</h4>
|
||||
|
||||
<img src="img/pref-notifications.png" />
|
||||
|
||||
<p>Selecting <i>Program→Preferences</i> through the menu-bar (<span class="key">ALT</span>
|
||||
<span class="key">,</span>), you'll see the Preferences window. Most of the options should
|
||||
be self-explanatory, but there a couple that are noteworthy:<p>
|
||||
|
||||
<p>The <i>Notifications</i> tab lets you toggle whether or not you receive message-related
|
||||
notifications and whether or not you'll be notified on a connection/disconnection.</p>
|
||||
|
||||
<p>You can also attach specific sounds to notifications through Haiku's <b>Sounds</b>
|
||||
preferences, brought up through the <i>Edit sounds…</i> button. The beeps configurable
|
||||
through <b>Sounds</b> are <i>Chat-O-Matic mention</i> and <i>Chat-O-Matic message</i>.</p>
|
||||
</section>
|
||||
|
||||
|
||||
<section>
|
||||
<h2 id="roster">Roster/user windows</h2>
|
||||
|
||||
<img src="img/select-user.png" />
|
||||
|
||||
<p>Roster and user-selection windows (as in <i>Roster→Edit roster…</i>,
|
||||
<i>Roster→Invite user…</i> and <i>Chat→New chat…</i> from the
|
||||
<a href="#menu_bar">menu-bar</a>) display a list of your contacts,
|
||||
allowing you to select one.</p>
|
||||
|
||||
<p>Through the account drop-down menu in the
|
||||
bottom-left corner, you can filter the list, showing only contacts
|
||||
of a specific account. In this example, “jaidedim-xmpp“, an XMPP
|
||||
account, is selected.</p>
|
||||
|
||||
<p>By typing into the text-box at the top of the window, you can search
|
||||
through the shown contacts— here, all contacts matching “Ash” are
|
||||
shown. If you have an account selected, you can also use this text-box
|
||||
to manually type in a username for selection. In this window, since
|
||||
a specific account is selected, “Select user Ash…” is an item in the
|
||||
list.</p>
|
||||
</section>
|
||||
|
||||
|
||||
<section>
|
||||
<h2 id="rooms">Room creation/join windows</h2>
|
||||
|
||||
<img src="img/room-creation.png" />
|
||||
|
||||
<p>With <i>Chat→Join room…</i> and <i>Chat→New room…</i> in the
|
||||
<a href="#menu_bar">menu-bar</a> (<span class="key">ALT</span><span class="key">J</span> and
|
||||
<span class="key">ALT</span><span class="key">N</span>, respectively), you'll see a window
|
||||
like the one above. For each protocol, the options and text-boxes shown will differ— for
|
||||
<abbr title="Internet Relay Chat">IRC</abbr>, as in this image, the only option is the
|
||||
channel-name.</p>
|
||||
|
||||
<p>You can select the account to join/create from through the account drop-down menu in the
|
||||
bottom-left corner. Here, the account “oftc-irc” is selected, an
|
||||
<abbr title="Internet Relay Chat">IRC</abbr> account.</p>
|
||||
|
||||
<p><i>Chat→Create chat…</i> (<span class="key">ALT</span><span class="key">M</span>), in
|
||||
contrast, is used for creating one-on-one chats, and opens a
|
||||
<a href="#roster">user-selection window</a> instead.</p>
|
||||
</section>
|
||||
|
||||
|
||||
<section>
|
||||
<h2 id="room_dir">Room directory</h2>
|
||||
|
||||
<img src="img/room-directory.png" />
|
||||
|
||||
<p>The room directory (accessible though <i>Chat→Room directory…</i> in the
|
||||
<a href="#menu_bar">menu-bar</a>) lets you browse and join publically listed chatrooms— a
|
||||
feature used extensively for <abbr title="Internet Relay Chat">IRC</abbr>,
|
||||
<abbr title="Extensible Messaging and Presence Protocol">XMPP</abbr>, and some libpurple
|
||||
add-ons.</p>
|
||||
|
||||
<p>Like other dialogues in Chat-O-Matic, you can select a specific account to act on though
|
||||
the bottom-left account dropdown menu. In this image, “All” accounts is selected, so rooms
|
||||
available to all the user's accounts are shown.</p>
|
||||
</section>
|
||||
|
||||
</body>
|
||||
</html>
|
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 135 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 136 KiB |
After Width: | Height: | Size: 83 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 71 KiB |
After Width: | Height: | Size: 6.9 KiB |
After Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 33 KiB |
After Width: | Height: | Size: 202 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 144 KiB |
After Width: | Height: | Size: 144 KiB |
|
@ -0,0 +1,22 @@
|
|||
/* SPCSS theme by Susam Pal, under the MIT license
|
||||
* https://github.com/susam/spcss */
|
||||
body{color:#333;font-family:helvetica,arial,sans-serif;line-height:1.5;margin:0 auto;max-width:40em;padding:0 1em}h1,h2,h3,h4,h5,h6{margin:1.25em 0 .5em;line-height:1.2}a:link{color:#00e}a:visited{color:#518}a:focus,a:hover{color:#03f}a:active{color:#e00}h1 a:empty:before,h2 a:empty:before,h3 a:empty:before,h4 a:empty:before,h5 a:empty:before,h6 a:empty:before{content:"#"}h1 a:empty,h2 a:empty,h3 a:empty,h4 a:empty,h5 a:empty,h6 a:empty{visibility:hidden;padding-left:.25em}h1:hover a:empty,h2:hover a:empty,h3:hover a:empty,h4:hover a:empty,h5:hover a:empty,h6:hover a:empty{visibility:visible}img{max-width:100%}figure{margin:1em 0;text-align:center}figcaption{font-size:small}code,kbd,pre,samp{color:#009;font-family:monospace,monospace}pre kbd{color:#060}blockquote,pre{background:#eee;padding:.5em}pre{overflow:auto}blockquote{border-left:medium solid #ccc;margin:1em 0}blockquote :first-child{margin-top:0}blockquote :last-child{margin-bottom:0}table{border-collapse:collapse}td,th{border:thin solid #999;padding:.3em .4em;text-align:left}@media (prefers-color-scheme:dark){body{background:#111;color:#bbb}a:link{color:#9bf}a:visited{color:#caf}a:focus,a:hover{color:#9cf}a:active{color:#faa}code,kbd,pre,samp{color:#6cf}pre kbd{color:#9c6}blockquote,pre{background:#000}blockquote{border-color:#333}td,th{border-color:#666}}
|
||||
|
||||
/*
|
||||
* Copyright 2008-2017, Haiku. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
.key { /* Shortcut (separate with */
|
||||
-webkit-border-radius: 3px;
|
||||
-khtml-border-radius: 3px;
|
||||
-moz-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
border-color: #c7c7c7;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
padding: 0px 2px 0px 2px;
|
||||
background-color: #e8e8e8;
|
||||
font-family: serif;
|
||||
font-variant: small-caps;
|
||||
font-size: 0.8em;
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
include Make.pre
|
||||
|
||||
# Haiku Generic Makefile v2.6 ##
|
||||
|
||||
## Fill in this file to specify the project being created, and the referenced
|
||||
|
@ -140,4 +142,4 @@ DEVEL_DIRECTORY := \
|
|||
$(shell findpaths -r "makefile_engine" B_FIND_PATH_DEVELOP_DIRECTORY)
|
||||
include $(DEVEL_DIRECTORY)/etc/makefile-engine
|
||||
|
||||
include Makefile.common
|
||||
include Make.post
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
include Make.pre
|
||||
|
||||
## Haiku Generic Makefile v2.6 ##
|
||||
|
||||
## Fill in this file to specify the project being created, and the referenced
|
||||
|
@ -134,4 +136,4 @@ DEVEL_DIRECTORY := \
|
|||
$(shell findpaths -r "makefile_engine" B_FIND_PATH_DEVELOP_DIRECTORY)
|
||||
include $(DEVEL_DIRECTORY)/etc/makefile-engine
|
||||
|
||||
include Makefile.common
|
||||
include Make.post
|
||||
|
|
|
@ -17,6 +17,7 @@ public:
|
|||
void AddItem(KEY k, TYPE t);
|
||||
|
||||
TYPE ValueFor(KEY, bool* found = NULL) const;
|
||||
KEY KeyFor(TYPE, bool* found = NULL) const;
|
||||
|
||||
TYPE RemoveItemAt(int32 position);
|
||||
TYPE RemoveItemFor(KEY);
|
||||
|
@ -63,11 +64,25 @@ KeyMap<KEY, TYPE>::ValueFor(KEY k, bool* found) const
|
|||
}
|
||||
|
||||
if (i == fMap.end())
|
||||
return NULL;
|
||||
return 0;
|
||||
return i->second;
|
||||
}
|
||||
|
||||
|
||||
template<class KEY, class TYPE>
|
||||
inline KEY
|
||||
KeyMap<KEY, TYPE>::KeyFor(TYPE v, bool* found) const
|
||||
{
|
||||
*found = false;
|
||||
for (int32 i = 0; i < CountItems(); i++)
|
||||
if (ValueAt(i) == v) {
|
||||
*found = true;
|
||||
return KeyAt(i);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
template<class KEY, class TYPE>
|
||||
inline TYPE
|
||||
KeyMap<KEY, TYPE>::RemoveItemAt(int32 position)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
include Make.pre
|
||||
|
||||
## Haiku Generic Makefile v2.6 ##
|
||||
|
||||
## Fill in this file to specify the project being created, and the referenced
|
||||
|
@ -134,4 +136,4 @@ DEVEL_DIRECTORY := \
|
|||
$(shell findpaths -r "makefile_engine" B_FIND_PATH_DEVELOP_DIRECTORY)
|
||||
include $(DEVEL_DIRECTORY)/etc/makefile-engine
|
||||
|
||||
include Makefile.common
|
||||
include Make.post
|
||||
|
|
|
@ -1,108 +1,133 @@
|
|||
1 English application/x-vnd.cardie 1762272810
|
||||
Disable deskbar replicant PreferencesReplicant Disable deskbar replicant
|
||||
1 English application/x-vnd.chat-o-matic 244317784
|
||||
No accounts enabled, no joy. ConversationView ― Startup messages No accounts enabled, no joy.
|
||||
Description Room directory Description
|
||||
%user% is now offline! Server %user% is now offline!
|
||||
New mention Conversation ― Notifications New mention
|
||||
{0, plural,=1{One lonely user}=2{Two partners}other{# members}} ConversationInfoWindow {0, plural,=1{One lonely user}=2{Two partners}other{# members}}
|
||||
Enable contact status notifications PreferencesNotifications Enable contact status notifications
|
||||
Edit sounds… PreferencesNotifications Edit sounds…
|
||||
Auto-raise when a message is received PreferencesBehavior Auto-raise when a message is received
|
||||
On incoming… PreferencesBehavior On incoming…
|
||||
Account name: AccountDialog Account name:
|
||||
Connected Server Connected
|
||||
User information UserInfoWindow User information
|
||||
Account now online! Server Account now online!
|
||||
Del AccountsWindow Short for 'delete' Del
|
||||
%name% is offline! RosterView %name% is offline!
|
||||
Preferences… MainWindow Preferences…
|
||||
** You created the room.\n ConversationView ** You created the room.\n
|
||||
Room directory Room directory Room directory
|
||||
Adding contact RosterEditWindow Adding contact
|
||||
Deskbar replicant PreferencesReplicant Deskbar replicant
|
||||
Add account PreferencesAccounts Add account
|
||||
It looks like you don't have any accounts enabled. ConversationView ― Startup messages It looks like you don't have any accounts enabled.
|
||||
Start a chat RosterListView Start a chat
|
||||
Enable PreferencesAccounts Enable
|
||||
%app% is released under the GNU GPL License.\nSome parts of %app% are available under MIT license.\nBuilt: %buildDate% TheApp %app% is released under the GNU GPL License.\nSome parts of %app% are available under MIT license.\nBuilt: %buildDate%
|
||||
Log messages ConversationListView Log messages
|
||||
Edit… AccountsWindow Edit…
|
||||
%app% setup ConversationView ― Startup messages %app% setup
|
||||
Manage accounts… MainWindow Manage accounts…
|
||||
Create room MainWindow Create room
|
||||
** The subject is now: %subject% ConversationView ** The subject is now: %subject%
|
||||
New chat… ConversationListView New chat…
|
||||
Add AccountsWindow Add
|
||||
Chat view PreferencesChatWindow Chat view
|
||||
Hide field in Deskbar PreferencesReplicant Hide field in Deskbar
|
||||
Edit roster… MainWindow Edit roster…
|
||||
Room information ConversationInfoWindow Room information
|
||||
Ouch! TheApp Ouch!
|
||||
Notifications PreferencesNotifications Notifications
|
||||
Disconnected Server Disconnected
|
||||
Join a room MainWindow Join a room
|
||||
Room info… ConversationListView Room info…
|
||||
OK PreferencesWindow OK
|
||||
Enable protocol status notifications PreferencesBehavior Enable protocol status notifications
|
||||
Accounts ConversationView ― Startup messages Accounts
|
||||
Send a file… RosterListView Send a file…
|
||||
Are you sure you want to quit? MainWindow Are you sure you want to quit?
|
||||
Del PreferencesAccounts Short for 'delete' Del
|
||||
Manage accounts through the %menu% menu to get started. ConversationView ― Startup messages Manage accounts through the %menu% menu to get started.
|
||||
%name% is available! RosterView %name% is available!
|
||||
New message Conversation ― Notifications New message
|
||||
Some items are empty. Please make sure to fill out every item. TemplateWindow Some items are empty. Please make sure to fill out every item.
|
||||
Enable message notifications PreferencesBehavior Enable message notifications
|
||||
Program MainWindow Program
|
||||
Cancel AccountDialog Cancel
|
||||
Leave room ConversationListView Leave room
|
||||
Behavior PreferencesBehavior Behavior
|
||||
Replicant PreferencesReplicant Replicant
|
||||
Play sound event PreferencesBehavior Play sound event
|
||||
Find… MainWindow Find…
|
||||
Enable MainWindow Enable
|
||||
You've been summoned from %source%. Conversation ― Notifications You've been summoned from %source%.
|
||||
Notify on every message ConversationListView Notify on every message
|
||||
Disabled Server Disabled
|
||||
That isn't a valid command. Try /help for a list. Conversation ― Command info That isn't a valid command. Try /help for a list.
|
||||
** You joined the room.\n ConversationView ** You joined the room.\n
|
||||
-- That command doesn't exist. Try '/help' for a list.\n Server -- That command doesn't exist. Try '/help' for a list.\n
|
||||
OK TemplateWindow OK
|
||||
Reject InviteDialogue Reject
|
||||
\nWritten by:\n About window \nWritten by:\n
|
||||
Disable PreferencesAccounts Disable
|
||||
All AccountsMenu All
|
||||
Offline Utils ― Status names Offline
|
||||
%user% has been disabled! Server %user% has been disabled!
|
||||
You've been invited to %room%. Server You've been invited to %room%.
|
||||
Invite user… UserListView Invite user…
|
||||
Add PreferencesAccounts Add
|
||||
Sound when mentioned PreferencesNotifications Sound when mentioned
|
||||
Preferences PreferencesWindow Preferences
|
||||
Deskbar notifications PreferencesBehavior Deskbar notifications
|
||||
Connecting Server Connecting
|
||||
Name Room directory Name
|
||||
General PreferencesBehavior General
|
||||
%user% is readying… Server %user% is readying…
|
||||
Enable protocol status notifications PreferencesNotifications Enable protocol status notifications
|
||||
Presence RosterView Presence
|
||||
Cancel TemplateWindow Cancel
|
||||
Hide offline contacts PreferencesBehavior Hide offline contacts
|
||||
%user% has joined the room.\n ConversationView %user% has joined the room.\n
|
||||
Busy Utils ― Status names Busy
|
||||
Roster RosterEditWindow Roster
|
||||
Auto-join room ConversationListView Auto-join room
|
||||
** %old% has changed their nick to %new%. Conversation ― Command info ** %old% has changed their nick to %new%.
|
||||
Don't ask confirmation at Quit PreferencesBehavior Don't ask confirmation at Quit
|
||||
Closing MainWindow Closing
|
||||
Sound on message received PreferencesNotifications Sound on message received
|
||||
Available Utils ― Status names Available
|
||||
Up MainWindow Up
|
||||
Invite user… MainWindow Invite user…
|
||||
Room directory… MainWindow Room directory…
|
||||
Custom Status Utils ― Status names Custom Status
|
||||
Can't find smileys settings in:\n\n%path% TheApp Can't find smileys settings in:\n\n%path%
|
||||
Connection failed Server Connection failed
|
||||
Mark unread window chat PreferencesBehavior Mark unread window chat
|
||||
%user% has left the room.\n ConversationView %user% has left the room.\n
|
||||
Join Room directory Join
|
||||
Join room… MainWindow Join room…
|
||||
Edit account AccountsWindow Edit account
|
||||
Preferences ReplicantStatusView Preferences
|
||||
Quit MainWindow Quit
|
||||
Chat MainWindow Chat
|
||||
No MainWindow No
|
||||
Chat settings PreferencesChatWindow Chat settings
|
||||
Cancel InviteDialogue Cancel
|
||||
Mark unread the Deskbar Replicant PreferencesBehavior Mark unread the Deskbar Replicant
|
||||
Sounds PreferencesNotifications Sounds
|
||||
Add account AccountsWindow Add account
|
||||
OK Server OK
|
||||
Enable AccountsWindow Enable
|
||||
Exit ReplicantStatusView Exit
|
||||
Disable AccountsWindow Disable
|
||||
User info… RosterListView User info…
|
||||
Move window to current workspace PreferencesBehavior Move window to current workspace
|
||||
Away Utils ― Status names Away
|
||||
OK AccountDialog OK
|
||||
Notify on direct-messages ConversationListView Notify on direct-messages
|
||||
Accounts MainWindow Accounts
|
||||
%user% has been banned.\n ConversationView %user% has been banned.\n
|
||||
Editing contact RosterEditWindow Editing contact
|
||||
%user% isn't a member of this room. ChatCommand %user% isn't a member of this room.
|
||||
Edit account PreferencesAccounts Edit account
|
||||
Account now offline and disconnected. Server Account now offline and disconnected.
|
||||
Down MainWindow Down
|
||||
** Commands: Server ** Commands:
|
||||
Cardie System name Cardie
|
||||
I'm rearing to go! Conversation ― Command info I'm rearing to go!
|
||||
About… About window About…
|
||||
Ignore emoticons PreferencesChatWindow Ignore emoticons
|
||||
Enable message notifications PreferencesNotifications Enable message notifications
|
||||
Invitation received Server Invitation received
|
||||
Enable contact status notifications PreferencesBehavior Enable contact status notifications
|
||||
Auto-raise when user is typing PreferencesBehavior Auto-raise when user is typing
|
||||
Ignore emoticons PreferencesChatWindow Ignore emoticons
|
||||
Error Server Error
|
||||
Modify account… MainWindow Modify account…
|
||||
Copyright © About window Copyright ©
|
||||
Roster MainWindow Roster
|
||||
Accept InviteDialogue Accept
|
||||
%user% was kicked (%body%).\n ConversationView %user% was kicked (%body%).\n
|
||||
An error is occurred renaming the account to %name%! AccountDialog An error is occurred renaming the account to %name%!
|
||||
%user% has invited you to %room%. Server %user% has invited you to %room%.
|
||||
Permanent deskbar replicant PreferencesReplicant Permanent deskbar replicant
|
||||
Default User role Default
|
||||
%user% has been banned (%body%).\n ConversationView %user% has been banned (%body%).\n
|
||||
Invite contact to chat… MainWindow Invite contact to chat…
|
||||
|
@ -110,14 +135,22 @@ Invite contact to chat… MainWindow Invite contact to chat…
|
|||
Window MainWindow Window
|
||||
Invisible Utils ― Status names Invisible
|
||||
{0, plural,=1{You've got a new message from %source%.}other{You've got # new messages from %source%.}} Conversation ― Notifications {0, plural,=1{You've got a new message from %source%.}other{You've got # new messages from %source%.}}
|
||||
Afterward, you can join a room or start a chat through the %menu% menu. :-) ConversationView ― Startup messages Afterward, you can join a room or start a chat through the %menu% menu. :-)
|
||||
%user% has joined the room (%body%).\n ConversationView %user% has joined the room (%body%).\n
|
||||
%app% is released under the MIT License.\nAdd-on and library licenses may vary.\nBuilt: %buildDate% TheApp %app% is released under the MIT License.\nAdd-on and library licenses may vary.\nBuilt: %buildDate%
|
||||
Chat-O-Matic System name Chat-O-Matic
|
||||
Yes MainWindow Yes
|
||||
An error has occured saving the settings.\nCheck if your disk has enough space. AccountDialog An error has occured saving the settings.\nCheck if your disk has enough space.
|
||||
%user% has been temporarily disabled. Server %user% has been temporarily disabled.
|
||||
Disable MainWindow Disable
|
||||
Close About window Close
|
||||
No protocols found!\nPlease make sure %app% was installed correctly. TheApp No protocols found!\nPlease make sure %app% was installed correctly.
|
||||
Accounts AccountsWindow Accounts
|
||||
%user% has left the room (%body%).\n ConversationView %user% has left the room (%body%).\n
|
||||
New chat… MainWindow New chat…
|
||||
New room… MainWindow New room…
|
||||
About… MainWindow About…
|
||||
Edit… PreferencesAccounts Edit…
|
||||
Master Foo ConversationView ― Startup messages Master Foo
|
||||
Chat ConversationView ― Startup messages Chat
|
||||
%user% was kicked.\n ConversationView %user% was kicked.\n
|
||||
You aren't contacts with and have no chats in common with %user%. Shame. ChatCommand You aren't contacts with and have no chats in common with %user%. Shame.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
1 English application/x-vnd.cardie.purple 2993124882
|
||||
1 English application/x-vnd.chat-o-matic.purple 3277859582
|
||||
Connection error PurpleApp ― Connection errors Connection error
|
||||
** You can't undo what was once done… at least with this protocol.\n PurpleApp ― Room moderation ** You can't undo what was once done… at least with this protocol.\n
|
||||
** Command isn't useful in this chat %err%\n PurpleApp ― Command errors ** Command isn't useful in this chat %err%\n
|
||||
|
@ -6,8 +6,8 @@ Self-signed certificate PurpleApp ― Connection errors Self-signed certificate
|
|||
Username: PurpleApp ― Account template Username:
|
||||
No SSL certificate provided PurpleApp ― Connection errors No SSL certificate provided
|
||||
SSL unsupported PurpleApp ― Connection errors SSL unsupported
|
||||
** Command error %err%\n PurpleApp ― Command errors ** Command error %err%\n
|
||||
Authentication failed PurpleApp ― Connection errors Authentication failed
|
||||
** Command error %err%\n PurpleApp ― Command errors ** Command error %err%\n
|
||||
You can't friend someone without a nick. PurpleProtocol ― Roster template You can't friend someone without a nick.
|
||||
** Command failed %err%\n PurpleApp ― Command errors ** Command failed %err%\n
|
||||
Certificate error PurpleApp ― Connection errors Certificate error
|
||||
|
@ -20,10 +20,12 @@ Certifcate and fingerprint conflict PurpleApp ― Connection errors Certifcate
|
|||
Password: PurpleApp ― Account template Password:
|
||||
Invalid username PurpleApp ― Connection errors Invalid username
|
||||
Username in use PurpleApp ― Connection errors Username in use
|
||||
User changed name to %nick% PurpleApp ― Room template User changed name to %nick%
|
||||
Encryption error PurpleApp ― Connection errors Encryption error
|
||||
A username needs to be specified! PurpleApp ― Account template A username needs to be specified!
|
||||
Settings invalid PurpleApp ― Connection errors Settings invalid
|
||||
Moderator PurpleApp ― User roles Moderator
|
||||
OK PurpleApp ― Room template OK
|
||||
Alias: PurpleProtocol ― Roster template Alias:
|
||||
Untrusted SSL certificate PurpleApp ― Connection errors Untrusted SSL certificate
|
||||
Operator PurpleApp ― User roles Operator
|
||||
|
@ -33,10 +35,12 @@ Founder PurpleApp ― User roles Founder
|
|||
Certificate and hostname conflict PurpleApp ― Connection errors Certificate and hostname conflict
|
||||
** Invalid arguments to command %err%\n PurpleApp ― Command errors ** Invalid arguments to command %err%\n
|
||||
** Command not found %err%\n PurpleApp ― Command errors ** Command not found %err%\n
|
||||
Couldn't set your nick:\n%error% PurpleApp ― Room template Couldn't set your nick:\n%error%
|
||||
Expired SSL certificate PurpleApp ― Connection errors Expired SSL certificate
|
||||
** Banning won't work with this protocol. Try being mean instead.\n PurpleApp ― Room moderation ** Banning won't work with this protocol. Try being mean instead.\n
|
||||
Room ID PurpleApp ― Room template Room ID
|
||||
** This protocol is particularly self-concious, and prefers that this person not see its chats.\n PurpleApp ― Room moderation ** This protocol is particularly self-concious, and prefers that this person not see its chats.\n
|
||||
Failed to set nickname PurpleApp ― Room template Failed to set nickname
|
||||
Authentication impossible PurpleApp ― Connection errors Authentication impossible
|
||||
Username: PurpleProtocol ― Roster template Username:
|
||||
** This protocol doesn't support deafening, but spamming the chat should be a good substitute. :^)\n PurpleApp ― Room moderation ** This protocol doesn't support deafening, but spamming the chat should be a good substitute. :^)\n
|
||||
|
|