Usual SVN tree (branches, tags, trunk).
This commit is contained in:
commit
0bf4b59922
|
@ -0,0 +1,12 @@
|
|||
SubDir TOP ;
|
||||
|
||||
# Include all the components
|
||||
SubInclude TOP libs ;
|
||||
SubInclude TOP application ;
|
||||
SubInclude TOP protocols ;
|
||||
SubInclude TOP smileys ;
|
||||
|
||||
Distro distro ;
|
||||
FullDistro fulldistro ;
|
||||
|
||||
UninstallTarget $(APPS_DIRECTORY)/caya ;
|
|
@ -0,0 +1,70 @@
|
|||
# The directories used by the build.
|
||||
BUILD_DIR = [ FDirName $(TOP) build ] ;
|
||||
JAM_DIR = [ FDirName $(BUILD_DIR) jam ] ;
|
||||
SCRIPTS_DIR = [ FDirName $(JAM_DIR) scripts ] ;
|
||||
GENERATED_DIR = [ FDirName $(TOP) generated ] ;
|
||||
DISTRO_DIR = [ FDirName $(TOP) generated distro ] ;
|
||||
FULL_DISTRO_DIR = [ FDirName $(TOP) generated fulldistro ] ;
|
||||
PACKAGE_DIR = [ FDirName $(GENERATED_DIR) packages ] ;
|
||||
PACKAGE_OBJECT_DIR = [ FDirName $(PACKAGE_DIR) objects ] ;
|
||||
|
||||
##-------------------------------------------------------------------
|
||||
## Defines
|
||||
##-------------------------------------------------------------------
|
||||
VERSION = 10 ;
|
||||
DEFINES += VERSION=\"\\\"$(VERSION)\\\"\" ;
|
||||
DEFINES += BUILD_DATE=\"\\\"$(JAMDATE)\\\"\" ;
|
||||
CHGRP = ;
|
||||
CHOWN = ;
|
||||
|
||||
# Include BuildConfig generated by configure
|
||||
{
|
||||
local buildConfig = [ Glob $(GENERATED_DIR) : BuildConfig ] ;
|
||||
if $(buildConfig) {
|
||||
LOCATE on BuildConfig = $(GENERATED_DIR) ;
|
||||
include BuildConfig ;
|
||||
} else {
|
||||
Exit "Run ./configure first!" ;
|
||||
}
|
||||
}
|
||||
|
||||
# Include UserBuildConfig
|
||||
{
|
||||
local userBuildConfig = [ Glob $(JAM_DIR) : UserBuildConfig ] ;
|
||||
if $(userBuildConfig) {
|
||||
LOCATE on UserBuildConfig = $(JAM_DIR) ;
|
||||
include UserBuildConfig ;
|
||||
}
|
||||
}
|
||||
|
||||
# Cache files for header scanning and jamfile caching.
|
||||
HCACHEFILE = header_cache ;
|
||||
JCACHEFILE = jamfile_cache ;
|
||||
LOCATE on $(HCACHEFILE) $(JCACHEFILE) = $(GENERATED_DIR) ;
|
||||
|
||||
# Perform configuration checks
|
||||
include [ FDirName $(JAM_DIR) CheckRules ] ;
|
||||
CheckGccPlatform ;
|
||||
CheckOpenSSL ;
|
||||
if ! $(HAVE_OPENSSL) {
|
||||
# Echo "** MSN, GoogleTalk and OSCAR protocols are disabled for lack of OpenSSL" ;
|
||||
}
|
||||
CheckLibYahoo2 ;
|
||||
if ! $(HAVE_LIBYAHOO2) {
|
||||
# Echo "** Yahoo protocol is disabled for lack of libyahoo2" ;
|
||||
}
|
||||
CheckInfoPopper ;
|
||||
if ! $(HAVE_INFOPOPPER) {
|
||||
# Echo "** im_infopopper client is disabled for lack of InfoPopper" ;
|
||||
}
|
||||
|
||||
# Include jam scripts
|
||||
include [ FDirName $(JAM_DIR) HelperRules ] ;
|
||||
include [ FDirName $(JAM_DIR) ConfigRules ] ;
|
||||
include [ FDirName $(JAM_DIR) OverriddenJamRules ] ;
|
||||
include [ FDirName $(JAM_DIR) MainBuildRules ] ;
|
||||
include [ FDirName $(JAM_DIR) FileRules ] ;
|
||||
include [ FDirName $(JAM_DIR) InstallRules ] ;
|
||||
include [ FDirName $(JAM_DIR) PackageRules ] ;
|
||||
include [ FDirName $(JAM_DIR) DistroRules ] ;
|
||||
include [ FDirName $(JAM_DIR) BuildSettings ] ;
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright 2009, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Andrea Anzani, andrea.anzani@gmail.com
|
||||
*/
|
||||
|
||||
#include "Account.h"
|
||||
|
||||
|
||||
Account::Account(BHandler* msgTarget)
|
||||
{
|
||||
BMessenger msgr(msgTarget);
|
||||
fMessenger = msgr;
|
||||
}
|
||||
|
||||
|
||||
Account::~Account()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Account::SendMessage(BMessage* message)
|
||||
{
|
||||
// This is just an example of what can be done ;)
|
||||
message->AddPointer("account", (void*)this);
|
||||
return fMessenger.SendMessage(message);
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright 2009, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _ACCOUNT_H
|
||||
#define _ACCOUNT_H
|
||||
|
||||
#include <Handler.h>
|
||||
#include <Messenger.h>
|
||||
|
||||
#include "CayaProtocol.h"
|
||||
|
||||
class Account : public CayaProtocolMessengerInterface {
|
||||
public:
|
||||
Account(BHandler* msgTarget);
|
||||
virtual ~Account();
|
||||
|
||||
virtual status_t SendMessage(BMessage* message);
|
||||
|
||||
private:
|
||||
BMessenger fMessenger;
|
||||
};
|
||||
|
||||
#endif // _ACCOUNT_H
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright 2009, Pier Luigi Fiorini. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
|
||||
*/
|
||||
|
||||
#include "AccountManager.h"
|
||||
#include "NotifyMessage.h"
|
||||
#include "Server.h"
|
||||
#include "TheApp.h"
|
||||
|
||||
static AccountManager* fInstance = NULL;
|
||||
|
||||
|
||||
AccountManager::AccountManager()
|
||||
: fStatus(CAYA_OFFLINE)
|
||||
{
|
||||
TheApp* theApp = reinterpret_cast<TheApp*>(be_app);
|
||||
RegisterObserver(theApp->GetMainWindow());
|
||||
}
|
||||
|
||||
|
||||
AccountManager::~AccountManager()
|
||||
{
|
||||
TheApp* theApp = reinterpret_cast<TheApp*>(be_app);
|
||||
UnregisterObserver(theApp->GetMainWindow());
|
||||
}
|
||||
|
||||
|
||||
AccountManager*
|
||||
AccountManager::Get()
|
||||
{
|
||||
if (fInstance == NULL)
|
||||
fInstance = new AccountManager();
|
||||
return fInstance;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AccountManager::SetNickname(BString nick)
|
||||
{
|
||||
// Create message
|
||||
BMessage* msg = new BMessage(IM_MESSAGE);
|
||||
msg->AddInt32("im_what", IM_SET_NICKNAME);
|
||||
msg->AddString("nick", nick);
|
||||
|
||||
// Send message
|
||||
TheApp* theApp = reinterpret_cast<TheApp*>(be_app);
|
||||
MainWindow* win = theApp->GetMainWindow();
|
||||
win->GetServer()->SendProtocolMessage(msg);
|
||||
}
|
||||
|
||||
|
||||
CayaStatus
|
||||
AccountManager::Status() const
|
||||
{
|
||||
return fStatus;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AccountManager::SetStatus(CayaStatus status, const char* str)
|
||||
{
|
||||
if (fStatus != status) {
|
||||
// Create status change message
|
||||
BMessage* msg = new BMessage(IM_MESSAGE);
|
||||
msg->AddInt32("im_what", IM_SET_STATUS);
|
||||
msg->AddInt32("status", (int32)status);
|
||||
if (str != NULL)
|
||||
msg->AddString("message", str);
|
||||
|
||||
// Send message
|
||||
TheApp* theApp = reinterpret_cast<TheApp*>(be_app);
|
||||
MainWindow* win = theApp->GetMainWindow();
|
||||
win->GetServer()->SendProtocolMessage(msg);
|
||||
|
||||
// Notify status change
|
||||
fStatus = status;
|
||||
NotifyInteger(INT_ACCOUNT_STATUS, (int32)fStatus);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright 2009, Pier Luigi Fiorini. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _ACCOUNT_MANAGER_H
|
||||
#define _ACCOUNT_MANAGER_H
|
||||
|
||||
#include "CayaConstants.h"
|
||||
#include "Notifier.h"
|
||||
|
||||
class AccountManager : public Notifier {
|
||||
public:
|
||||
static AccountManager* Get();
|
||||
|
||||
void SetNickname(BString nick);
|
||||
|
||||
CayaStatus Status() const;
|
||||
void SetStatus(CayaStatus status, const char* str = NULL);
|
||||
|
||||
private:
|
||||
AccountManager();
|
||||
~AccountManager();
|
||||
|
||||
CayaStatus fStatus;
|
||||
//BObjectList<Account*> fAccounts;
|
||||
};
|
||||
|
||||
#endif // _ACCOUNT_MANAGER_H
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* Copyright 2009, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _CAYA_H
|
||||
#define _CAYA_H
|
||||
|
||||
#define CAYA_SIGNATURE "application/x-vnd.xeD.Caya"
|
||||
|
||||
#endif // _CAYA_H
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* Copyright 2009, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _CAYA_CONSTANTS_H
|
||||
#define _CAYA_CONSTANTS_H
|
||||
|
||||
#include <GraphicsDefs.h>
|
||||
|
||||
/*
|
||||
* Color constants.
|
||||
*/
|
||||
const rgb_color CAYA_ORANGE_COLOR = {255, 186, 0, 255};
|
||||
const rgb_color CAYA_GREEN_COLOR = {43, 134, 43, 255};
|
||||
const rgb_color CAYA_RED_COLOR = {175, 1, 1, 255};
|
||||
const rgb_color CAYA_WHITE_COLOR = {255, 255, 255, 255};
|
||||
const rgb_color CAYA_BLACK_COLOR = {0, 0, 0, 255};
|
||||
const rgb_color CAYA_SELSTART_COLOR = {254, 150, 57};
|
||||
const rgb_color CAYA_SELEND_COLOR = {230, 113, 9};
|
||||
|
||||
/**
|
||||
* What-codes for messages.
|
||||
*/
|
||||
enum message_what_codes {
|
||||
// Used for all error messages
|
||||
IM_ERROR = 'IMer',
|
||||
|
||||
// Returned after a request has succeded
|
||||
IM_ACTION_PERFORMED = 'IMok',
|
||||
|
||||
// All client <> protocol communication uses the MESSAGE what-code.
|
||||
IM_MESSAGE = 'IMme',
|
||||
|
||||
IM_SERVER_BASED_CONTACT_LIST = 'IMsl'
|
||||
};
|
||||
|
||||
/**
|
||||
* Valid codes for im_what field.
|
||||
*/
|
||||
enum im_what_code {
|
||||
// Request a server-side contact list from protocol
|
||||
IM_GET_CONTACT_LIST = 1,
|
||||
|
||||
// Send a message to a contact
|
||||
IM_SEND_MESSAGE = 2,
|
||||
|
||||
// Message has been sent to contact
|
||||
IM_MESSAGE_SENT = 3,
|
||||
|
||||
// Message received from contact
|
||||
IM_MESSAGE_RECEIVED = 4,
|
||||
|
||||
// Contact's status has changes
|
||||
IM_STATUS_CHANGED = 5,
|
||||
|
||||
// Server-side contact list received
|
||||
IM_CONTACT_LIST = 6,
|
||||
|
||||
// Change own nickname
|
||||
IM_SET_NICKNAME = 7,
|
||||
|
||||
// Change own status
|
||||
IM_SET_STATUS = 8,
|
||||
|
||||
// Retreive information on contact
|
||||
IM_GET_CONTACT_INFO = 9,
|
||||
|
||||
// Received information on contact
|
||||
IM_CONTACT_INFO = 10,
|
||||
|
||||
// Start listening to changes in these contact's statuses
|
||||
IM_REGISTER_CONTACTS = 11,
|
||||
|
||||
// Contact started typing
|
||||
IM_CONTACT_STARTED_TYPING = 12,
|
||||
|
||||
// Contact stopped typing
|
||||
IM_CONTACT_STOPPED_TYPING = 13,
|
||||
|
||||
// User started typing
|
||||
IM_USER_STARTED_TYPING = 14,
|
||||
|
||||
// User stopped typing
|
||||
IM_USER_STOPPED_TYPING = 15,
|
||||
|
||||
// Own status was chagned
|
||||
IM_STATUS_SET = 16,
|
||||
|
||||
// Authorization request received
|
||||
IM_AUTH_REQUEST = 17,
|
||||
|
||||
// Send authorization
|
||||
IM_SEND_AUTH_ACK = 18,
|
||||
|
||||
// Contact has been authorized
|
||||
IM_CONTACT_AUTHORIZED = 19,
|
||||
|
||||
// Request authorization from contact
|
||||
IM_REQUEST_AUTH = 20,
|
||||
|
||||
// Stop listening to status changes from these contacts
|
||||
IM_UNREGISTER_CONTACTS = 21,
|
||||
|
||||
// Progress message received, could be login sequence, file transfer etc...
|
||||
IM_PROGRESS = 22,
|
||||
|
||||
// Away message
|
||||
GET_AWAY_MESSAGE = 23,
|
||||
AWAY_MESSAGE = 24,
|
||||
|
||||
// Protocols send this when they get a new avatar icon
|
||||
IM_SET_AVATAR = 25,
|
||||
|
||||
// Client get this when an avatar icon is changed
|
||||
IM_AVATAR_CHANGED = 26,
|
||||
|
||||
// Adding and removing contact from the server side list
|
||||
IM_SERVER_LIST_ADD_CONTACT = 27,
|
||||
IM_SERVER_LIST_REMOVED_CONTACT = 28,
|
||||
|
||||
// Get account contact information
|
||||
IM_OWN_CONTACT_INFO = 29,
|
||||
|
||||
// These are forwarded to or from protocols
|
||||
IM_SPECIAL_TO_PROTOCOL = 1000,
|
||||
IM_SPECIAL_FROM_PROTOCOL = 1001
|
||||
};
|
||||
|
||||
enum CayaStatus {
|
||||
CAYA_ONLINE = 1,
|
||||
CAYA_AWAY = 2,
|
||||
CAYA_EXTENDED_AWAY = 3,
|
||||
CAYA_DO_NOT_DISTURB = 4,
|
||||
CAYA_OFFLINE = 5,
|
||||
CAYA_STATUSES = 6
|
||||
};
|
||||
|
||||
#endif // _CAYA_CONSTANTS_H
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright 2009, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef CayaProtocol_h
|
||||
#define CayaProtocol_h
|
||||
|
||||
#include <Messenger.h>
|
||||
|
||||
class CayaProtocolMessengerInterface {
|
||||
|
||||
public:
|
||||
virtual status_t SendMessage(BMessage *message) = 0;
|
||||
|
||||
};
|
||||
|
||||
class CayaProtocol
|
||||
{
|
||||
public:
|
||||
|
||||
// messenger
|
||||
virtual status_t Init( CayaProtocolMessengerInterface * ) = 0;
|
||||
|
||||
// called before unloading from memory
|
||||
virtual status_t Shutdown() = 0;
|
||||
|
||||
// process message
|
||||
virtual status_t Process( BMessage * ) = 0;
|
||||
|
||||
// Get name of protocol
|
||||
virtual const char * GetSignature() = 0;
|
||||
virtual const char * GetFriendlySignature() = 0;
|
||||
|
||||
// settings changed
|
||||
virtual status_t UpdateSettings( BMessage & ) = 0;
|
||||
|
||||
// preferred encoding of messages
|
||||
virtual uint32 GetEncoding() = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright 2009-2010, Pier Luigi Fiorini. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _CAYA_RESOURCES_H
|
||||
#define _CAYA_RESOURCES_H
|
||||
|
||||
enum {
|
||||
kOnlineIcon = 10,
|
||||
kAwayIcon = 11,
|
||||
kBusyIcon = 12,
|
||||
kOfflineIcon = 13,
|
||||
|
||||
kSearchIcon = 100,
|
||||
|
||||
kProtocolSettingsTemplate = 1000
|
||||
};
|
||||
|
||||
#endif // _CAYA_RESOURCES_H
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright 2009-2010, Pier Luigi Fiorini. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
|
||||
*/
|
||||
|
||||
#include <memory.h>
|
||||
|
||||
#include <Bitmap.h>
|
||||
|
||||
#include "private/IconUtils.h"
|
||||
|
||||
#include "CayaUtils.h"
|
||||
|
||||
|
||||
const char*
|
||||
CayaStatusToString(CayaStatus status)
|
||||
{
|
||||
switch (status) {
|
||||
case CAYA_ONLINE:
|
||||
return "Available";
|
||||
case CAYA_OFFLINE:
|
||||
return "Offline";
|
||||
case CAYA_AWAY:
|
||||
return "Away";
|
||||
case CAYA_EXTENDED_AWAY:
|
||||
return "Extended Away";
|
||||
case CAYA_DO_NOT_DISTURB:
|
||||
return "Busy";
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BBitmap*
|
||||
RescaleBitmap(const BBitmap* src, int32 width, int32 height)
|
||||
{
|
||||
width--; height--;
|
||||
|
||||
if (!src || !src->IsValid())
|
||||
return NULL;
|
||||
|
||||
BRect srcSize = src->Bounds();
|
||||
|
||||
if (height < 0) {
|
||||
float srcProp = srcSize.Height() / srcSize.Width();
|
||||
height = (int32)(width * srcProp);
|
||||
}
|
||||
|
||||
BBitmap* res = new BBitmap(BRect(0, 0, width, height), src->ColorSpace());
|
||||
|
||||
float dx = (srcSize.Width() + 1) / (width + 1);
|
||||
float dy = (srcSize.Height() + 1) / (height + 1);
|
||||
uint8 bpp = (uint8)(src->BytesPerRow() / srcSize.Width());
|
||||
|
||||
int srcYOff = src->BytesPerRow();
|
||||
int dstYOff = res->BytesPerRow();
|
||||
|
||||
void* dstData = res->Bits();
|
||||
void* srcData = src->Bits();
|
||||
|
||||
for (int32 y = 0; y <= height; y++) {
|
||||
void* dstRow = (void *)((uint32)dstData + (uint32)(y * dstYOff));
|
||||
void* srcRow = (void *)((uint32)srcData + ((uint32)(y * dy) * srcYOff));
|
||||
|
||||
for (int32 x = 0; x <= width; x++)
|
||||
memcpy((void*)((uint32)dstRow + (x * bpp)), (void*)((uint32)srcRow +
|
||||
((uint32)(x * dx) * bpp)), bpp);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
extern "C" {
|
||||
|
||||
status_t
|
||||
our_image(image_info& image)
|
||||
{
|
||||
team_id team = B_CURRENT_TEAM;
|
||||
|
||||
int32 cookie = 0;
|
||||
while (get_next_image_info(team, &cookie, &image) == B_OK) {
|
||||
if ((char *)our_image >= (char *)image.text
|
||||
&& (char *)our_image <= (char *)image.text + image.text_size)
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright 2009-2010, Pier Luigi Fiorini. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _CAYA_UTILS_H
|
||||
#define _CAYA_UTILS_H
|
||||
|
||||
#include <image.h>
|
||||
#include <Mime.h>
|
||||
|
||||
#include "CayaConstants.h"
|
||||
|
||||
class BBitmap;
|
||||
class BResources;
|
||||
|
||||
const char* CayaStatusToString(CayaStatus status);
|
||||
|
||||
BBitmap* RescaleBitmap(const BBitmap* src, int32 width, int32 height);
|
||||
|
||||
extern "C" status_t our_image(image_info& image);
|
||||
|
||||
#endif // _CAYA_UTILS_H
|
|
@ -0,0 +1,248 @@
|
|||
/*
|
||||
* Copyright 2009, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Andrea Anzani, andrea.anzani@gmail.com
|
||||
*/
|
||||
|
||||
#include <Alert.h>
|
||||
#include <Application.h>
|
||||
#include <Box.h>
|
||||
#include <Button.h>
|
||||
#include <CheckBox.h>
|
||||
#include <GridLayout.h>
|
||||
#include <GridLayoutBuilder.h>
|
||||
#include <GroupLayout.h>
|
||||
#include <GroupLayoutBuilder.h>
|
||||
#include <Layout.h>
|
||||
#include <ListView.h>
|
||||
#include <Message.h>
|
||||
#include <SpaceLayoutItem.h>
|
||||
#include <ScrollView.h>
|
||||
#include <String.h>
|
||||
|
||||
#include "ChatWindow.h"
|
||||
#include "ContactLinker.h"
|
||||
#include "EditingFilter.h"
|
||||
#include "CayaConstants.h"
|
||||
#include "CayaRenderView.h"
|
||||
#include "NotifyMessage.h"
|
||||
|
||||
const int32 kCloseWindow = 'clwn';
|
||||
const int32 kChat = 'chat';
|
||||
|
||||
|
||||
ChatWindow::ChatWindow(ContactLinker* cl)
|
||||
: BWindow(BRect(200, 200, 500, 500),
|
||||
cl->GetName().String(), B_DOCUMENT_WINDOW, 0),
|
||||
fContactLinker(cl)
|
||||
{
|
||||
fReceiveView = new CayaRenderView("fReceiveView");
|
||||
fReceiveView->SetOtherNick(cl->GetName());
|
||||
BScrollView* scrollViewReceive = new BScrollView("scrollviewR", fReceiveView,
|
||||
B_WILL_DRAW, false, true);
|
||||
|
||||
fSendView = new BTextView("fReceiveView");
|
||||
BScrollView* scrollViewSend = new BScrollView("scrollviewS", fSendView,
|
||||
B_WILL_DRAW, false, true);
|
||||
fSendView->SetWordWrap(true);
|
||||
AddCommonFilter(new EditingFilter(fSendView));
|
||||
fSendView->MakeFocus(true);
|
||||
|
||||
SetLayout(new BGroupLayout(B_HORIZONTAL));
|
||||
|
||||
AddChild(BGroupLayoutBuilder(B_VERTICAL, 10)
|
||||
.Add(scrollViewReceive, 2)
|
||||
.Add(scrollViewSend)
|
||||
.SetInsets(5, 5, 5, 5)
|
||||
);
|
||||
|
||||
MoveTo(BAlert::AlertPosition(Bounds().Width(), Bounds().Height() / 2));
|
||||
|
||||
fSendView->MakeFocus(true);
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ChatWindow::QuitRequested()
|
||||
{
|
||||
BMessage msg(kCloseWindow);
|
||||
msg.AddString("id", fContactLinker->GetId());
|
||||
fContactLinker->GetMessenger().SendMessage(&msg);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ChatWindow::MessageReceived(BMessage* message)
|
||||
{
|
||||
switch(message->what) {
|
||||
case kChat:
|
||||
{
|
||||
BString message = fSendView->Text();
|
||||
if (message == "")
|
||||
return;
|
||||
|
||||
fReceiveView->AppendOwnMessage(message.String());
|
||||
|
||||
BMessage msg(IM_MESSAGE);
|
||||
msg.AddInt32("im_what", IM_SEND_MESSAGE);
|
||||
msg.AddString("id", fContactLinker->GetId());
|
||||
msg.AddString("message", message);
|
||||
fContactLinker->GetMessenger().SendMessage(&msg);
|
||||
|
||||
fSendView->SetText("");
|
||||
break;
|
||||
}
|
||||
case IM_MESSAGE:
|
||||
ImMessage(message);
|
||||
break;
|
||||
default:
|
||||
BWindow::MessageReceived(message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ChatWindow::ImMessage(BMessage* msg)
|
||||
{
|
||||
int32 im_what = msg->FindInt32("im_what");
|
||||
switch (im_what) {
|
||||
case IM_MESSAGE_RECEIVED:
|
||||
{
|
||||
BString message = msg->FindString("message");
|
||||
fReceiveView->AppendOtherMessage(message.String());
|
||||
break;
|
||||
}
|
||||
case IM_STATUS_CHANGED:
|
||||
{
|
||||
#if 0
|
||||
int32 status;
|
||||
|
||||
if (msg->FindInt32("status", &status) != B_OK)
|
||||
return;
|
||||
|
||||
BString id = msg->FindString("id");
|
||||
|
||||
if (id != "" && status >= CAYA_ONLINE) {
|
||||
bool found = false;
|
||||
BStringItem *item = fRosterMap.ValueFor(id,&found);
|
||||
|
||||
if (!found) {
|
||||
item = new BStringItem(id.String());
|
||||
item->SetHeight(50.0);
|
||||
listView->AddItem(item);
|
||||
fRosterMap.AddItem(id, item);
|
||||
} else {
|
||||
bool itemPresent = listView->HasItem(item);
|
||||
if (status == CAYA_OFFLINE) {
|
||||
//remove from list. (for now)
|
||||
if (itemPresent)
|
||||
listView->RemoveItem(item);
|
||||
} else {
|
||||
if(!itemPresent)
|
||||
listView->AddItem(item);
|
||||
}
|
||||
}
|
||||
|
||||
UpdateListItem(item);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case IM_CONTACT_INFO:
|
||||
{
|
||||
#if 0
|
||||
BString id = msg->FindString("id");
|
||||
BString fullName = msg->FindString("nick");
|
||||
if (id != "" && fullName != "") {
|
||||
bool found = false;
|
||||
BStringItem *item = fRosterMap.ValueFor(id,&found);
|
||||
if (!found) {
|
||||
item = new BStringItem(id.String());
|
||||
item->SetHeight(50.0);
|
||||
fRosterMap.AddItem(id, item);
|
||||
}
|
||||
|
||||
item->SetText(fullName);
|
||||
UpdateListItem(item);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ChatWindow::ObserveString(int32 what, BString str)
|
||||
{
|
||||
switch(what) {
|
||||
case STR_CONTACT_NAME:
|
||||
if (Lock()){
|
||||
SetTitle(str);
|
||||
fReceiveView->SetOtherNick(str);
|
||||
Unlock();
|
||||
}
|
||||
break;
|
||||
case STR_PERSONAL_STATUS:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ChatWindow::ObservePointer(int32 what, void* ptr)
|
||||
{
|
||||
switch (what) {
|
||||
case PTR_AVATAR_BITMAP:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ChatWindow::ObserveInteger(int32 what, int32 val)
|
||||
{
|
||||
switch (what) {
|
||||
case INT_CONTACT_STATUS:
|
||||
if (Lock()) {
|
||||
AppendStatus((CayaStatus)val);
|
||||
Unlock();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ChatWindow::AppendStatus(CayaStatus status)
|
||||
{
|
||||
BString message(fContactLinker->GetName());
|
||||
|
||||
switch (status) {
|
||||
case CAYA_ONLINE:
|
||||
message << " is available";
|
||||
break;
|
||||
case CAYA_EXTENDED_AWAY:
|
||||
case CAYA_AWAY:
|
||||
message << " is away";
|
||||
break;
|
||||
case CAYA_DO_NOT_DISTURB:
|
||||
message << " is busy, please do not disturb!";
|
||||
break;
|
||||
case CAYA_OFFLINE:
|
||||
message << " is offline";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
fReceiveView->Append(message.String(), COL_TEXT, COL_TEXT, R_TEXT);
|
||||
fReceiveView->Append("\n", COL_TEXT, COL_TEXT, R_TEXT);
|
||||
fReceiveView->ScrollToSelection();
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright 2009, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef ChatWindow_H_
|
||||
#define ChatWindow_H_
|
||||
|
||||
#include <Window.h>
|
||||
#include <TextView.h>
|
||||
#include "Observer.h"
|
||||
#include "CayaConstants.h"
|
||||
|
||||
class ContactLinker;
|
||||
class CayaRenderView;
|
||||
|
||||
class ChatWindow: public BWindow , public Observer
|
||||
{
|
||||
|
||||
public:
|
||||
ChatWindow(ContactLinker* cl);
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
void ImMessage(BMessage *msg);
|
||||
virtual bool QuitRequested();
|
||||
|
||||
void ObserveString(int32 what, BString str);
|
||||
void ObservePointer(int32 what, void* ptr);
|
||||
void ObserveInteger(int32 what, int32 val);
|
||||
void AppendStatus(CayaStatus status);
|
||||
|
||||
private:
|
||||
|
||||
BTextView* fSendView;
|
||||
ContactLinker* fContactLinker;
|
||||
CayaRenderView *fReceiveView;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
//--
|
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
* Copyright 2009, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Andrea Anzani, andrea.anzani@gmail.com
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ChatWindow.h"
|
||||
#include "ContactLinker.h"
|
||||
#include "ContactPopUp.h"
|
||||
#include "NotifyMessage.h"
|
||||
#include "ProtocolManager.h"
|
||||
#include "RosterItem.h"
|
||||
#include "WindowsManager.h"
|
||||
|
||||
|
||||
ContactLinker::ContactLinker(BString id, BMessenger msgn)
|
||||
: fChatWindow(NULL),
|
||||
fID(id),
|
||||
fName(id),
|
||||
fMessenger(msgn),
|
||||
fStatus(CAYA_OFFLINE),
|
||||
fPopUp(NULL)
|
||||
{
|
||||
// Create the roster item and register it as observer
|
||||
fRosterItem = new RosterItem(id.String(), this);
|
||||
RegisterObserver(fRosterItem);
|
||||
|
||||
// By default we use protocol icon as avatar icon
|
||||
fAvatarBitmap = ProtocolManager::Get()->GetProtocolIcon("gtalk");
|
||||
}
|
||||
|
||||
|
||||
ChatWindow*
|
||||
ContactLinker::GetChatWindow()
|
||||
{
|
||||
if (fChatWindow == NULL)
|
||||
CreateChatWindow();
|
||||
return fChatWindow;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ContactLinker::DeleteWindow()
|
||||
{
|
||||
if (fChatWindow != NULL) {
|
||||
if (fChatWindow->Lock()) {
|
||||
UnregisterObserver(fChatWindow);
|
||||
fChatWindow->Quit();
|
||||
fChatWindow = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ContactLinker::ShowWindow()
|
||||
{
|
||||
if (fChatWindow == NULL)
|
||||
CreateChatWindow();
|
||||
fChatWindow->SetWorkspaces(B_CURRENT_WORKSPACE);
|
||||
if (fChatWindow->IsHidden())
|
||||
fChatWindow->Show();
|
||||
fChatWindow->Activate(true);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ContactLinker::HideWindow()
|
||||
{
|
||||
if ((fChatWindow != NULL) && !fChatWindow->IsHidden())
|
||||
fChatWindow->Hide();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ContactLinker::ShowPopUp(BPoint where)
|
||||
{
|
||||
if (fPopUp == NULL) {
|
||||
fPopUp = new ContactPopUp(this);
|
||||
RegisterObserver(fPopUp);
|
||||
}
|
||||
|
||||
fPopUp->Show();
|
||||
fPopUp->MoveTo(where);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ContactLinker::HidePopUp()
|
||||
{
|
||||
if ((fPopUp != NULL) && !fPopUp->IsHidden())
|
||||
fPopUp->Hide();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ContactLinker::DeletePopUp()
|
||||
{
|
||||
if (fPopUp == NULL)
|
||||
return;
|
||||
|
||||
if (fPopUp->Lock()) {
|
||||
UnregisterObserver(fPopUp);
|
||||
fPopUp->Quit();
|
||||
fPopUp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ContactLinker::SetNotifyName(BString name)
|
||||
{
|
||||
if (fName.Compare(name) != 0) {
|
||||
fName = name;
|
||||
NotifyString(STR_CONTACT_NAME, name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ContactLinker::SetNotifyAvatarBitmap(BBitmap* bitmap)
|
||||
{
|
||||
if ((fAvatarBitmap != bitmap) && (bitmap != NULL)) {
|
||||
fAvatarBitmap = bitmap;
|
||||
NotifyPointer(PTR_AVATAR_BITMAP, (void*)bitmap);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ContactLinker::SetNotifyStatus(CayaStatus status)
|
||||
{
|
||||
if (fStatus != status) {
|
||||
fStatus = status;
|
||||
NotifyInteger(INT_CONTACT_STATUS, (int32)fStatus);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ContactLinker::SetNotifyPersonalStatus(BString personalStatus)
|
||||
{
|
||||
if (fPersonalStatus.Compare(personalStatus) != 0) {
|
||||
fPersonalStatus = personalStatus;
|
||||
NotifyString(STR_PERSONAL_STATUS, personalStatus);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ContactLinker::CreateChatWindow()
|
||||
{
|
||||
fChatWindow = new ChatWindow(this);
|
||||
WindowsManager::Get()->RelocateWindow(fChatWindow);
|
||||
RegisterObserver(fChatWindow);
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright 2009, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _CONTACT_LINKER_H_
|
||||
#define _CONTACT_LINKER_H_
|
||||
|
||||
#include <String.h>
|
||||
#include <Message.h>
|
||||
#include <Messenger.h>
|
||||
|
||||
#include "Notifier.h"
|
||||
#include "CayaConstants.h"
|
||||
|
||||
class BBitmap;
|
||||
|
||||
class ChatWindow;
|
||||
class ContactPopUp;
|
||||
class RosterItem;
|
||||
|
||||
class ContactLinker : public Notifier {
|
||||
public:
|
||||
ContactLinker(BString id, BMessenger msgn);
|
||||
|
||||
ChatWindow* GetChatWindow();
|
||||
void DeleteWindow();
|
||||
|
||||
void ShowWindow();
|
||||
void HideWindow();
|
||||
|
||||
void ShowPopUp(BPoint where);
|
||||
void DeletePopUp();
|
||||
void HidePopUp();
|
||||
|
||||
RosterItem* GetRosterItem() { return fRosterItem; }
|
||||
|
||||
BString GetId() { return fID; }
|
||||
|
||||
BMessenger GetMessenger() { return fMessenger; }
|
||||
|
||||
BString GetName() { return fName; }
|
||||
BBitmap* AvatarBitmap() { return fAvatarBitmap; }
|
||||
|
||||
void SetNotifyName(BString name);
|
||||
void SetNotifyAvatarBitmap(BBitmap* bitmap);
|
||||
void SetNotifyStatus(CayaStatus status);
|
||||
void SetNotifyPersonalStatus(BString personalStatus);
|
||||
|
||||
private:
|
||||
void CreateChatWindow();
|
||||
|
||||
RosterItem* fRosterItem;
|
||||
ChatWindow* fChatWindow;
|
||||
BMessenger fMessenger;
|
||||
|
||||
BString fID;
|
||||
BString fName;
|
||||
BString fPersonalStatus;
|
||||
BBitmap* fAvatarBitmap;
|
||||
CayaStatus fStatus;
|
||||
ContactPopUp* fPopUp;
|
||||
};
|
||||
|
||||
#endif // _CONTACT_LINKER_H_
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright 2009, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Andrea Anzani, andrea.anzani@gmail.com
|
||||
*/
|
||||
|
||||
#include <InterfaceDefs.h>
|
||||
#include <Message.h>
|
||||
#include <Window.h>
|
||||
|
||||
#include "EditingFilter.h"
|
||||
|
||||
|
||||
EditingFilter::EditingFilter(BTextView* view)
|
||||
: BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE, B_KEY_DOWN, NULL),
|
||||
_view(view)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
filter_result
|
||||
EditingFilter::Filter(BMessage* message, BHandler** target)
|
||||
{
|
||||
int32 modifiers;
|
||||
|
||||
int8 byte;
|
||||
message->FindInt8("byte", &byte);
|
||||
|
||||
// If we have modifiers but none are the Alt key
|
||||
if (message->FindInt32("modifiers", &modifiers))
|
||||
return B_DISPATCH_MESSAGE;
|
||||
|
||||
// If the Alt key jives with the command_enter status
|
||||
if ((modifiers & B_COMMAND_KEY) != 0 && byte == B_ENTER) {
|
||||
_view->Insert("\n");
|
||||
return B_SKIP_MESSAGE;
|
||||
} else if ((modifiers & B_COMMAND_KEY) == 0 && byte == B_ENTER) {
|
||||
_view->Window()->PostMessage('chat');
|
||||
return B_SKIP_MESSAGE;
|
||||
}
|
||||
|
||||
return B_DISPATCH_MESSAGE;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright 2009, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef EDITING_FILTER_H
|
||||
#define EDITING_FILTER_H
|
||||
|
||||
#include <MessageFilter.h>
|
||||
#include <interface/TextView.h>
|
||||
|
||||
class EditingFilter : public BMessageFilter {
|
||||
public:
|
||||
EditingFilter(BTextView *view);
|
||||
|
||||
virtual filter_result Filter(BMessage *message, BHandler **target);
|
||||
|
||||
private:
|
||||
BTextView *_view;
|
||||
};
|
||||
#endif
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright 2009, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Andrea Anzani, andrea.anzani@gmail.com
|
||||
*/
|
||||
|
||||
#include "ImageCache.h"
|
||||
|
||||
#include <AppDefs.h>
|
||||
#include <Bitmap.h>
|
||||
#include <Debug.h>
|
||||
#include <TranslationUtils.h>
|
||||
|
||||
ImageCache *ImageCache::m_instance = NULL;
|
||||
|
||||
|
||||
ImageCache::ImageCache()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ImageCache::~ImageCache()
|
||||
{
|
||||
while(m_bitmaps.CountItems()) {
|
||||
BBitmap* bit=m_bitmaps.ValueFor(0);
|
||||
delete bit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BBitmap*
|
||||
ImageCache::GetImage(BString which, BString name)
|
||||
{
|
||||
if (m_instance == NULL)
|
||||
m_instance = new ImageCache();
|
||||
|
||||
// Loads the bitmap if found
|
||||
bool found;
|
||||
BBitmap* bitmap = m_instance->m_bitmaps.ValueFor(name, &found);
|
||||
|
||||
if (!found) {
|
||||
bitmap = LoadImage(which.String(), name.String());
|
||||
if (bitmap)
|
||||
m_instance->m_bitmaps.AddItem(name, bitmap);
|
||||
return bitmap;
|
||||
} else
|
||||
return bitmap;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ImageCache::AddImage(BString name, BBitmap* which)
|
||||
{
|
||||
if (m_instance == NULL)
|
||||
m_instance = new ImageCache();
|
||||
|
||||
m_instance->m_bitmaps.AddItem(name, which);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ImageCache::DeleteImage(BString name)
|
||||
{
|
||||
if (m_instance == NULL)
|
||||
m_instance = new ImageCache();
|
||||
|
||||
BBitmap* bitmap = m_instance->m_bitmaps.ValueFor(name);
|
||||
if (bitmap){
|
||||
m_instance->m_bitmaps.RemoveItemFor(name);
|
||||
delete bitmap;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ImageCache::Release()
|
||||
{
|
||||
if (m_instance != NULL) {
|
||||
delete m_instance;
|
||||
m_instance = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BBitmap*
|
||||
ImageCache::LoadImage(const char* fullName, const char* shortName)
|
||||
{
|
||||
BBitmap* bitmap = BTranslationUtils::GetBitmap(fullName);
|
||||
if (!bitmap)
|
||||
bitmap = BTranslationUtils::GetBitmap('PNG ', shortName);
|
||||
|
||||
if (!bitmap)
|
||||
printf("ImageCache: Can't load bitmap! %s\n",fullName);
|
||||
return bitmap;
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright 2009, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef ImageCache_H
|
||||
#define ImageCache_H
|
||||
|
||||
/**
|
||||
* ImageCache.
|
||||
* @author Andrea Anzani.
|
||||
*/
|
||||
|
||||
class BBitmap;
|
||||
|
||||
#include <SupportDefs.h>
|
||||
#include <String.h>
|
||||
#include "KeyMap.h"
|
||||
|
||||
class ImageCache
|
||||
{
|
||||
|
||||
protected: // Constructor/Destructor
|
||||
|
||||
ImageCache();
|
||||
|
||||
~ImageCache();
|
||||
|
||||
public: // Operations
|
||||
|
||||
/** Returns the image corresponding to the which constant */
|
||||
static BBitmap * GetImage( BString fullPath , BString symbolicName);
|
||||
|
||||
|
||||
static void AddImage(BString name,BBitmap* which);
|
||||
static void DeleteImage(BString name);
|
||||
|
||||
/** Frees the singleton instance of the cache;
|
||||
Call this when app quits
|
||||
*/
|
||||
static void Release();
|
||||
|
||||
private:
|
||||
|
||||
static BBitmap * LoadImage( const char *resourceName,const char *);
|
||||
// Class Data
|
||||
|
||||
static ImageCache * m_instance;
|
||||
|
||||
private: // Instance Data
|
||||
|
||||
|
||||
KeyMap<BString,BBitmap*> m_bitmaps;
|
||||
|
||||
};
|
||||
|
||||
#endif /* __C_ImageCache_H__ */
|
|
@ -0,0 +1,56 @@
|
|||
SubDir TOP application ;
|
||||
|
||||
SubDirSysHdrs [ FDirName $(TOP) ] ;
|
||||
SubDirSysHdrs [ FDirName $(TOP) libs ] ;
|
||||
SubDirSysHdrs [ FDirName $(TOP) libs libjabber ] ;
|
||||
SubDirSysHdrs [ FDirName $(TOP) libs librunview ] ;
|
||||
SubDirSysHdrs [ FDirName $(TOP) libs libinterface ] ;
|
||||
SubDirSysHdrs [ FDirName $(OPENSSL_INCLUDE_DIR) ] ;
|
||||
|
||||
SEARCH_SOURCE += [ FDirName $(TOP) application preferences ] ;
|
||||
SEARCH_SOURCE += [ FDirName $(TOP) application views ] ;
|
||||
|
||||
Application caya :
|
||||
Account.cpp
|
||||
AccountManager.cpp
|
||||
CayaUtils.cpp
|
||||
ChatWindow.cpp
|
||||
ContactLinker.cpp
|
||||
EditingFilter.cpp
|
||||
ImageCache.cpp
|
||||
LooperCayaProtocol.cpp
|
||||
Main.cpp
|
||||
MainWindow.cpp
|
||||
Notifier.cpp
|
||||
ProtocolManager.cpp
|
||||
ProtocolSettings.cpp
|
||||
Server.cpp
|
||||
TheApp.cpp
|
||||
WindowsManager.cpp
|
||||
|
||||
# preferences
|
||||
AccountListItem.cpp
|
||||
PreferencesDialog.cpp
|
||||
PreferencesAccounts.cpp
|
||||
|
||||
# views
|
||||
ContactPopUp.cpp
|
||||
NicknameTextControl.cpp
|
||||
RosterItem.cpp
|
||||
RosterListView.cpp
|
||||
StatusMenuItem.cpp
|
||||
StatusView.cpp
|
||||
CayaRenderView.cpp
|
||||
: be $(TARGET_LIBSTDC++) network translation expat
|
||||
librunview.a libinterface.a libjabber.a
|
||||
ssl crypto
|
||||
: caya.rdef
|
||||
;
|
||||
|
||||
Depends caya : libjabber.a ;
|
||||
Depends caya : librunview.a ;
|
||||
Depends caya : libinterface.a ;
|
||||
|
||||
LINKFLAGS on caya += -L$(OPENSSL_LIBRARY_DIR) ;
|
||||
|
||||
InstallBin $(APPS_DIRECTORY)/caya : caya ;
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* Copyright 2009, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _KEY_MAP_H
|
||||
#define _KEY_MAP_H
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <List.h>
|
||||
#include <SupportDefs.h>
|
||||
|
||||
template<class KEY, class TYPE>
|
||||
class KeyMap {
|
||||
public:
|
||||
uint32 CountItems();
|
||||
|
||||
void AddItem(KEY k, TYPE t);
|
||||
|
||||
TYPE ValueFor(KEY, bool* found = NULL);
|
||||
|
||||
void RemoveItemAt(int32 position);
|
||||
void RemoveItemFor(KEY);
|
||||
|
||||
TYPE ValueAt(int32 position);
|
||||
KEY KeyAt(int32 position);
|
||||
|
||||
BList* Items();
|
||||
|
||||
private:
|
||||
std::map<KEY,TYPE> fMap;
|
||||
typedef typename std::map<KEY,TYPE>::iterator fIter;
|
||||
};
|
||||
|
||||
|
||||
template<class KEY, class TYPE>
|
||||
uint32 KeyMap<KEY, TYPE>::CountItems()
|
||||
{
|
||||
return fMap.size();
|
||||
}
|
||||
|
||||
|
||||
template<class KEY, class TYPE>
|
||||
void KeyMap<KEY, TYPE>::AddItem(KEY k, TYPE t)
|
||||
{
|
||||
fMap[k] = t;
|
||||
}
|
||||
|
||||
|
||||
template<class KEY, class TYPE>
|
||||
TYPE KeyMap<KEY, TYPE>::ValueFor(KEY k, bool* found)
|
||||
{
|
||||
fIter i = fMap.find(k);
|
||||
|
||||
if (found) {
|
||||
if (i == fMap.end())
|
||||
*found = false;
|
||||
else
|
||||
*found = true;
|
||||
}
|
||||
|
||||
if (i == fMap.end())
|
||||
return NULL;
|
||||
return i->second;
|
||||
}
|
||||
|
||||
|
||||
template<class KEY, class TYPE>
|
||||
void KeyMap<KEY, TYPE>::RemoveItemAt(int32 position)
|
||||
{
|
||||
fIter i = fMap.begin();
|
||||
std::advance(i, position);
|
||||
fMap.erase(i->first);
|
||||
}
|
||||
|
||||
|
||||
template<class KEY, class TYPE>
|
||||
void KeyMap<KEY, TYPE>::RemoveItemFor(KEY k)
|
||||
{
|
||||
fMap.erase(k);
|
||||
}
|
||||
|
||||
|
||||
template<class KEY, class TYPE>
|
||||
TYPE KeyMap<KEY, TYPE>::ValueAt(int32 position)
|
||||
{
|
||||
fIter i = fMap.begin();
|
||||
std::advance(i, position);
|
||||
if (i == fMap.end())
|
||||
return NULL;
|
||||
return i->second;
|
||||
}
|
||||
|
||||
|
||||
template<class KEY, class TYPE>
|
||||
KEY KeyMap<KEY, TYPE>::KeyAt(int32 position)
|
||||
{
|
||||
fIter i = fMap.begin();
|
||||
std::advance(i, position);
|
||||
if (i == fMap.end())
|
||||
return NULL;
|
||||
return i->first;
|
||||
}
|
||||
|
||||
|
||||
template<class KEY, class TYPE>
|
||||
BList* KeyMap<KEY, TYPE>::Items()
|
||||
{
|
||||
BList* list = new BList();
|
||||
|
||||
for (fIter i = fMap.begin(); i != fMap.end(); ++i)
|
||||
list->AddItem(i->second);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
#endif // _KEY_MAP_H
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright 2009, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Andrea Anzani, andrea.anzani@gmail.com
|
||||
*/
|
||||
|
||||
#include <String.h>
|
||||
|
||||
#include "LooperCayaProtocol.h"
|
||||
|
||||
|
||||
LooperCayaProtocol::LooperCayaProtocol(CayaProtocol* protocol)
|
||||
: BLooper(),
|
||||
fProtocol(protocol)
|
||||
{
|
||||
BString name("CayaProcol - ");
|
||||
name << protocol->GetFriendlySignature();
|
||||
SetName(name.String());
|
||||
Run();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LooperCayaProtocol::MessageReceived(BMessage* msg)
|
||||
{
|
||||
if (Protocol()->Process(msg) != B_OK)
|
||||
BLooper::MessageReceived(msg);
|
||||
}
|
||||
|
||||
|
||||
CayaProtocol*
|
||||
LooperCayaProtocol::Protocol()
|
||||
{
|
||||
return fProtocol;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright 2009, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef LooperCayaProtocol_h
|
||||
#define LooperCayaProtocol_h
|
||||
|
||||
#include <Looper.h>
|
||||
#include "CayaProtocol.h"
|
||||
|
||||
class LooperCayaProtocol : public BLooper
|
||||
{
|
||||
public:
|
||||
LooperCayaProtocol(CayaProtocol* protocol);
|
||||
|
||||
void MessageReceived(BMessage* msg);
|
||||
|
||||
CayaProtocol* Protocol();
|
||||
|
||||
private:
|
||||
CayaProtocol* fProtocol;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright 2009, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Andrea Anzani, andrea.anzani@gmail.com
|
||||
*/
|
||||
|
||||
#include "TheApp.h"
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
TheApp app;
|
||||
app.Run();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,314 @@
|
|||
/*
|
||||
* Copyright 2009-2010, Andrea Anzani. All rights reserved.
|
||||
* Copyright 2009-2010, Pier Luigi Fiorini. 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
|
||||
*/
|
||||
|
||||
#include <Application.h>
|
||||
#include <Button.h>
|
||||
#include <Alert.h>
|
||||
#include <ListView.h>
|
||||
#include <Box.h>
|
||||
#include <CheckBox.h>
|
||||
#include <Entry.h>
|
||||
#include <GridLayoutBuilder.h>
|
||||
#include <GroupLayout.h>
|
||||
#include <CardLayout.h>
|
||||
#include <GroupLayoutBuilder.h>
|
||||
#include <Layout.h>
|
||||
#include <GridLayout.h>
|
||||
#include <SpaceLayoutItem.h>
|
||||
#include <ScrollView.h>
|
||||
#include <StringView.h>
|
||||
#include <TextControl.h>
|
||||
#include <TranslationUtils.h>
|
||||
|
||||
#include "CayaConstants.h"
|
||||
#include "NotifyMessage.h"
|
||||
#include "MainWindow.h"
|
||||
#include "PreferencesDialog.h"
|
||||
#include "RosterItem.h"
|
||||
#include "RosterListView.h"
|
||||
#include "Server.h"
|
||||
#include "StatusView.h"
|
||||
|
||||
const int32 kLogin = 'LOGI';
|
||||
const int32 kSearchContact = 'SRCH';
|
||||
const int32 kPreferences = 'PRFS';
|
||||
|
||||
|
||||
MainWindow::MainWindow() :
|
||||
BWindow(BRect(0, 0, 300, 400), "Caya", B_DOCUMENT_WINDOW, 0)
|
||||
{
|
||||
SetLayout(fStack = new BCardLayout());
|
||||
|
||||
BBox* loginView = new BBox("loginView");
|
||||
|
||||
BButton* login = new BButton(BRect(294.0, 302.0, 392.0, 328.0), "login",
|
||||
"Login", new BMessage(kLogin), B_FOLLOW_BOTTOM | B_FOLLOW_RIGHT);
|
||||
|
||||
loginView->SetLayout(new BGroupLayout(B_HORIZONTAL));
|
||||
loginView->AddChild(BGroupLayoutBuilder(B_VERTICAL, 5)
|
||||
.Add(BGridLayoutBuilder(10, 10)
|
||||
.Add(new BStringView("label_u", "Username"), 0, 0)
|
||||
.Add(fUsername = new BTextControl("username", NULL, NULL, NULL), 1, 0)
|
||||
.Add(new BStringView("label_p", "Password"), 0, 1)
|
||||
.Add(fPassword = new BTextControl("password", NULL, NULL,
|
||||
new BMessage(kLogin)), 1, 1), 2)
|
||||
.Add(login, 3)
|
||||
);
|
||||
|
||||
fStack->AddView(loginView);
|
||||
|
||||
fStatusView = new StatusView("statusView");
|
||||
|
||||
BTextControl* searchBox = new BTextControl("searchBox", NULL, NULL,
|
||||
new BMessage(kSearchContact));
|
||||
|
||||
BBox* rosterView = new BBox("rosterView");
|
||||
|
||||
fListView = new RosterListView("buddyView");
|
||||
fListView->SetInvocationMessage(new BMessage(OPEN_WINDOW));
|
||||
BScrollView* scrollView = new BScrollView("scrollview", fListView,
|
||||
B_WILL_DRAW, false, true);
|
||||
|
||||
BButton* wrench = new BButton("wrench", new BMessage(kPreferences));
|
||||
|
||||
rosterView->SetLayout(new BGroupLayout(B_HORIZONTAL));
|
||||
rosterView->AddChild(BGroupLayoutBuilder(B_HORIZONTAL)
|
||||
.AddGroup(B_VERTICAL)
|
||||
.AddGroup(B_HORIZONTAL)
|
||||
.AddGroup(B_VERTICAL)
|
||||
.Add(fStatusView)
|
||||
.Add(searchBox)
|
||||
.End()
|
||||
.Add(wrench)
|
||||
.End()
|
||||
.Add(scrollView)
|
||||
.End()
|
||||
.SetInsets(5, 5, 5, 10)
|
||||
);
|
||||
|
||||
fStack->AddView(rosterView);
|
||||
fStack->SetVisibleItem((long)0);
|
||||
|
||||
AddShortcut('a', B_COMMAND_KEY, new BMessage(B_ABOUT_REQUESTED));
|
||||
MoveTo(BAlert::AlertPosition(Bounds().Width(), Bounds().Height() / 2));
|
||||
|
||||
fPassword->TextView()->HideTyping(true);
|
||||
fUsername->MakeFocus(true);
|
||||
|
||||
fSrv = new Server(this);
|
||||
AddFilter(fSrv);
|
||||
|
||||
CenterOnScreen();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
MainWindow::QuitRequested()
|
||||
{
|
||||
fListView->MakeEmpty();
|
||||
fSrv->Quit();
|
||||
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::MessageReceived(BMessage* message)
|
||||
{
|
||||
switch(message->what) {
|
||||
case kLogin:
|
||||
{
|
||||
BString username(fUsername->Text());
|
||||
BString password(fPassword->Text());
|
||||
if (username == "" || password == "")
|
||||
return;
|
||||
|
||||
BMessage config;
|
||||
config.AddString("username", username);
|
||||
config.AddString("password", password);
|
||||
config.AddString("resource", "caya");
|
||||
|
||||
fSrv->UpdateSettings(config);
|
||||
fSrv->Login();
|
||||
|
||||
fStack->SetVisibleItem((long)1);
|
||||
break;
|
||||
}
|
||||
case kSearchContact:
|
||||
{
|
||||
void* control = NULL;
|
||||
if (message->FindPointer("source", &control) != B_OK)
|
||||
return;
|
||||
|
||||
BTextControl* searchBox = static_cast<BTextControl*>(control);
|
||||
if (searchBox == NULL)
|
||||
return;
|
||||
|
||||
RosterMap map = fSrv->RosterItems();
|
||||
for (uint32 i = 0; i < map.CountItems(); i++) {
|
||||
ContactLinker* linker = map.ValueAt(i);
|
||||
RosterItem* item = linker->GetRosterItem();
|
||||
|
||||
// If the search filter has been deleted show all the items,
|
||||
// otherwise remove the item in order to show only items
|
||||
// that matches the search criteria
|
||||
if (strcmp(searchBox->Text(), "") == 0)
|
||||
AddItem(item);
|
||||
else if (linker->GetName().IFindFirst(searchBox->Text()) == B_ERROR)
|
||||
RemoveItem(item);
|
||||
else
|
||||
AddItem(item);
|
||||
UpdateListItem(item);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kPreferences: {
|
||||
PreferencesDialog* dialog = new PreferencesDialog();
|
||||
dialog->Show();
|
||||
break;
|
||||
}
|
||||
case IM_MESSAGE:
|
||||
ImMessage(message);
|
||||
break;
|
||||
case IM_ERROR:
|
||||
ImError(message);
|
||||
break;
|
||||
default:
|
||||
BWindow::MessageReceived(message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::ImError(BMessage* msg)
|
||||
{
|
||||
//FIXME: better error handling..
|
||||
BAlert* alert = new BAlert("Error", msg->FindString("error"), "Ouch!");
|
||||
alert->Go();
|
||||
fStack->SetVisibleItem((long)0);
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::ImMessage(BMessage* msg)
|
||||
{
|
||||
int32 im_what = msg->FindInt32("im_what");
|
||||
switch(im_what) {
|
||||
case IM_OWN_CONTACT_INFO:
|
||||
{
|
||||
fStatusView->SetName(msg->FindString("nick"));
|
||||
|
||||
entry_ref ref;
|
||||
if (msg->FindRef("ref", &ref) == B_OK) {
|
||||
BBitmap* bitmap = BTranslationUtils::GetBitmap(&ref);
|
||||
fStatusView->SetAvatar(bitmap);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IM_STATUS_CHANGED:
|
||||
{
|
||||
int32 status;
|
||||
|
||||
if (msg->FindInt32("status", &status) != B_OK)
|
||||
return;
|
||||
|
||||
RosterItem* rosterItem = fSrv->RosterItemForId(msg->FindString("id"));
|
||||
|
||||
if (rosterItem) {
|
||||
// Add or remove item
|
||||
UpdateListItem(rosterItem);
|
||||
switch (status) {
|
||||
case CAYA_OFFLINE:
|
||||
if (HasItem(rosterItem))
|
||||
RemoveItem(rosterItem);
|
||||
return;
|
||||
default:
|
||||
if (!HasItem(rosterItem))
|
||||
AddItem(rosterItem);
|
||||
break;
|
||||
}
|
||||
UpdateListItem(rosterItem);
|
||||
|
||||
// Sort list view again
|
||||
fListView->Sort();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IM_AVATAR_CHANGED:
|
||||
case IM_CONTACT_INFO:
|
||||
{
|
||||
RosterItem* rosterItem = fSrv->RosterItemForId(msg->FindString("id"));
|
||||
if (rosterItem)
|
||||
UpdateListItem(rosterItem);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::ObserveInteger(int32 what, int32 val)
|
||||
{
|
||||
switch (what) {
|
||||
case INT_ACCOUNT_STATUS:
|
||||
fStatusView->SetStatus((CayaStatus)val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::UpdateListItem(RosterItem* item)
|
||||
{
|
||||
if (fListView->HasItem(item))
|
||||
fListView->InvalidateItem(fListView->IndexOf(item));
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
MainWindow::CountItems() const
|
||||
{
|
||||
return fListView->CountItems();
|
||||
}
|
||||
|
||||
|
||||
RosterItem*
|
||||
MainWindow::ItemAt(int index)
|
||||
{
|
||||
return dynamic_cast<RosterItem*>(fListView->ItemAt(index));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::AddItem(RosterItem* item)
|
||||
{
|
||||
// Don't add offline items and avoid duplicates
|
||||
if ((item->Status() == CAYA_OFFLINE) || HasItem(item))
|
||||
return;
|
||||
|
||||
// Add item and sort
|
||||
fListView->AddItem(item);
|
||||
fListView->Sort();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
MainWindow::HasItem(RosterItem* item)
|
||||
{
|
||||
return fListView->HasItem(item);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::RemoveItem(RosterItem* item)
|
||||
{
|
||||
// Remove item and sort
|
||||
fListView->RemoveItem(item);
|
||||
fListView->Sort();
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright 2009-2010, Andrea Anzani. All rights reserved.
|
||||
* Copyright 2009-2010, Pier Luigi Fiorini. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _MAIN_WINDOW_H
|
||||
#define _MAIN_WINDOW_H
|
||||
|
||||
#include <Window.h>
|
||||
|
||||
#include "Observer.h"
|
||||
|
||||
class BCardLayout;
|
||||
class BTextControl;
|
||||
|
||||
class Server;
|
||||
class StatusView;
|
||||
class RosterListView;
|
||||
class RosterItem;
|
||||
|
||||
#define OPEN_WINDOW 'opwn'
|
||||
#define CLOSE_WINDOW 'clwn'
|
||||
|
||||
class MainWindow: public BWindow, public Observer {
|
||||
public:
|
||||
MainWindow();
|
||||
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
void ImMessage(BMessage* msg);
|
||||
void ImError(BMessage* msg);
|
||||
virtual bool QuitRequested();
|
||||
|
||||
void ObserveInteger(int32 what, int32 val);
|
||||
|
||||
Server* GetServer() const { return fSrv; }
|
||||
|
||||
void UpdateListItem(RosterItem* item);
|
||||
|
||||
int32 CountItems() const;
|
||||
RosterItem* ItemAt(int index);
|
||||
void AddItem(RosterItem*);
|
||||
bool HasItem(RosterItem*);
|
||||
void RemoveItem(RosterItem*);
|
||||
|
||||
private:
|
||||
StatusView* fStatusView;
|
||||
RosterListView* fListView;
|
||||
BCardLayout* fStack;
|
||||
BTextControl* fUsername;
|
||||
BTextControl* fPassword;
|
||||
Server* fSrv;
|
||||
};
|
||||
|
||||
#endif // _MAIN_WINDOW_H
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright 2009, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Andrea Anzani, andrea.anzani@gmail.com
|
||||
*/
|
||||
|
||||
#include "Notifier.h"
|
||||
#include "Observer.h"
|
||||
|
||||
|
||||
void
|
||||
Notifier::RegisterObserver(Observer* obs)
|
||||
{
|
||||
if (!fObserverList.HasItem(obs))
|
||||
fObserverList.AddItem(obs);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Notifier::UnregisterObserver(Observer* obs)
|
||||
{
|
||||
if (fObserverList.HasItem(obs))
|
||||
fObserverList.RemoveItem(obs, false);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Notifier::NotifyString(int32 what, BString str)
|
||||
{
|
||||
for (int i = 0; i < fObserverList.CountItems(); i++)
|
||||
fObserverList.ItemAt(i)->ObserveString(what, str);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Notifier::NotifyInteger(int32 what, int32 value)
|
||||
{
|
||||
for (int i = 0; i < fObserverList.CountItems(); i++)
|
||||
fObserverList.ItemAt(i)->ObserveInteger(what, value);
|
||||
}
|
||||
|
||||
void
|
||||
Notifier::NotifyPointer(int32 what, void* ptr)
|
||||
{
|
||||
for (int i = 0; i < fObserverList.CountItems(); i++)
|
||||
fObserverList.ItemAt(i)->ObservePointer(what, ptr);
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright 2009, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef Notifier_h_
|
||||
#define Notifier_h_
|
||||
|
||||
#include <String.h>
|
||||
|
||||
#include "ObjectList.h"
|
||||
#include "Observer.h"
|
||||
|
||||
class Notifier
|
||||
{
|
||||
public:
|
||||
|
||||
void RegisterObserver(Observer*);
|
||||
void UnregisterObserver(Observer*);
|
||||
|
||||
void NotifyString(int32 what, BString str);
|
||||
void NotifyInteger(int32 what, int32 value);
|
||||
void NotifyPointer(int32 what, void* ptr);
|
||||
|
||||
private:
|
||||
|
||||
BObjectList<Observer> fObserverList;
|
||||
|
||||
};
|
||||
#endif
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright 2009, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _NOTIFY_MESSAGE_H
|
||||
#define _NOTIFY_MESSAGE_H
|
||||
|
||||
enum {
|
||||
STR_CONTACT_NAME,
|
||||
STR_PERSONAL_STATUS,
|
||||
|
||||
PTR_AVATAR_BITMAP,
|
||||
|
||||
INT_ACCOUNT_STATUS,
|
||||
INT_CONTACT_STATUS
|
||||
};
|
||||
|
||||
#endif // _NOTIFY_MESSAGE_H
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright 2009, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef Observer_h_
|
||||
#define Observer_h_
|
||||
|
||||
#include <String.h>
|
||||
|
||||
class Notifier;
|
||||
|
||||
class Observer
|
||||
{
|
||||
public:
|
||||
virtual void ObserveString(int32 what, BString str) {};
|
||||
virtual void ObserveInteger(int32 what, int32 value) {};
|
||||
virtual void ObservePointer(int32 what, void* ptr) {};
|
||||
};
|
||||
#endif
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright 2009, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Andrea Anzani, andrea.anzani@gmail.com
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Entry.h>
|
||||
#include <image.h>
|
||||
|
||||
#include <libinterface/BitmapUtils.h>
|
||||
|
||||
#include "ProtocolManager.h"
|
||||
#include "CayaProtocol.h"
|
||||
#include "CayaUtils.h"
|
||||
|
||||
static ProtocolManager* fInstance = NULL;
|
||||
|
||||
|
||||
void
|
||||
ProtocolManager::Init(BDirectory protocolDir)
|
||||
{
|
||||
BEntry entry;
|
||||
BPath path;
|
||||
|
||||
protocolDir.Rewind();
|
||||
|
||||
while (protocolDir.GetNextEntry(&entry) == B_OK) {
|
||||
path = BPath(&entry);
|
||||
|
||||
image_id id = load_add_on(path.Path());
|
||||
if (id >= 0) {
|
||||
CayaProtocol* (*main_protocol)();
|
||||
if (get_image_symbol(id, "main_protocol", B_SYMBOL_TYPE_TEXT,
|
||||
(void**)&main_protocol) == B_OK) {
|
||||
CayaProtocol* cayp = (*main_protocol)();
|
||||
|
||||
if (cayp) {
|
||||
printf("Found a new Protocol: %s [%s]\n", cayp->GetFriendlySignature(),
|
||||
cayp->GetSignature());
|
||||
fProtocolMap.AddItem(BString(cayp->GetSignature()), cayp);
|
||||
fAddonMap.AddItem(BString(cayp->GetSignature()), new BPath(path));
|
||||
} else
|
||||
unload_add_on(id);
|
||||
} else
|
||||
unload_add_on(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ProtocolManager::ProtocolManager()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ProtocolManager*
|
||||
ProtocolManager::Get()
|
||||
{
|
||||
if (fInstance == NULL)
|
||||
fInstance = new ProtocolManager();
|
||||
return fInstance;
|
||||
}
|
||||
|
||||
|
||||
CayaProtocol*
|
||||
ProtocolManager::GetProtocol(BString signature)
|
||||
{
|
||||
return fProtocolMap.ValueFor(signature);
|
||||
}
|
||||
|
||||
|
||||
BList*
|
||||
ProtocolManager::GetProtocols()
|
||||
{
|
||||
return fProtocolMap.Items();
|
||||
}
|
||||
|
||||
|
||||
BPath*
|
||||
ProtocolManager::GetProtocolPath(BString signature)
|
||||
{
|
||||
return fAddonMap.ValueFor(signature);
|
||||
}
|
||||
|
||||
|
||||
BBitmap*
|
||||
ProtocolManager::GetProtocolIcon(BString signature)
|
||||
{
|
||||
BPath* path = fAddonMap.ValueFor(signature);
|
||||
return ReadNodeIcon(path->Path(), B_LARGE_ICON, true);
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright 2009, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef ProtocolManager_h
|
||||
#define ProtocolManager_h
|
||||
|
||||
#include <Directory.h>
|
||||
#include <Path.h>
|
||||
#include <String.h>
|
||||
|
||||
#include "KeyMap.h"
|
||||
#include "CayaProtocol.h"
|
||||
|
||||
class BBitmap;
|
||||
|
||||
class ProtocolManager
|
||||
{
|
||||
public:
|
||||
void Init(BDirectory protocolDir);
|
||||
static ProtocolManager* Get();
|
||||
|
||||
CayaProtocol* GetProtocol(BString signature);
|
||||
|
||||
BList* GetProtocols();
|
||||
|
||||
BPath* GetProtocolPath(BString signature);
|
||||
BBitmap* GetProtocolIcon(BString signature);
|
||||
|
||||
private:
|
||||
|
||||
ProtocolManager();
|
||||
|
||||
KeyMap<BString, CayaProtocol*> fProtocolMap;
|
||||
KeyMap<BString, BPath*> fAddonMap;
|
||||
};
|
||||
#endif
|
|
@ -0,0 +1,435 @@
|
|||
/*
|
||||
* Copyright 2009-2010, Pier Luigi Fiorini. All rights reserved.
|
||||
* Copyright 2003-2009, IM Kit Team. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Michael Davidson, slaad@bong.com.au
|
||||
* Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <CheckBox.h>
|
||||
#include <Directory.h>
|
||||
#include <File.h>
|
||||
#include <FindDirectory.h>
|
||||
#include <GroupLayout.h>
|
||||
#include <GroupLayoutBuilder.h>
|
||||
#include <Menu.h>
|
||||
#include <MenuItem.h>
|
||||
#include <MenuField.h>
|
||||
#include <Message.h>
|
||||
#include <Path.h>
|
||||
#include <PopUpMenu.h>
|
||||
#include <Resources.h>
|
||||
#include <ScrollView.h>
|
||||
#include <StringView.h>
|
||||
#include <TextControl.h>
|
||||
#include <TextView.h>
|
||||
#include <TypeConstants.h>
|
||||
|
||||
#include <libinterface/NotifyingTextView.h>
|
||||
|
||||
#include "CayaProtocol.h"
|
||||
#include "CayaResources.h"
|
||||
#include "ProtocolManager.h"
|
||||
#include "ProtocolSettings.h"
|
||||
|
||||
#define _T(str) (str)
|
||||
|
||||
const float kDividerWidth = 1.0f;
|
||||
|
||||
|
||||
ProtocolSettings::ProtocolSettings(CayaProtocol* cayap)
|
||||
: fProtocol(cayap),
|
||||
fTemplate(new BMessage()),
|
||||
fSettings(new BMessage())
|
||||
{
|
||||
_Init();
|
||||
}
|
||||
|
||||
|
||||
ProtocolSettings::~ProtocolSettings()
|
||||
{
|
||||
delete fTemplate;
|
||||
delete fSettings;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ProtocolSettings::InitCheck() const
|
||||
{
|
||||
return fStatus;
|
||||
}
|
||||
|
||||
|
||||
BList*
|
||||
ProtocolSettings::Accounts() const
|
||||
{
|
||||
BPath path;
|
||||
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK)
|
||||
return NULL;
|
||||
|
||||
path.Append("Caya/Protocols");
|
||||
path.Append(fProtocol->GetSignature());
|
||||
if (create_directory(path.Path(), 0755) != B_OK)
|
||||
return NULL;
|
||||
|
||||
BList* list = new BList();
|
||||
BDirectory dir(path.Path());
|
||||
BEntry entry;
|
||||
while (dir.GetNextEntry(&entry) == B_OK) {
|
||||
BFile file(&entry, B_READ_ONLY);
|
||||
BMessage msg;
|
||||
|
||||
if (msg.Unflatten(&file) == B_OK) {
|
||||
char buffer[B_PATH_NAME_LENGTH];
|
||||
if (entry.GetName(buffer) == B_OK) {
|
||||
BString* string = new BString(buffer);
|
||||
list->AddItem(string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ProtocolSettings::Load(const char* account)
|
||||
{
|
||||
status_t ret = B_ERROR;
|
||||
|
||||
// Find user's settings path
|
||||
BPath path;
|
||||
if ((ret = find_directory(B_USER_SETTINGS_DIRECTORY, &path)) != B_OK)
|
||||
return ret;
|
||||
|
||||
// Create path
|
||||
path.Append("Caya/Protocols");
|
||||
path.Append(fProtocol->GetSignature());
|
||||
if ((ret = create_directory(path.Path(), 0755)) != B_OK)
|
||||
return ret;
|
||||
|
||||
// Load settings file
|
||||
path.Append(account);
|
||||
BFile file(path.Path(), B_READ_ONLY);
|
||||
return fSettings->Unflatten(&file);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ProtocolSettings::Save(const char* account)
|
||||
{
|
||||
status_t ret = B_ERROR;
|
||||
|
||||
// Find user's settings path
|
||||
BPath path;
|
||||
if ((ret = find_directory(B_USER_SETTINGS_DIRECTORY, &path)) != B_OK)
|
||||
return ret;
|
||||
|
||||
// Create path
|
||||
path.Append("Caya/Protocols");
|
||||
path.Append(fProtocol->GetSignature());
|
||||
if ((ret = create_directory(path.Path(), 0755)) != B_OK)
|
||||
return ret;
|
||||
|
||||
// Load settings file
|
||||
path.Append(account);
|
||||
BFile file(path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_WRITE_ONLY);
|
||||
return fSettings->Flatten(&file);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ProtocolSettings::Delete(const char* account)
|
||||
{
|
||||
status_t ret = B_ERROR;
|
||||
|
||||
// Find user's settings path
|
||||
BPath path;
|
||||
if ((ret = find_directory(B_USER_SETTINGS_DIRECTORY, &path)) != B_OK)
|
||||
return ret;
|
||||
|
||||
// Create path
|
||||
path.Append("Caya/Protocols");
|
||||
path.Append(fProtocol->GetSignature());
|
||||
if ((ret = create_directory(path.Path(), 0755)) != B_OK)
|
||||
return ret;
|
||||
path.Append(account);
|
||||
|
||||
// Delete settings file
|
||||
BEntry entry(path.Path());
|
||||
if ((ret = entry.Remove()) != B_OK)
|
||||
return ret;
|
||||
|
||||
delete fSettings;
|
||||
fSettings = new BMessage();
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ProtocolSettings::BuildGUI(BView* parent)
|
||||
{
|
||||
if (!parent)
|
||||
debugger("Couldn't build protocol's settings GUI on a NULL parent!");
|
||||
|
||||
BMessage curr;
|
||||
float inset = ceilf(be_plain_font->Size() * 0.7f);
|
||||
|
||||
// Setup layout
|
||||
parent->SetLayout(new BGroupLayout(B_VERTICAL));
|
||||
BGroupLayoutBuilder layout(B_VERTICAL, inset);
|
||||
|
||||
for (int32 i = 0; fTemplate->FindMessage("setting", i, &curr) == B_OK; i++) {
|
||||
char temp[512];
|
||||
|
||||
// Get stuff from settings template
|
||||
const char* name = curr.FindString("name");
|
||||
const char* desc = curr.FindString("description");
|
||||
const char* value = NULL;
|
||||
int32 type = -1;
|
||||
bool secret = false;
|
||||
bool freeText = true;
|
||||
bool multiLine = false;
|
||||
BView* control = NULL;
|
||||
BMenu* menu = NULL;
|
||||
|
||||
// Ignore settings with errors
|
||||
if (curr.FindInt32("type", &type) != B_OK)
|
||||
continue;
|
||||
|
||||
switch (type) {
|
||||
case B_STRING_TYPE: {
|
||||
if (curr.FindString("valid_value")) {
|
||||
// It's a "select one of these" setting
|
||||
freeText = false;
|
||||
|
||||
menu = new BPopUpMenu(name);
|
||||
for (int j = 0; curr.FindString("valid_value", j); j++) {
|
||||
BMenuItem* item
|
||||
= new BMenuItem(curr.FindString("valid_value", j), NULL);
|
||||
menu->AddItem(item);
|
||||
}
|
||||
|
||||
value = fSettings->FindString(name);
|
||||
if (value)
|
||||
menu->FindItem(value)->SetMarked(true);
|
||||
} else {
|
||||
// It's a free-text setting
|
||||
if (curr.FindBool("multi_line", &multiLine) != B_OK)
|
||||
multiLine = false;
|
||||
|
||||
value = fSettings->FindString(name);
|
||||
if (!value)
|
||||
value = curr.FindString("default");
|
||||
|
||||
if (curr.FindBool("is_secret",&secret) != B_OK)
|
||||
secret = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case B_INT32_TYPE: {
|
||||
if (curr.FindInt32("valid_value")) {
|
||||
// It's a "select one of these" setting
|
||||
freeText = false;
|
||||
|
||||
menu = new BPopUpMenu(name);
|
||||
|
||||
int32 def = 0;
|
||||
status_t hasValue = fSettings->FindInt32(name, 0, &def);
|
||||
|
||||
if (hasValue != B_OK)
|
||||
hasValue = curr.FindInt32("default", 0, &def);
|
||||
|
||||
int32 v = 0;
|
||||
for (int32 j = 0; curr.FindInt32("valid_value", j, &v) == B_OK; j++) {
|
||||
sprintf(temp, "%ld", v);
|
||||
|
||||
BMenuItem* item = new BMenuItem(temp, NULL);
|
||||
|
||||
if (hasValue != B_OK && j == 0)
|
||||
item->SetMarked(true);
|
||||
else if ((hasValue == B_OK) && (def == v))
|
||||
item->SetMarked(true);
|
||||
|
||||
menu->AddItem(item);
|
||||
}
|
||||
} else {
|
||||
// It's a free-text (but number) setting
|
||||
int32 v = 0;
|
||||
|
||||
if (fSettings->FindInt32(name, &v) == B_OK) {
|
||||
sprintf(temp,"%ld", v);
|
||||
value = temp;
|
||||
} else if (curr.FindInt32("default", &v) == B_OK) {
|
||||
sprintf(temp,"%ld", v);
|
||||
value = temp;
|
||||
}
|
||||
|
||||
if (curr.FindBool("is_secret",&secret) != B_OK)
|
||||
secret = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case B_BOOL_TYPE: {
|
||||
bool active;
|
||||
|
||||
if (fSettings->FindBool(name, &active) != B_OK) {
|
||||
if (curr.FindBool("default", &active) != B_OK)
|
||||
active = false;
|
||||
}
|
||||
|
||||
control = new BCheckBox(name, _T(desc), NULL);
|
||||
if (active)
|
||||
dynamic_cast<BCheckBox*>(control)->SetValue(B_CONTROL_ON);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!value)
|
||||
value = "";
|
||||
|
||||
if (!control) {
|
||||
if (freeText) {
|
||||
if (!multiLine) {
|
||||
control = new BTextControl(name, _T(desc), value, NULL);
|
||||
if (secret) {
|
||||
dynamic_cast<BTextControl*>(control)->TextView()->HideTyping(true);
|
||||
dynamic_cast<BTextControl*>(control)->SetText(_T(value));
|
||||
}
|
||||
dynamic_cast<BTextControl*>(control)->SetDivider(kDividerWidth);
|
||||
} else {
|
||||
BStringView* label = new BStringView("NA", _T(desc), B_WILL_DRAW);
|
||||
layout.Add(label);
|
||||
|
||||
NotifyingTextView* textView
|
||||
= new NotifyingTextView(name);
|
||||
control = new BScrollView("NA", textView, 0, false, true);
|
||||
textView->SetText(_T(value));
|
||||
}
|
||||
} else {
|
||||
control = new BMenuField(name, _T(desc), menu);
|
||||
dynamic_cast<BMenuField*>(control)->SetDivider(kDividerWidth);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (curr.FindString("help"))
|
||||
gHelper.SetHelp(control, strdup(curr.FindString("help")));
|
||||
#endif
|
||||
|
||||
layout.Add(control);
|
||||
}
|
||||
|
||||
layout.AddGlue();
|
||||
parent->AddChild(layout);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ProtocolSettings::SaveGUI(BView* parent)
|
||||
{
|
||||
if (!parent)
|
||||
debugger("Couldn't save protocol's settings GUI on a NULL parent!");
|
||||
|
||||
BMessage cur;
|
||||
for (int32 i = 0; fTemplate->FindMessage("setting", i, &cur) == B_OK; i++) {
|
||||
const char* name = cur.FindString("name");
|
||||
|
||||
// Skip NULL names
|
||||
if (!name)
|
||||
continue;
|
||||
|
||||
int32 type = -1;
|
||||
if (cur.FindInt32("type", &type) != B_OK)
|
||||
continue;
|
||||
|
||||
BView* view = parent->FindView(name);
|
||||
if (!view)
|
||||
continue;
|
||||
|
||||
BTextControl* textControl
|
||||
= dynamic_cast<BTextControl*>(view);
|
||||
if (textControl) {
|
||||
switch (type) {
|
||||
case B_STRING_TYPE:
|
||||
fSettings->AddString(name, textControl->Text());
|
||||
break;
|
||||
case B_INT32_TYPE:
|
||||
fSettings->AddInt32(name, atoi(textControl->Text()));
|
||||
break;
|
||||
default:
|
||||
return B_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
BMenuField* menuField
|
||||
= dynamic_cast<BMenuField*>(view);
|
||||
if (menuField) {
|
||||
BMenuItem* item = menuField->Menu()->FindMarked();
|
||||
if (!item)
|
||||
return B_ERROR;
|
||||
|
||||
switch (type) {
|
||||
case B_STRING_TYPE:
|
||||
fSettings->AddString(name, item->Label());
|
||||
break;
|
||||
case B_INT32_TYPE:
|
||||
fSettings->AddInt32(name, atoi(item->Label()));
|
||||
break;
|
||||
default:
|
||||
return B_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
BCheckBox* checkBox
|
||||
= dynamic_cast<BCheckBox*>(view);
|
||||
if (checkBox)
|
||||
fSettings->AddBool(name, (checkBox->Value() == B_CONTROL_ON));
|
||||
|
||||
NotifyingTextView* textView
|
||||
= dynamic_cast<NotifyingTextView*>(view);
|
||||
if (textView)
|
||||
fSettings->AddString(name, textView->Text());
|
||||
}
|
||||
|
||||
fSettings->PrintToStream();
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ProtocolSettings::_Init()
|
||||
{
|
||||
// Find protocol add-on
|
||||
BPath* dllPath = ProtocolManager::Get()->GetProtocolPath(
|
||||
fProtocol->GetSignature());
|
||||
BFile file(dllPath->Path(), B_READ_ONLY);
|
||||
if (file.InitCheck() < B_OK) {
|
||||
fStatus = file.InitCheck();
|
||||
return;
|
||||
}
|
||||
|
||||
BResources resources(&file);
|
||||
if (resources.InitCheck() != B_OK) {
|
||||
fStatus = resources.InitCheck();
|
||||
return;
|
||||
}
|
||||
|
||||
size_t size;
|
||||
const void* data = resources.LoadResource(B_MESSAGE_TYPE,
|
||||
kProtocolSettingsTemplate, &size);
|
||||
if (!data) {
|
||||
fStatus = B_BAD_VALUE;
|
||||
return;
|
||||
}
|
||||
|
||||
// Load protocol's settings template
|
||||
fTemplate->Unflatten((const char*)data);
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright 2009-2010, Pier Luigi Fiorini. All rights reserved.
|
||||
* Copyright 2003-2009, IM Kit Team. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _PROTOCOL_SETTINGS_H
|
||||
#define _PROTOCOL_SETTINGS_H
|
||||
|
||||
class BMessage;
|
||||
class CayaProtocol;
|
||||
|
||||
class ProtocolSettings {
|
||||
public:
|
||||
ProtocolSettings(CayaProtocol* cayap);
|
||||
~ProtocolSettings();
|
||||
|
||||
status_t InitCheck() const;
|
||||
|
||||
BList* Accounts() const;
|
||||
|
||||
status_t Load(const char* account);
|
||||
status_t Save(const char* account);
|
||||
status_t Delete(const char* account);
|
||||
|
||||
void BuildGUI(BView* parent);
|
||||
status_t SaveGUI(BView* parent);
|
||||
|
||||
private:
|
||||
status_t fStatus;
|
||||
CayaProtocol* fProtocol;
|
||||
BString fAccount;
|
||||
BMessage* fTemplate;
|
||||
BMessage* fSettings;
|
||||
|
||||
void _Init();
|
||||
};
|
||||
|
||||
#endif // _PROTOCOL_SETTINGS_H
|
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
* Copyright 2009, Andrea Anzani. 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
|
||||
*/
|
||||
|
||||
#include <Application.h>
|
||||
#include <Entry.h>
|
||||
#include <Path.h>
|
||||
#include <TranslationUtils.h>
|
||||
|
||||
#include "AccountManager.h"
|
||||
#include "ImageCache.h"
|
||||
#include "LooperCayaProtocol.h"
|
||||
#include "ProtocolManager.h"
|
||||
#include "Server.h"
|
||||
#include "MainWindow.h"
|
||||
#include "RosterItem.h"
|
||||
#include "ChatWindow.h"
|
||||
#include <Debug.h>
|
||||
#include "Account.h"
|
||||
|
||||
Server::Server(MainWindow* mainWindow)
|
||||
: BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE)
|
||||
{
|
||||
CayaProtocol* pp = ProtocolManager::Get()->GetProtocol("gtalk");
|
||||
if (!pp)
|
||||
debugger("something wrong");
|
||||
|
||||
//FIXME: here just a first draft of the final design:
|
||||
|
||||
Account* gtalkAccount = new Account(mainWindow);
|
||||
|
||||
pp->Init(gtalkAccount);
|
||||
|
||||
fMainWindow = mainWindow;
|
||||
fProtocol = new LooperCayaProtocol(pp);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Server::Quit()
|
||||
{
|
||||
ContactLinker* linker = NULL;
|
||||
while ((linker = fRosterMap.ValueAt(0))) {
|
||||
linker->DeleteWindow();
|
||||
linker->DeletePopUp();
|
||||
fRosterMap.RemoveItemAt(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Server::Login()
|
||||
{
|
||||
BMessage* msg = new BMessage(IM_MESSAGE);
|
||||
msg->AddInt32("im_what", IM_SET_STATUS);
|
||||
msg->AddInt32("status", CAYA_ONLINE);
|
||||
fProtocol->PostMessage(msg);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Server::SendProtocolMessage(BMessage* msg)
|
||||
{
|
||||
if (msg != NULL)
|
||||
fProtocol->PostMessage(msg);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Server::UpdateSettings(BMessage settings)
|
||||
{
|
||||
fProtocol->Protocol()->UpdateSettings(settings);
|
||||
}
|
||||
|
||||
|
||||
filter_result
|
||||
Server::Filter(BMessage* message, BHandler **target)
|
||||
{
|
||||
filter_result result = B_DISPATCH_MESSAGE;
|
||||
|
||||
switch(message->what) {
|
||||
case IM_SERVER_BASED_CONTACT_LIST:
|
||||
{
|
||||
int i = 0;
|
||||
BString id;
|
||||
while (message->FindString("id", i++, &id) == B_OK) {
|
||||
bool found = false;
|
||||
ContactLinker* item = fRosterMap.ValueFor(id, &found);
|
||||
|
||||
if (!found) {
|
||||
item = new ContactLinker(id.String(), Looper());
|
||||
fRosterMap.AddItem(id, item);
|
||||
}
|
||||
}
|
||||
result = B_SKIP_MESSAGE;
|
||||
break;
|
||||
}
|
||||
case OPEN_WINDOW:
|
||||
{
|
||||
int index = message->FindInt32("index");
|
||||
RosterItem* ritem = fMainWindow->ItemAt(index);
|
||||
if (ritem != NULL)
|
||||
ritem->GetContactLinker()->ShowWindow();
|
||||
result = B_SKIP_MESSAGE;
|
||||
break;
|
||||
}
|
||||
case CLOSE_WINDOW:
|
||||
{
|
||||
BString id = message->FindString("id");
|
||||
if (id != "") {
|
||||
bool found = false;
|
||||
ContactLinker *item = fRosterMap.ValueFor(id, &found);
|
||||
|
||||
if (found)
|
||||
item->HideWindow();
|
||||
}
|
||||
result = B_SKIP_MESSAGE;
|
||||
break;
|
||||
}
|
||||
case IM_MESSAGE:
|
||||
result = ImMessage(message);
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
RosterMap
|
||||
Server::RosterItems() const
|
||||
{
|
||||
return fRosterMap;
|
||||
}
|
||||
|
||||
|
||||
RosterItem*
|
||||
Server::RosterItemForId(BString id)
|
||||
{
|
||||
bool found = false;
|
||||
ContactLinker* item = fRosterMap.ValueFor(id, &found);
|
||||
return item ? item->GetRosterItem() : NULL;
|
||||
}
|
||||
|
||||
|
||||
filter_result
|
||||
Server::ImMessage(BMessage* msg)
|
||||
{
|
||||
filter_result result = B_DISPATCH_MESSAGE;
|
||||
int32 im_what = msg->FindInt32("im_what");
|
||||
|
||||
switch (im_what) {
|
||||
case IM_STATUS_SET:
|
||||
{
|
||||
int32 status;
|
||||
const char* protocol;
|
||||
|
||||
if (msg->FindInt32("status", &status) != B_OK)
|
||||
return B_SKIP_MESSAGE;
|
||||
if (msg->FindString("protocol", &protocol) != B_OK)
|
||||
return B_SKIP_MESSAGE;
|
||||
|
||||
AccountManager* accountManager = AccountManager::Get();
|
||||
accountManager->SetStatus((CayaStatus)status);
|
||||
break;
|
||||
}
|
||||
case IM_STATUS_CHANGED:
|
||||
{
|
||||
int32 status;
|
||||
|
||||
if (msg->FindInt32("status", &status) != B_OK)
|
||||
return B_SKIP_MESSAGE;
|
||||
|
||||
ContactLinker* linker = EnsureContactLinker(msg->FindString("id"));
|
||||
linker->SetNotifyStatus((CayaStatus)status);
|
||||
linker->SetNotifyPersonalStatus(msg->FindString("message"));
|
||||
break;
|
||||
}
|
||||
case IM_CONTACT_INFO:
|
||||
{
|
||||
ContactLinker* linker = EnsureContactLinker(msg->FindString("id"));
|
||||
BString fullName = msg->FindString("nick");
|
||||
if (fullName != "")
|
||||
linker->SetNotifyName(fullName);
|
||||
break;
|
||||
}
|
||||
case IM_AVATAR_CHANGED:
|
||||
{
|
||||
ContactLinker* linker = EnsureContactLinker(msg->FindString("id"));
|
||||
entry_ref ref;
|
||||
if (linker) {
|
||||
if (msg->FindRef("ref", &ref) == B_OK) {
|
||||
//BPath fullPath(&ref);
|
||||
//BBitmap *bitmap = ImageCache::GetImage(BString(fullPath.Path()), BString(fullPath.Path()));
|
||||
BBitmap *bitmap = BTranslationUtils::GetBitmap(&ref);
|
||||
linker->SetNotifyAvatarBitmap(bitmap);
|
||||
} else
|
||||
linker->SetNotifyAvatarBitmap(NULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IM_SEND_MESSAGE:
|
||||
fProtocol->PostMessage(msg);
|
||||
break;
|
||||
case IM_MESSAGE_RECEIVED:
|
||||
{
|
||||
BString id = msg->FindString("id");
|
||||
if (id != "") {
|
||||
bool found = false;
|
||||
ContactLinker* item = fRosterMap.ValueFor(id, &found);
|
||||
if (found) {
|
||||
ChatWindow* win = item->GetChatWindow();
|
||||
item->ShowWindow();
|
||||
win->PostMessage(msg);
|
||||
}
|
||||
}
|
||||
result = B_SKIP_MESSAGE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
msg->PrintToStream();
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
ContactLinker*
|
||||
Server::EnsureContactLinker(BString id)
|
||||
{
|
||||
ContactLinker* item = NULL;
|
||||
if (id != "") {
|
||||
bool found = false;
|
||||
item = fRosterMap.ValueFor(id, &found);
|
||||
|
||||
if (!found) {
|
||||
item = new ContactLinker(id.String(), Looper());
|
||||
fRosterMap.AddItem(id, item);
|
||||
}
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
ContactLinker*
|
||||
Server::GetOwnContact()
|
||||
{
|
||||
return fMySelf;
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright 2009, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _SERVER_H
|
||||
#define _SERVER_H
|
||||
|
||||
#include <Message.h>
|
||||
#include <MessageFilter.h>
|
||||
|
||||
#include "CayaConstants.h"
|
||||
#include "ContactLinker.h"
|
||||
#include "KeyMap.h"
|
||||
|
||||
class MainWindow;
|
||||
class RosterItem;
|
||||
class LooperCayaProtocol;
|
||||
|
||||
typedef KeyMap<BString, ContactLinker*> RosterMap;
|
||||
|
||||
class Server: public BMessageFilter {
|
||||
public:
|
||||
Server(MainWindow* mainWindow);
|
||||
|
||||
virtual filter_result Filter(BMessage* message, BHandler** target);
|
||||
filter_result ImMessage(BMessage* msg);
|
||||
|
||||
void UpdateSettings(BMessage settings);
|
||||
|
||||
void Login();
|
||||
|
||||
void SendProtocolMessage(BMessage* msg);
|
||||
void SendChatMessage(BMessage* msg);
|
||||
|
||||
RosterMap RosterItems() const;
|
||||
RosterItem* RosterItemForId(BString id);
|
||||
|
||||
void Quit();
|
||||
|
||||
//TODO: there should be a contact for each account.
|
||||
ContactLinker* GetOwnContact();
|
||||
|
||||
private:
|
||||
ContactLinker* EnsureContactLinker(BString id);
|
||||
|
||||
RosterMap fRosterMap;
|
||||
MainWindow* fMainWindow;
|
||||
LooperCayaProtocol* fProtocol;
|
||||
ContactLinker* fMySelf;
|
||||
};
|
||||
|
||||
#endif // _SERVER_H
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright 2009, Andrea Anzani. 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
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Alert.h>
|
||||
#include <Path.h>
|
||||
#include <Roster.h>
|
||||
|
||||
#include "Caya.h"
|
||||
#include "TheApp.h"
|
||||
#include "FilePanel.h"
|
||||
#include "MainWindow.h"
|
||||
#include "Emoticor.h"
|
||||
#include "ProtocolManager.h"
|
||||
|
||||
|
||||
TheApp::TheApp()
|
||||
: BApplication(CAYA_SIGNATURE),
|
||||
fMainWin(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TheApp::ReadyToRun()
|
||||
{
|
||||
app_info theInfo;
|
||||
|
||||
if (be_app->GetAppInfo(&theInfo) == B_OK) {
|
||||
BPath applicationDirectory(&theInfo.ref);
|
||||
applicationDirectory.GetParent(&applicationDirectory);
|
||||
|
||||
BPath currentPath = applicationDirectory;
|
||||
currentPath.Append("smileys");
|
||||
currentPath.Append("settings.xml");
|
||||
BEntry entry(currentPath.Path());
|
||||
if (entry.Exists())
|
||||
Emoticor::Get()->LoadConfig(currentPath.Path());
|
||||
else {
|
||||
BString msg("Can't find smileys settings in:\n\n");
|
||||
msg << currentPath.Path();
|
||||
BAlert* alert = new BAlert("", msg.String(), "Ouch!");
|
||||
alert->Go();
|
||||
}
|
||||
printf("Loaded Emoticons settings from: %s\n", currentPath.Path());
|
||||
|
||||
currentPath = applicationDirectory;
|
||||
currentPath.Append("protocols");
|
||||
if (BEntry(currentPath.Path()).Exists()) {
|
||||
printf("Looking for protocols from: %s\n", currentPath.Path());
|
||||
ProtocolManager::Get()->Init(BDirectory(currentPath.Path()));
|
||||
} else {
|
||||
BString msg("Can't find protocols in:\n\n");
|
||||
msg << currentPath.Path();
|
||||
BAlert* alert = new BAlert("", msg.String(), "Ouch!");
|
||||
alert->Go();
|
||||
PostMessage(B_QUIT_REQUESTED);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fMainWin = new MainWindow();
|
||||
fMainWin->Show();
|
||||
}
|
||||
|
||||
|
||||
MainWindow*
|
||||
TheApp::GetMainWindow() const
|
||||
{
|
||||
return fMainWin;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright 2009, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _THE_APP_H
|
||||
#define _THE_APP_H
|
||||
|
||||
#include <Application.h>
|
||||
|
||||
#include "MainWindow.h"
|
||||
|
||||
class TheApp : public BApplication {
|
||||
public:
|
||||
TheApp();
|
||||
|
||||
void ReadyToRun();
|
||||
|
||||
MainWindow* GetMainWindow() const;
|
||||
|
||||
private:
|
||||
MainWindow* fMainWin;
|
||||
|
||||
};
|
||||
|
||||
#endif // _THE_APP_H
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright 2009, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Andrea Anzani, andrea.anzani@gmail.com
|
||||
*/
|
||||
|
||||
#include "WindowsManager.h"
|
||||
|
||||
WindowsManager* WindowsManager::fInstance = NULL;
|
||||
|
||||
WindowsManager::WindowsManager()
|
||||
{
|
||||
fCurrentPoint.Set(40.0f, 40.0f);
|
||||
}
|
||||
|
||||
|
||||
WindowsManager*
|
||||
WindowsManager::Get()
|
||||
{
|
||||
if (!fInstance)
|
||||
fInstance = new WindowsManager();
|
||||
|
||||
return fInstance;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WindowsManager::RelocateWindow(BWindow* window)
|
||||
{
|
||||
window->SetWorkspaces(B_CURRENT_WORKSPACE);
|
||||
window->MoveTo(fCurrentPoint);
|
||||
fCurrentPoint += BPoint(40.0f, 40.0f);
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright 2009, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _WINDOWS_MANAGER_H_
|
||||
#define _WINDOWS_MANAGER_H_
|
||||
|
||||
#include <Window.h>
|
||||
#include <Point.h>
|
||||
|
||||
class WindowsManager
|
||||
{
|
||||
public:
|
||||
static WindowsManager* Get();
|
||||
|
||||
void RelocateWindow(BWindow* window);
|
||||
|
||||
private:
|
||||
WindowsManager();
|
||||
|
||||
static WindowsManager* fInstance;
|
||||
BPoint fCurrentPoint;
|
||||
};
|
||||
|
||||
#endif // _WINDOWS_MANAGER_H_
|
|
@ -0,0 +1,95 @@
|
|||
|
||||
#include "Caya.h"
|
||||
#include "CayaResources.h"
|
||||
|
||||
resource app_signature CAYA_SIGNATURE;
|
||||
|
||||
resource app_version {
|
||||
major = 0,
|
||||
middle = 0,
|
||||
minor = 0,
|
||||
|
||||
variety = B_APPV_ALPHA,
|
||||
internal = 0,
|
||||
|
||||
short_info = "Caya",
|
||||
long_info = "©2009-2010 Andrea Anzani, Pier Luigi Fiorini"
|
||||
};
|
||||
|
||||
resource app_flags B_SINGLE_LAUNCH;
|
||||
|
||||
resource file_types message;
|
||||
|
||||
resource vector_icon {
|
||||
$"6E636966080501040046020106023E40000000000000003D4000494000470000"
|
||||
$"7EFFFFFFFFE5E1DA02000602000000BBC0004000000000009220244AF0000000"
|
||||
$"33CCFC3366FF02000602000000BA000040000000000092202448800000336699"
|
||||
$"FF6699CC02000602000000B9000040000000000092202448E00000CC0000FFFF"
|
||||
$"000002000602000000BA000040000000000092202448800000FF9900FFFBFF00"
|
||||
$"02000602000000BA000040000000000092202448800000006600FF00CC000A02"
|
||||
$"06C22622C7562239222E342E2B2E3D4146364441483C50404C3C504A444A4E55"
|
||||
$"44CBB634CBB83E5E2A0206C22622C7562239222E342E2B2E3D4146364441483C"
|
||||
$"50404C3C504C464A505744CBB634CBB83E5E2A02024C265928532A583B59335D"
|
||||
$"350610CAFFFEAF375335543B3B5A3B5A395D325D355D2C5D274F275627483241"
|
||||
$"2C413541BDA7C2A83942BDA7C2A8394A3F463F463C40324036402A40234F2346"
|
||||
$"2358325E2A5E395EBF5C5A3F5CBF5C5A3F544053080234313C310404FE372C37"
|
||||
$"393739373A393B383B3A3B3B393B3A3B390406FE0B4536403640363F363E383E"
|
||||
$"373E383E393E393E3A403B3F3B413B453A0405FE03453C453445344533433244"
|
||||
$"324332403240323F323E343E333E3408024D2C4D3C0803553C4F3655300D0A00"
|
||||
$"01001001178400040A020101000A010102000A0101032021210A010204053021"
|
||||
$"2101178200040A0102070630212101178200040A010108301D2101178200040A"
|
||||
$"0102090830212101178200040A030103000A040204051001178200040A050207"
|
||||
$"061001178200040A060108301C2001178200040A07020908100117820004"
|
||||
};
|
||||
|
||||
/*
|
||||
* Status icons
|
||||
*/
|
||||
|
||||
// Online
|
||||
resource(kOnlineIcon) #'VICN' array {
|
||||
$"6E63696601020104040050B96455B9D6BEA917932FFF2766210102044030C345"
|
||||
$"30BC3A30304030BC3A30C3454050BC3A50C34550504050C34550BC3A010A0001"
|
||||
$"0002408000000000000000408000C60000C60000"
|
||||
};
|
||||
|
||||
// Away
|
||||
resource(kAwayIcon) #'VICN' array {
|
||||
$"6E636966010201040400FFBA0055FFFFFFA9E8B732FFB891270102044030C345"
|
||||
$"30BC3A30304030BC3A30C3454050BC3A50C34550504050C34550BC3A010A0001"
|
||||
$"0002408000000000000000408000C60000C60000"
|
||||
};
|
||||
|
||||
// Busy
|
||||
resource(kBusyIcon) #'VICN' array {
|
||||
$"6E636966010201040400E9060655E1CECEA9C43A3AFF752F2F0102044030C345"
|
||||
$"30BC3A30304030BC3A30C3454050BC3A50C34550504050C34550BC3A010A0001"
|
||||
$"0002408000000000000000408000C60000C60000"
|
||||
};
|
||||
|
||||
// Offline
|
||||
resource(kOfflineIcon) #'VICN' array {
|
||||
$"6E63696601020104040000337F558B9097A92D3541FF0F12160102044030C345"
|
||||
$"30BC3A30304030BC3A30C3454050BC3A50C34550504050C34550BC3A010A0001"
|
||||
$"0002408000000000000000408000C60000C60000"
|
||||
};
|
||||
|
||||
// Search icon
|
||||
resource(kSearchIcon) #'VICN' array {
|
||||
$"6E6369660805010200060338D2F73CD163BF82B23B84A94B88504870C900FFEF"
|
||||
$"A5BDFFFCC0FFFFF890020106023E49240000000000003CAAAA4940004A3000FF"
|
||||
$"FFFCC07CF1B706040192020016023A55A6BAC2293F0DA33E958646C2EB47A1D6"
|
||||
$"0001FF9E020106023C00000000000000003C00004A30004A500000DCF4FFFF60"
|
||||
$"94AA02001603360FF5B7B2B23AD6A4392A794ABC0B4AF035FF55C285005005FF"
|
||||
$"0B0606AE0BB40BBF4D33C3AFB75DC173BDEFC607C13EC804CA28BD82C118B920"
|
||||
$"C51BBB40BF07B8083AB6BC0605AE02B57D3EB9B9C3EFB7BB44BBB751BD75C936"
|
||||
$"CA8EC1B1402F0A093B593D5BBFCDC93E455BC516C5F160465B435D4544510A04"
|
||||
$"5A425E3F5A3D574008022D40BE1B3108023042BF00BAD108023344BFB3BC1D08"
|
||||
$"023646C072BD750802264329440204423AC2BF3ABE583A384438BF2438C38B42"
|
||||
$"4EBE584EC2BF4E4C444CC38B4CBF240606BA0A4C51565B585AC91CCA4EC983C9"
|
||||
$"E959584F4E4B4D050A00010A12414992000000000000414992CA3294CA674701"
|
||||
$"178400040A06010A02414992000000000000414992CA3294CA67470A00010912"
|
||||
$"414992000000000000414992CA3294CA674701178400040A0501090241499200"
|
||||
$"0000000000414992CA3294CA67470A070109023D49920000000000003D49923A"
|
||||
$"DA753AC02E"
|
||||
};
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Copyright 2009-2010, Pier Luigi Fiorini. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
|
||||
*/
|
||||
|
||||
#include <View.h>
|
||||
|
||||
#include "AccountListItem.h"
|
||||
#include "CayaProtocol.h"
|
||||
#include "ProtocolSettings.h"
|
||||
|
||||
|
||||
AccountListItem::AccountListItem(CayaProtocol* cayap, const char* account)
|
||||
: BStringItem(account),
|
||||
fProtocol(cayap),
|
||||
fAccount(account),
|
||||
fBaselineOffset(0)
|
||||
{
|
||||
fSettings = new ProtocolSettings(cayap);
|
||||
fSettings->Load(account);
|
||||
}
|
||||
|
||||
|
||||
AccountListItem::~AccountListItem()
|
||||
{
|
||||
delete fSettings;
|
||||
}
|
||||
|
||||
|
||||
ProtocolSettings*
|
||||
AccountListItem::Settings() const
|
||||
{
|
||||
return fSettings;
|
||||
}
|
||||
|
||||
|
||||
CayaProtocol*
|
||||
AccountListItem::Protocol() const
|
||||
{
|
||||
return fProtocol;
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
AccountListItem::Account() const
|
||||
{
|
||||
return fAccount.String();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AccountListItem::DrawItem(BView* owner, BRect frame, bool complete)
|
||||
{
|
||||
rgb_color highColor = owner->HighColor();
|
||||
rgb_color lowColor = owner->LowColor();
|
||||
|
||||
// Draw selection
|
||||
if (IsSelected()) {
|
||||
rgb_color highlightColor = ui_color(B_CONTROL_HIGHLIGHT_COLOR);
|
||||
|
||||
owner->SetLowColor(highlightColor);
|
||||
owner->SetHighColor(highlightColor);
|
||||
owner->FillRect(frame);
|
||||
}
|
||||
|
||||
// Draw account name
|
||||
rgb_color textColor = ui_color(B_CONTROL_TEXT_COLOR);
|
||||
owner->MovePenTo(frame.left, frame.top + fBaselineOffset);
|
||||
if (!IsEnabled())
|
||||
owner->SetHighColor(tint_color(textColor, B_LIGHTEN_2_TINT));
|
||||
else
|
||||
owner->SetHighColor(textColor);
|
||||
owner->DrawString(Text());
|
||||
|
||||
owner->SetHighColor(highColor);
|
||||
owner->SetLowColor(lowColor);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AccountListItem::Update(BView* owner, const BFont* font)
|
||||
{
|
||||
if (Text())
|
||||
SetWidth(font->StringWidth(Text()));
|
||||
|
||||
font_height height;
|
||||
font->GetHeight(&height);
|
||||
|
||||
fBaselineOffset = 2 + ceilf(height.ascent + height.leading / 2);
|
||||
|
||||
SetHeight(ceilf(height.ascent) + ceilf(height.descent)
|
||||
+ ceilf(height.leading) + 4);
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright 2009-2010, Pier Luigi Fiorini. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _ACCOUNT_LIST_ITEM_H
|
||||
#define _ACCOUNT_LIST_ITEM_H
|
||||
|
||||
#include <String.h>
|
||||
#include <StringItem.h>
|
||||
|
||||
class CayaProtocol;
|
||||
class ProtocolSettings;
|
||||
|
||||
class AccountListItem : public BStringItem {
|
||||
public:
|
||||
AccountListItem(CayaProtocol* cayap,
|
||||
const char* account);
|
||||
virtual ~AccountListItem();
|
||||
|
||||
ProtocolSettings* Settings() const;
|
||||
CayaProtocol* Protocol() const;
|
||||
const char* Account() const;
|
||||
|
||||
void DrawItem(BView* owner, BRect frame,
|
||||
bool complete = false);
|
||||
|
||||
void Update(BView* owner, const BFont* font);
|
||||
|
||||
private:
|
||||
CayaProtocol* fProtocol;
|
||||
BString fAccount;
|
||||
ProtocolSettings* fSettings;
|
||||
float fBaselineOffset;
|
||||
};
|
||||
|
||||
#endif // _ACCOUNT_LIST_ITEM_H
|
|
@ -0,0 +1,300 @@
|
|||
/*
|
||||
* Copyright 2009-2010, Pier Luigi Fiorini. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
|
||||
*/
|
||||
|
||||
#include <Button.h>
|
||||
#include <ControlLook.h>
|
||||
#include <CheckBox.h>
|
||||
#include <GroupLayout.h>
|
||||
#include <GroupLayoutBuilder.h>
|
||||
#include <ListView.h>
|
||||
#include <Menu.h>
|
||||
#include <MenuField.h>
|
||||
#include <ScrollView.h>
|
||||
#include <TextControl.h>
|
||||
#include <Window.h>
|
||||
|
||||
#include <libinterface/BitmapMenuItem.h>
|
||||
#include <libinterface/Divider.h>
|
||||
#include <libinterface/NotifyingTextView.h>
|
||||
|
||||
#include "AccountListItem.h"
|
||||
#include "CayaProtocol.h"
|
||||
#include "PreferencesAccounts.h"
|
||||
#include "ProtocolManager.h"
|
||||
#include "ProtocolSettings.h"
|
||||
|
||||
const uint32 kAddAccount = 'ADAC';
|
||||
const uint32 kEditAccount = 'EDAC';
|
||||
const uint32 kDelAccount = 'DLAC';
|
||||
const uint32 kSelect = 'SELT';
|
||||
|
||||
const uint32 kCancel = 'CANC';
|
||||
const uint32 kOK = 'SAVE';
|
||||
const uint32 kChanged = 'CHGD';
|
||||
|
||||
|
||||
class AccountView : public BView {
|
||||
public:
|
||||
AccountView(const char* name)
|
||||
: BView(name, B_WILL_DRAW)
|
||||
{
|
||||
}
|
||||
|
||||
void AttachedToWindow()
|
||||
{
|
||||
// Once we are attached to window, the GUI is already created
|
||||
// so we can set our window as target for messages
|
||||
for (int32 i = 0; i < CountChildren(); i++) {
|
||||
BView* child = ChildAt(i);
|
||||
|
||||
BMenu* menu = dynamic_cast<BMenu*>(child);
|
||||
BMenuField* menuField
|
||||
= dynamic_cast<BMenuField*>(child);
|
||||
BTextControl* textControl
|
||||
= dynamic_cast<BTextControl*>(child);
|
||||
NotifyingTextView* textView
|
||||
= dynamic_cast<NotifyingTextView*>(child);
|
||||
BCheckBox* checkBox = dynamic_cast<BCheckBox*>(child);
|
||||
|
||||
if (menuField)
|
||||
menu = menuField->Menu();
|
||||
|
||||
if (menu) {
|
||||
for (int32 j = 0; j < menu->CountItems(); j++) {
|
||||
BMenuItem* item = menu->ItemAt(j);
|
||||
item->SetMessage(new BMessage(kChanged));
|
||||
item->SetTarget(Window());
|
||||
}
|
||||
|
||||
menu->SetTargetForItems(Window());
|
||||
}
|
||||
|
||||
if (textControl) {
|
||||
textControl->SetMessage(new BMessage(kChanged));
|
||||
textControl->SetTarget(Window());
|
||||
}
|
||||
|
||||
if (checkBox) {
|
||||
checkBox->SetMessage(new BMessage(kChanged));
|
||||
checkBox->SetTarget(Window());
|
||||
}
|
||||
|
||||
if (textView) {
|
||||
textView->SetMessage(new BMessage(kChanged));
|
||||
textView->SetTarget(Window());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class AccountDialog : public BWindow {
|
||||
public:
|
||||
AccountDialog(const char* title, CayaProtocol* cayap, const char* account = NULL)
|
||||
: BWindow(BRect(0, 0, 1, 1), title, B_MODAL_WINDOW, B_NOT_RESIZABLE |
|
||||
B_AUTO_UPDATE_SIZE_LIMITS | B_CLOSE_ON_ESCAPE)
|
||||
{
|
||||
fSettings = new ProtocolSettings(cayap);
|
||||
if (account)
|
||||
fSettings->Load(account);
|
||||
|
||||
fAccountName = new BTextControl("accountName", "Account name:", NULL, NULL);
|
||||
fAccountName->SetFont(be_bold_font);
|
||||
fAccountName->MakeFocus();
|
||||
if (account) {
|
||||
fAccountName->SetText(account);
|
||||
fAccountName->SetEnabled(false);
|
||||
}
|
||||
|
||||
Divider* divider = new Divider("divider", B_WILL_DRAW);
|
||||
|
||||
fTop = new AccountView("top");
|
||||
fSettings->BuildGUI(fTop);
|
||||
|
||||
BButton* cancel = new BButton("Cancel", new BMessage(kCancel));
|
||||
BButton* ok = new BButton("OK", new BMessage(kOK));
|
||||
|
||||
const float spacing = be_control_look->DefaultItemSpacing();
|
||||
|
||||
SetLayout(new BGroupLayout(B_VERTICAL, spacing));
|
||||
AddChild(BGroupLayoutBuilder(B_VERTICAL, spacing)
|
||||
.Add(fAccountName)
|
||||
.Add(divider)
|
||||
.Add(fTop)
|
||||
.AddGroup(B_HORIZONTAL, spacing)
|
||||
.AddGlue()
|
||||
.Add(cancel)
|
||||
.Add(ok)
|
||||
.End()
|
||||
.AddGlue()
|
||||
.SetInsets(spacing, spacing, spacing, 0)
|
||||
);
|
||||
|
||||
CenterOnScreen();
|
||||
}
|
||||
|
||||
void MessageReceived(BMessage* msg)
|
||||
{
|
||||
switch (msg->what) {
|
||||
case kOK:
|
||||
if (fSettings->SaveGUI(fTop) == B_OK)
|
||||
if (fSettings->Save(fAccountName->Text()) == B_OK)
|
||||
Close();
|
||||
// TODO: Error!
|
||||
break;
|
||||
case kCancel:
|
||||
Close();
|
||||
break;
|
||||
case kChanged:
|
||||
msg->PrintToStream();
|
||||
break;
|
||||
default:
|
||||
BWindow::MessageReceived(msg);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
ProtocolSettings* fSettings;
|
||||
AccountView* fTop;
|
||||
BTextControl* fAccountName;
|
||||
};
|
||||
|
||||
|
||||
PreferencesAccounts::PreferencesAccounts()
|
||||
: BView("Accounts", B_WILL_DRAW)
|
||||
{
|
||||
fListView = new BListView("accountsListView");
|
||||
fListView->SetInvocationMessage(new BMessage(kEditAccount));
|
||||
fListView->SetSelectionMessage(new BMessage(kSelect));
|
||||
|
||||
BScrollView* scrollView = new BScrollView("scrollView", fListView,
|
||||
B_WILL_DRAW, false, true);
|
||||
|
||||
BList* protocols = ProtocolManager::Get()->GetProtocols();
|
||||
|
||||
fProtosMenu = new BMenu("Add");
|
||||
for (int32 i = 0; i < protocols->CountItems(); i++) {
|
||||
CayaProtocol* cayap
|
||||
= reinterpret_cast<CayaProtocol*>(protocols->ItemAtFast(i));
|
||||
ProtocolSettings* settings = new ProtocolSettings(cayap);
|
||||
BList* accounts = settings->Accounts();
|
||||
|
||||
// Add accounts to list view
|
||||
for (int32 j = 0; j < accounts->CountItems(); j++) {
|
||||
BString* account = reinterpret_cast<BString*>(accounts->ItemAtFast(j));
|
||||
AccountListItem* listItem = new AccountListItem(cayap,
|
||||
account->String());
|
||||
fListView->AddItem(listItem);
|
||||
}
|
||||
|
||||
// Add menu items
|
||||
BMessage* msg = new BMessage(kAddAccount);
|
||||
msg->AddPointer("protocol", cayap);
|
||||
|
||||
BitmapMenuItem* item = new BitmapMenuItem(
|
||||
cayap->GetFriendlySignature(), msg,
|
||||
ProtocolManager::Get()->GetProtocolIcon(cayap->GetSignature()));
|
||||
fProtosMenu->AddItem(item);
|
||||
|
||||
delete accounts;
|
||||
delete settings;
|
||||
}
|
||||
|
||||
BMenuField* proto = new BMenuField("addAccountField", NULL, fProtosMenu);
|
||||
fDelButton = new BButton(" - ", new BMessage(kDelAccount));
|
||||
fEditButton = new BButton("Edit...", new BMessage(kEditAccount));
|
||||
fDelButton->SetEnabled(false);
|
||||
fEditButton->SetEnabled(false);
|
||||
|
||||
const float spacing = be_control_look->DefaultItemSpacing();
|
||||
|
||||
SetLayout(new BGroupLayout(B_HORIZONTAL, spacing));
|
||||
AddChild(BGroupLayoutBuilder(B_VERTICAL)
|
||||
.Add(scrollView)
|
||||
.AddGroup(B_HORIZONTAL, spacing)
|
||||
.Add(proto)
|
||||
.Add(fDelButton)
|
||||
.AddGlue()
|
||||
.Add(fEditButton)
|
||||
.End()
|
||||
.SetInsets(spacing, spacing, spacing, spacing)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PreferencesAccounts::AttachedToWindow()
|
||||
{
|
||||
fListView->SetTarget(this);
|
||||
fProtosMenu->SetTargetForItems(this);
|
||||
fDelButton->SetTarget(this);
|
||||
fEditButton->SetTarget(this);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PreferencesAccounts::MessageReceived(BMessage* msg)
|
||||
{
|
||||
switch (msg->what) {
|
||||
case kSelect: {
|
||||
int32 index;
|
||||
|
||||
if (msg->FindInt32("index", &index) == B_OK) {
|
||||
fDelButton->SetEnabled(index >= 0);
|
||||
fEditButton->SetEnabled(index >= 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case kAddAccount: {
|
||||
void *protocol = NULL;
|
||||
if (msg->FindPointer("protocol", &protocol) == B_OK) {
|
||||
CayaProtocol* cayap = (CayaProtocol*) protocol;
|
||||
|
||||
AccountDialog* dialog = new AccountDialog("Add account", cayap);
|
||||
dialog->Show();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kEditAccount: {
|
||||
for (int32 i = 0; i < fListView->CountItems(); i++) {
|
||||
int32 selected = fListView->CurrentSelection(i);
|
||||
if (selected < 0)
|
||||
continue;
|
||||
|
||||
AccountListItem* item
|
||||
= dynamic_cast<AccountListItem*>(fListView->ItemAt(selected));
|
||||
|
||||
CayaProtocol* cayap = item->Protocol();
|
||||
const char* account = item->Account();
|
||||
|
||||
AccountDialog* dialog = new AccountDialog("Edit account", cayap, account);
|
||||
dialog->Show();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kDelAccount: {
|
||||
for (int32 i = 0; i < fListView->CountItems(); i++) {
|
||||
int32 selected = fListView->CurrentSelection(i);
|
||||
if (selected < 0)
|
||||
continue;
|
||||
|
||||
AccountListItem* item
|
||||
= dynamic_cast<AccountListItem*>(fListView->ItemAt(selected));
|
||||
|
||||
const char* account = item->Account();
|
||||
ProtocolSettings* settings = item->Settings();
|
||||
if (settings->Delete(account) == B_OK)
|
||||
fListView->RemoveItem(item);
|
||||
delete settings;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
BView::MessageReceived(msg);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright 2009-2010, Pier Luigi Fiorini. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _PREFERENCES_ACCOUNTS_H
|
||||
#define _PREFERENCES_ACCOUNTS_H
|
||||
|
||||
#include <View.h>
|
||||
|
||||
class BListView;
|
||||
class BMenu;
|
||||
class BButton;
|
||||
|
||||
class PreferencesAccounts : public BView {
|
||||
public:
|
||||
PreferencesAccounts();
|
||||
|
||||
virtual void AttachedToWindow();
|
||||
virtual void MessageReceived(BMessage* msg);
|
||||
|
||||
private:
|
||||
BListView* fListView;
|
||||
BMenu* fProtosMenu;
|
||||
BButton* fDelButton;
|
||||
BButton* fEditButton;
|
||||
};
|
||||
|
||||
#endif // _PREFERENCES_ACCOUNTS_H
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright 2009-2010, Pier Luigi Fiorini. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
|
||||
*/
|
||||
|
||||
#include <Button.h>
|
||||
#include <ControlLook.h>
|
||||
#include <GroupLayout.h>
|
||||
#include <GroupLayoutBuilder.h>
|
||||
#include <TabView.h>
|
||||
|
||||
#include "PreferencesDialog.h"
|
||||
#include "PreferencesAccounts.h"
|
||||
|
||||
const int32 kOK = 'SAVE';
|
||||
|
||||
|
||||
PreferencesDialog::PreferencesDialog()
|
||||
: BWindow(BRect(0, 0, 400, 400), "Preferences", B_TITLED_WINDOW,
|
||||
B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_CLOSE_ON_ESCAPE)
|
||||
{
|
||||
BTabView* tabView = new BTabView("tabView", B_WIDTH_AS_USUAL);
|
||||
tabView->AddTab(new PreferencesAccounts());
|
||||
|
||||
BButton* ok = new BButton("OK", new BMessage(kOK));
|
||||
|
||||
const float spacing = be_control_look->DefaultItemSpacing();
|
||||
|
||||
SetLayout(new BGroupLayout(B_VERTICAL,
|
||||
be_control_look->DefaultItemSpacing()));
|
||||
AddChild(BGroupLayoutBuilder(B_VERTICAL)
|
||||
.Add(tabView)
|
||||
.AddGroup(B_HORIZONTAL)
|
||||
.AddGlue()
|
||||
.Add(ok)
|
||||
.SetInsets(spacing, spacing, 0, 0)
|
||||
.End()
|
||||
.SetInsets(spacing, spacing, spacing, spacing)
|
||||
);
|
||||
|
||||
CenterOnScreen();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PreferencesDialog::MessageReceived(BMessage* msg)
|
||||
{
|
||||
switch (msg->what) {
|
||||
case kOK:
|
||||
Close();
|
||||
break;
|
||||
default:
|
||||
BWindow::MessageReceived(msg);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright 2009-2010, Pier Luigi Fiorini. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _PREFERENCES_DIALOG_H
|
||||
#define _PREFERENCES_DIALOG_H
|
||||
|
||||
#include <Window.h>
|
||||
|
||||
class PreferencesDialog : public BWindow {
|
||||
public:
|
||||
PreferencesDialog();
|
||||
|
||||
virtual void MessageReceived(BMessage* msg);
|
||||
};
|
||||
|
||||
#endif // _PREFERENCES_DIALOG_H
|
|
@ -0,0 +1,93 @@
|
|||
#include "CayaRenderView.h"
|
||||
#include "Theme.h"
|
||||
#include "RunView.h"
|
||||
|
||||
CayaRenderView::CayaRenderView(const char *name, const char* smileyConfig) :
|
||||
RunView( BRect(0, 0, 1, 1), name, fTheme = new Theme(name, COL_MAX_COLORS + 1, COL_MAX_COLORS + 1, MAX_RENDERS + 1), B_FOLLOW_ALL, B_WILL_DRAW )
|
||||
{
|
||||
if (smileyConfig)
|
||||
Emoticor::Get()->LoadConfig(smileyConfig);
|
||||
|
||||
PrepareTheme(fTheme);
|
||||
|
||||
SetViewColor(245, 245, 245, 0);
|
||||
SetLowColor(245, 245, 245, 0);
|
||||
SetHighColor(0, 0, 0, 0);
|
||||
|
||||
|
||||
SetTimeStampFormat(NULL);
|
||||
if ( IsHidden() )
|
||||
Show();
|
||||
ScrollToBottom();
|
||||
}
|
||||
|
||||
void
|
||||
CayaRenderView::AppendOtherMessage(const char* message)
|
||||
{
|
||||
Append(fOtherNick.String(), COL_OTHERNICK, COL_OTHERNICK, R_TEXT);
|
||||
Append(": ", COL_OTHERNICK, COL_OTHERNICK, R_TEXT);
|
||||
AddEmoticText(message, COL_TEXT, R_TEXT, COL_TEXT,R_EMOTICON);
|
||||
Append("\n", COL_TEXT, COL_TEXT, R_TEXT);
|
||||
ScrollToSelection();
|
||||
}
|
||||
|
||||
void
|
||||
CayaRenderView::AppendOwnMessage(const char* message)
|
||||
{
|
||||
Append("You say: ", COL_OWNNICK, COL_OWNNICK, R_TEXT);
|
||||
AddEmoticText(message, COL_TEXT, R_TEXT,COL_TEXT,R_EMOTICON);
|
||||
Append("\n", COL_TEXT, COL_TEXT, R_TEXT);
|
||||
ScrollToSelection();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CayaRenderView::AddEmoticText(const char * txt, int16 cols , int16 font , int16 cols2 , int16 font2)
|
||||
{
|
||||
Emoticor::Get()->AddText(this, txt, cols, font, cols2, font2);
|
||||
}
|
||||
|
||||
void
|
||||
CayaRenderView::PrepareTheme(Theme *fTheme)
|
||||
{
|
||||
Theme::TimestampFore = COL_TIMESTAMP_DUMMY;
|
||||
Theme::TimestampBack = COL_TIMESTAMP_DUMMY;
|
||||
Theme::TimespaceFore = COL_MAX_COLORS;
|
||||
Theme::TimespaceBack = COL_MAX_COLORS;
|
||||
Theme::TimespaceFont = MAX_RENDERS;
|
||||
Theme::TimestampFont = R_TIMESTAMP_DUMMY;
|
||||
Theme::NormalFore = COL_TEXT;
|
||||
Theme::NormalBack = COL_TEXT;
|
||||
Theme::NormalFont = R_TEXT;
|
||||
Theme::SelectionBack = COL_SELECTION;
|
||||
|
||||
fTheme->WriteLock();
|
||||
fTheme->SetForeground(COL_URL, 5, 5, 150);
|
||||
fTheme->SetBackground(COL_URL, 255, 255, 255);
|
||||
|
||||
fTheme->SetForeground(COL_TIMESTAMP, 130, 130, 130);
|
||||
fTheme->SetBackground(COL_TIMESTAMP, 255, 255, 255);
|
||||
|
||||
fTheme->SetForeground(COL_TEXT, 0, 0, 0);
|
||||
fTheme->SetBackground(COL_TEXT, 255, 255, 255);
|
||||
|
||||
fTheme->SetForeground(COL_ACTION, 0, 0, 0);
|
||||
fTheme->SetBackground(COL_ACTION, 255, 255, 255);
|
||||
|
||||
fTheme->SetForeground(COL_SELECTION, 255, 255, 255);
|
||||
fTheme->SetBackground(COL_SELECTION, 0, 0, 0);
|
||||
|
||||
fTheme->SetForeground(COL_OWNNICK, 0, 0, 255);
|
||||
fTheme->SetBackground(COL_OWNNICK, 255, 255, 255);
|
||||
|
||||
fTheme->SetForeground(COL_OTHERNICK, 255, 0, 0);
|
||||
fTheme->SetBackground(COL_OTHERNICK, 255, 255, 255);
|
||||
|
||||
fTheme->SetTextRender(R_EMOTICON, &str);
|
||||
|
||||
fTheme->SetSoftLineIndent(5.0);
|
||||
fTheme->SetTextMargin(5.0);
|
||||
|
||||
fTheme->WriteUnlock();
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
#ifndef _CayaRenderView_H
|
||||
#define _CayaRenderView_H_
|
||||
|
||||
#include "RunView.h"
|
||||
#include "SmileTextRender.h"
|
||||
|
||||
class RunView;
|
||||
class Theme;
|
||||
|
||||
enum CayaRenderViewColors {
|
||||
COL_URL = 0,
|
||||
COL_TIMESTAMP,
|
||||
COL_TEXT,
|
||||
COL_OWNNICK,
|
||||
COL_OTHERNICK,
|
||||
COL_ACTION,
|
||||
COL_SELECTION,
|
||||
COL_TIMESTAMP_DUMMY,
|
||||
COL_MAX_COLORS
|
||||
};
|
||||
|
||||
enum {
|
||||
R_URL = 0,
|
||||
R_TEXT,
|
||||
R_TIMESTAMP,
|
||||
R_ACTION,
|
||||
R_EMOTICON,
|
||||
R_TIMESTAMP_DUMMY,
|
||||
MAX_RENDERS
|
||||
};
|
||||
|
||||
class CayaRenderView : public RunView
|
||||
{
|
||||
public:
|
||||
CayaRenderView(const char* name, const char* smileyConfig = NULL);
|
||||
|
||||
void AppendOtherMessage(const char* message);
|
||||
void AppendOwnMessage(const char* message);
|
||||
void AddEmoticText(const char * txt, int16 cols , int16 font , int16 cols2 , int16 font2);
|
||||
|
||||
void SetOwnNick(BString nick) { fOwnNick = nick; }
|
||||
void SetOtherNick(BString nick) { fOtherNick = nick; }
|
||||
|
||||
protected:
|
||||
void PrepareTheme(Theme* theme);
|
||||
|
||||
private:
|
||||
BString fOwnNick;
|
||||
BString fOtherNick;
|
||||
Theme* fTheme;
|
||||
SmileTextRender str;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Copyright 2009, Pier Luigi Fiorini. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
|
||||
*/
|
||||
|
||||
#include <GroupLayout.h>
|
||||
#include <GroupLayoutBuilder.h>
|
||||
#include <StringView.h>
|
||||
#include <TextControl.h>
|
||||
|
||||
#include "BitmapView.h"
|
||||
#include "ContactLinker.h"
|
||||
#include "ContactPopUp.h"
|
||||
#include "NotifyMessage.h"
|
||||
|
||||
const window_feel kMenuWindowFeel = window_feel(1025);
|
||||
|
||||
const int32 kNickChanged = 'NICH';
|
||||
|
||||
|
||||
ContactPopUp::ContactPopUp(ContactLinker* contact)
|
||||
: BWindow(BRect(0, 0, 1, 1), "ContactPopUp", B_BORDERED_WINDOW_LOOK,
|
||||
kMenuWindowFeel, B_NOT_MOVABLE | B_NOT_CLOSABLE | B_NOT_MINIMIZABLE |
|
||||
B_NOT_ZOOMABLE | B_NOT_RESIZABLE | B_ASYNCHRONOUS_CONTROLS |
|
||||
B_AVOID_FOCUS | B_AUTO_UPDATE_SIZE_LIMITS),
|
||||
fCoords(B_ORIGIN)
|
||||
{
|
||||
// Box to change nick name
|
||||
fNickBox = new BTextControl("nickBox", NULL, contact->GetName(),
|
||||
new BMessage(kNickChanged));
|
||||
|
||||
// Real nick name
|
||||
fLabel = new BStringView("label", contact->GetId());
|
||||
|
||||
// Avatar bitmap
|
||||
fAvatarView = new BitmapView("avatarView");
|
||||
fAvatarView->SetBitmap(contact->AvatarBitmap());
|
||||
|
||||
// Layout
|
||||
SetLayout(new BGroupLayout(B_VERTICAL));
|
||||
AddChild(BGroupLayoutBuilder(B_HORIZONTAL, 10)
|
||||
.AddGroup(B_VERTICAL)
|
||||
.Add(fNickBox)
|
||||
.Add(fLabel)
|
||||
.AddGlue()
|
||||
.End()
|
||||
.Add(fAvatarView)
|
||||
.SetInsets(10, 10, 10, 10)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ContactPopUp::MessageReceived(BMessage* msg)
|
||||
{
|
||||
switch (msg->what) {
|
||||
case kNickChanged:
|
||||
break;
|
||||
default:
|
||||
BWindow::MessageReceived(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ContactPopUp::MoveTo(BPoint where)
|
||||
{
|
||||
if (fCoords != where) {
|
||||
if (Lock()) {
|
||||
BWindow::MoveTo(where);
|
||||
fCoords = where;
|
||||
Unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ContactPopUp::ObserveString(int32 what, BString str)
|
||||
{
|
||||
switch (what) {
|
||||
case STR_CONTACT_NAME:
|
||||
if (Lock()) {
|
||||
fLabel->SetText(str);
|
||||
Unlock();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ContactPopUp::ObservePointer(int32 what, void* ptr)
|
||||
{
|
||||
switch (what) {
|
||||
case PTR_AVATAR_BITMAP:
|
||||
if (Lock()) {
|
||||
fAvatarView->SetBitmap((BBitmap*)ptr);
|
||||
Unlock();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ContactPopUp::ObserveInteger(int32 what, int32 val)
|
||||
{
|
||||
switch (what) {
|
||||
case INT_CONTACT_STATUS:
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright 2009, Pier Luigi Fiorini. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _CONTACT_POPUP_H
|
||||
#define _CONTACT_POPUP_H
|
||||
|
||||
#include <Window.h>
|
||||
|
||||
#include "Observer.h"
|
||||
|
||||
class BTextControl;
|
||||
class BStringView;
|
||||
|
||||
class BitmapView;
|
||||
class ContactLinker;
|
||||
|
||||
class ContactPopUp : public BWindow, public Observer {
|
||||
public:
|
||||
ContactPopUp(ContactLinker* contact);
|
||||
|
||||
virtual void MessageReceived(BMessage* msg);
|
||||
|
||||
void MoveTo(BPoint where);
|
||||
|
||||
protected:
|
||||
void ObserveString(int32 what, BString str);
|
||||
void ObservePointer(int32 what, void* ptr);
|
||||
void ObserveInteger(int32 what, int32 val);
|
||||
|
||||
private:
|
||||
BPoint fCoords;
|
||||
BTextControl* fNickBox;
|
||||
BStringView* fLabel;
|
||||
BitmapView* fAvatarView;
|
||||
};
|
||||
|
||||
#endif // _CONTACT_POPUP_H
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright 2009, Pier Luigi Fiorini. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
|
||||
*/
|
||||
|
||||
#include "NicknameTextControl.h"
|
||||
|
||||
|
||||
NicknameTextControl::NicknameTextControl(const char* name, BMessage* message)
|
||||
: BTextControl(name, NULL, NULL, message)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
NicknameTextControl::Draw(BRect updateRect)
|
||||
{
|
||||
BRect rect(Bounds());
|
||||
|
||||
SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
FillRect(rect);
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright 2009, Pier Luigi Fiorini. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _NICKNAME_TEXT_CONTROL_H
|
||||
#define _NICKNAME_TEXT_CONTROL_H
|
||||
|
||||
#include <TextControl.h>
|
||||
|
||||
class NicknameTextControl : public BTextControl {
|
||||
public:
|
||||
NicknameTextControl(const char* name, BMessage* message);
|
||||
|
||||
virtual void Draw(BRect updateRect);
|
||||
};
|
||||
|
||||
#endif // _NICKNAME_TEXT_CONTROL_H
|
|
@ -0,0 +1,182 @@
|
|||
/*
|
||||
* Copyright 2009, Andrea Anzani. 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
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <ListView.h>
|
||||
|
||||
#include "CayaUtils.h"
|
||||
#include "ContactLinker.h"
|
||||
#include "NotifyMessage.h"
|
||||
#include "RosterItem.h"
|
||||
|
||||
|
||||
RosterItem::RosterItem(const char* name, ContactLinker* contact)
|
||||
: BStringItem(name),
|
||||
fBitmap(NULL),
|
||||
fStatus(CAYA_OFFLINE),
|
||||
contactLinker(contact),
|
||||
fVisible(true)
|
||||
{
|
||||
rgb_color highlightColor = ui_color(B_CONTROL_HIGHLIGHT_COLOR);
|
||||
rgb_color darkenHighlightColor = tint_color(highlightColor, B_DARKEN_1_TINT);
|
||||
|
||||
fGradient.AddColor(highlightColor, 0);
|
||||
fGradient.AddColor(darkenHighlightColor, 255);
|
||||
}
|
||||
|
||||
|
||||
RosterItem::~RosterItem()
|
||||
{
|
||||
delete fBitmap;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RosterItem::SetVisible(bool visible)
|
||||
{
|
||||
fVisible = visible;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RosterItem::SetBitmap(BBitmap* bitmap)
|
||||
{
|
||||
if (fBitmap != NULL)
|
||||
delete fBitmap;
|
||||
fBitmap = bitmap;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RosterItem::ObserveString(int32 what, BString str)
|
||||
{
|
||||
switch (what) {
|
||||
case STR_CONTACT_NAME:
|
||||
SetText(str);
|
||||
break;
|
||||
case STR_PERSONAL_STATUS:
|
||||
SetPersonalStatus(str);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RosterItem::ObservePointer(int32 what, void* ptr)
|
||||
{
|
||||
switch (what) {
|
||||
case PTR_AVATAR_BITMAP:
|
||||
SetBitmap((BBitmap*)ptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RosterItem::ObserveInteger(int32 what, int32 val)
|
||||
{
|
||||
switch (what) {
|
||||
case INT_CONTACT_STATUS:
|
||||
SetStatus((CayaStatus)val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RosterItem::DrawItem(BView* owner, BRect frame, bool complete)
|
||||
{
|
||||
if (Text() == NULL)
|
||||
return;
|
||||
|
||||
rgb_color highlightColor = ui_color(B_CONTROL_HIGHLIGHT_COLOR);
|
||||
rgb_color highColor = owner->HighColor();
|
||||
rgb_color lowColor = owner->LowColor();
|
||||
|
||||
// Draw selection
|
||||
if (IsSelected()) {
|
||||
fGradient.SetStart(frame.LeftTop());
|
||||
fGradient.SetEnd(frame.LeftBottom());
|
||||
owner->SetLowColor(highlightColor);
|
||||
owner->FillRect(frame, fGradient);
|
||||
} else if (complete) {
|
||||
owner->SetHighColor(lowColor);
|
||||
owner->FillRect(frame);
|
||||
}
|
||||
|
||||
// Draw contact status
|
||||
switch (fStatus) {
|
||||
case CAYA_ONLINE:
|
||||
owner->SetHighColor(CAYA_GREEN_COLOR);
|
||||
break;
|
||||
case CAYA_EXTENDED_AWAY:
|
||||
case CAYA_AWAY:
|
||||
owner->SetHighColor(CAYA_ORANGE_COLOR);
|
||||
break;
|
||||
case CAYA_DO_NOT_DISTURB:
|
||||
owner->SetHighColor(CAYA_RED_COLOR);
|
||||
break;
|
||||
case CAYA_OFFLINE:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
owner->FillEllipse(BRect(frame.left + 6, frame.top + 6,
|
||||
frame.left + 6 + 7 , frame.top + 6 + 7));
|
||||
|
||||
// Draw contact name
|
||||
owner->MovePenTo(frame.left + 20, frame.top + myfBaselineOffset);
|
||||
owner->SetHighColor(ui_color(B_CONTROL_TEXT_COLOR));
|
||||
owner->DrawString(Text());
|
||||
|
||||
// Draw contact status string
|
||||
owner->MovePenTo(frame.left + 20, frame.top + myfBaselineOffset +
|
||||
myfBaselineOffset + 2);
|
||||
owner->SetHighColor(tint_color(lowColor, B_DARKEN_1_TINT));
|
||||
if (fPersonalStatus.Length() == 0)
|
||||
owner->DrawString(CayaStatusToString(fStatus));
|
||||
else
|
||||
owner->DrawString(fPersonalStatus);
|
||||
|
||||
// Draw separator between items
|
||||
owner->StrokeLine(BPoint(frame.left, frame.bottom), BPoint(frame.right, frame.bottom));
|
||||
|
||||
// Draw avatar icon
|
||||
if (fBitmap != NULL) {
|
||||
float h = frame.Height() - 4;
|
||||
BRect rect(frame.right - h - 2, frame.top + 2, frame.right - 2, frame.top + h );
|
||||
owner->SetDrawingMode(B_OP_ALPHA);
|
||||
owner->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
|
||||
owner->DrawBitmap(fBitmap, rect);
|
||||
}
|
||||
|
||||
owner->SetHighColor(highColor);
|
||||
owner->SetLowColor(lowColor);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RosterItem::Update(BView* owner, const BFont* font)
|
||||
{
|
||||
font_height fheight;
|
||||
font->GetHeight(&fheight);
|
||||
|
||||
myfBaselineOffset = 2 + ceilf(fheight.ascent + fheight.leading / 2);
|
||||
|
||||
SetHeight((ceilf(fheight.ascent) + ceilf(fheight.descent) +
|
||||
ceilf(fheight.leading) + 4 ) * 2);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RosterItem::SetStatus(CayaStatus status)
|
||||
{
|
||||
if (fStatus != status)
|
||||
fStatus = status;
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright 2009, Andrea Anzani. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _ROSTER_ITEM_H
|
||||
#define _ROSTER_ITEM_H
|
||||
|
||||
#include <Bitmap.h>
|
||||
#include <GradientLinear.h>
|
||||
#include <ListItem.h>
|
||||
#include <View.h>
|
||||
#include <String.h>
|
||||
|
||||
#include "CayaConstants.h"
|
||||
#include "ContactLinker.h"
|
||||
#include "Observer.h"
|
||||
|
||||
class RosterItem : public BStringItem, public Observer {
|
||||
public:
|
||||
RosterItem(const char* name, ContactLinker* contact);
|
||||
~RosterItem();
|
||||
|
||||
bool IsVisible() const { return fVisible; }
|
||||
void SetVisible(bool visible);
|
||||
|
||||
void DrawItem(BView *owner, BRect frame,
|
||||
bool complete = false);
|
||||
|
||||
void Update(BView *owner, const BFont *font);
|
||||
|
||||
ContactLinker* GetContactLinker() { return contactLinker;}
|
||||
|
||||
CayaStatus Status() const { return fStatus; }
|
||||
void SetStatus(CayaStatus status);
|
||||
|
||||
BString PersonalStatus() const { return fPersonalStatus; }
|
||||
void SetPersonalStatus(BString str) { fPersonalStatus = str; }
|
||||
|
||||
BBitmap* Bitmap() const { return fBitmap; }
|
||||
void SetBitmap(BBitmap *);
|
||||
|
||||
protected:
|
||||
void ObserveString(int32 what, BString str);
|
||||
void ObservePointer(int32 what, void* ptr);
|
||||
void ObserveInteger(int32 what, int32 val);
|
||||
|
||||
private:
|
||||
ContactLinker* contactLinker;
|
||||
float myfBaselineOffset;
|
||||
BString fPersonalStatus;
|
||||
CayaStatus fStatus;
|
||||
BBitmap* fBitmap;
|
||||
bool fVisible;
|
||||
BGradientLinear fGradient;
|
||||
};
|
||||
|
||||
#endif // _ROSTER_ITEM_H
|
|
@ -0,0 +1,173 @@
|
|||
/*
|
||||
* Copyright 2009, Pier Luigi Fiorini. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Looper.h>
|
||||
#include <MenuItem.h>
|
||||
#include <PopUpMenu.h>
|
||||
#include <SeparatorItem.h>
|
||||
|
||||
#include "ContactLinker.h"
|
||||
#include "RosterItem.h"
|
||||
#include "RosterListView.h"
|
||||
|
||||
const int32 kGetInfo = 'GINF';
|
||||
const int32 kShowLogs = 'SHLG';
|
||||
const int32 kAddPeople = 'ADPL';
|
||||
|
||||
|
||||
static int
|
||||
compare_by_name(const void* _item1, const void* _item2)
|
||||
{
|
||||
RosterItem* item1 = *(RosterItem**)_item1;
|
||||
RosterItem* item2 = *(RosterItem**)_item2;
|
||||
|
||||
return strcasecmp(item1->GetContactLinker()->GetName().String(),
|
||||
item2->GetContactLinker()->GetName().String());
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
compare_by_status(const void* _item1, const void* _item2)
|
||||
{
|
||||
RosterItem* item1 = *(RosterItem**)_item1;
|
||||
RosterItem* item2 = *(RosterItem**)_item2;
|
||||
|
||||
if (item1->Status() < item2->Status())
|
||||
return 1;
|
||||
if (item1->Status() > item2->Status())
|
||||
return 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
RosterListView::RosterListView(const char* name)
|
||||
: BListView(name, B_SINGLE_SELECTION_LIST, B_WILL_DRAW | B_FRAME_EVENTS |
|
||||
B_NAVIGABLE | B_FULL_UPDATE_ON_RESIZE),
|
||||
fPrevItem(NULL)
|
||||
{
|
||||
// Context menu
|
||||
fPopUp = new BPopUpMenu("contextMenu", false);
|
||||
fPopUp->AddItem(new BMenuItem("Get Information", new BMessage(kGetInfo)));
|
||||
fPopUp->AddItem(new BMenuItem("Show Logs", new BMessage(kShowLogs)));
|
||||
fPopUp->AddItem(new BSeparatorItem());
|
||||
fPopUp->AddItem(new BMenuItem("Add to Address Book",
|
||||
new BMessage(kAddPeople)));
|
||||
fPopUp->SetTargetForItems(this);
|
||||
}
|
||||
|
||||
|
||||
// #pragama mark -
|
||||
|
||||
|
||||
void
|
||||
RosterListView::MessageReceived(BMessage* msg)
|
||||
{
|
||||
switch (msg->what) {
|
||||
case kGetInfo:
|
||||
msg->PrintToStream();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RosterListView::MouseMoved(BPoint where, uint32 code, const BMessage* msg)
|
||||
{
|
||||
BListView::MouseMoved(where, code, msg);
|
||||
return;
|
||||
|
||||
switch (code) {
|
||||
case B_INSIDE_VIEW:
|
||||
{
|
||||
// Mouse cursor is inside this view, hide last item's popup
|
||||
// and show current item's popup
|
||||
BListItem* item = ItemAt(IndexOf(where));
|
||||
RosterItem* ritem = reinterpret_cast<RosterItem*>(item);
|
||||
|
||||
if (ritem == NULL)
|
||||
return;
|
||||
|
||||
// Hide previous item's popup
|
||||
if ((fPrevItem != NULL) && (fPrevItem != ritem))
|
||||
fPrevItem->GetContactLinker()->HidePopUp();
|
||||
|
||||
// Show current item's popup
|
||||
ritem->GetContactLinker()->ShowPopUp(ConvertToScreen(where));
|
||||
|
||||
// This will be the previous item
|
||||
fPrevItem = ritem;
|
||||
break;
|
||||
}
|
||||
case B_EXITED_VIEW:
|
||||
// Mouse cursor leaved this view, hide last item's popup
|
||||
if (fPrevItem != NULL)
|
||||
fPrevItem->GetContactLinker()->HidePopUp();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RosterListView::MouseDown(BPoint where)
|
||||
{
|
||||
BMessage* message = Looper()->CurrentMessage();
|
||||
|
||||
int32 buttons = 0;
|
||||
(void)message->FindInt32("buttons", &buttons);
|
||||
|
||||
if (buttons == B_SECONDARY_MOUSE_BUTTON) {
|
||||
int32 index = IndexOf(where);
|
||||
if (index >= 0) {
|
||||
// Select list item
|
||||
Select(index);
|
||||
|
||||
// Show context menu if right button is clicked
|
||||
(void)fPopUp->Go(ConvertToScreen(where), false, true, false);
|
||||
}
|
||||
} else
|
||||
// Call original MouseDown()
|
||||
BListView::MouseDown(where);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RosterListView::Draw(BRect updateRect)
|
||||
{
|
||||
int32 count = CountItems();
|
||||
if (count == 0)
|
||||
return;
|
||||
|
||||
BRect itemFrame(0, 0, Bounds().right, -1);
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
BListItem* item = ItemAt(i);
|
||||
RosterItem* rosterItem = reinterpret_cast<RosterItem*>(item);
|
||||
|
||||
if (!rosterItem->IsVisible())
|
||||
continue;
|
||||
|
||||
itemFrame.bottom = itemFrame.top + ceilf(item->Height()) - 1;
|
||||
|
||||
if (itemFrame.Intersects(updateRect))
|
||||
rosterItem->DrawItem(this, itemFrame);
|
||||
|
||||
itemFrame.top = itemFrame.bottom + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// #pragama mark -
|
||||
|
||||
|
||||
void
|
||||
RosterListView::Sort()
|
||||
{
|
||||
SortItems(compare_by_name);
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright 2009, Pier Luigi Fiorini. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _ROSTER_LIST_VIEW_H
|
||||
#define _ROSTER_LIST_VIEW_H
|
||||
|
||||
#include <ListView.h>
|
||||
|
||||
class BPopUpMenu;
|
||||
|
||||
class RosterItem;
|
||||
|
||||
class RosterListView : public BListView
|
||||
{
|
||||
public:
|
||||
RosterListView(const char* name);
|
||||
|
||||
virtual void MessageReceived(BMessage* msg);
|
||||
virtual void MouseMoved(BPoint where, uint32 code, const BMessage*);
|
||||
virtual void MouseDown(BPoint where);
|
||||
virtual void Draw(BRect updateRect);
|
||||
|
||||
void Sort();
|
||||
|
||||
private:
|
||||
BPopUpMenu* fPopUp;
|
||||
RosterItem* fPrevItem;
|
||||
};
|
||||
|
||||
#endif // _ROSTER_LIST_VIEW_H
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Copyright 2009, Pier Luigi Fiorini. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <Bitmap.h>
|
||||
#include <Menu.h>
|
||||
|
||||
#include <libinterface/BitmapUtils.h>
|
||||
|
||||
#include "CayaResources.h"
|
||||
#include "CayaUtils.h"
|
||||
#include "StatusMenuItem.h"
|
||||
|
||||
const float kSize = 16;
|
||||
const float kCircle = 12;
|
||||
|
||||
|
||||
StatusMenuItem::StatusMenuItem(const char* label, CayaStatus status,
|
||||
bool custom, char shortcut, uint32 modifiers)
|
||||
: BitmapMenuItem(label, NULL, NULL, shortcut, modifiers),
|
||||
fStatus(status),
|
||||
fCustom(custom)
|
||||
{
|
||||
BMessage* msg = new BMessage(kSetStatus);
|
||||
msg->AddInt32("status", fStatus);
|
||||
msg->AddBool("custom", fCustom);
|
||||
SetMessage(msg);
|
||||
|
||||
SetIcon();
|
||||
}
|
||||
|
||||
|
||||
CayaStatus
|
||||
StatusMenuItem::Status() const
|
||||
{
|
||||
return fStatus;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
StatusMenuItem::IsCustom() const
|
||||
{
|
||||
return fCustom;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StatusMenuItem::SetIcon()
|
||||
{
|
||||
image_info info;
|
||||
if (our_image(info) != B_OK)
|
||||
return;
|
||||
|
||||
BFile file(info.name, B_READ_ONLY);
|
||||
if (file.InitCheck() != B_OK)
|
||||
return;
|
||||
|
||||
BResources res(&file);
|
||||
if (res.InitCheck() != B_OK)
|
||||
return;
|
||||
|
||||
int32 num = 0;
|
||||
|
||||
switch (fStatus) {
|
||||
case CAYA_ONLINE:
|
||||
num = kOnlineIcon;
|
||||
break;
|
||||
case CAYA_EXTENDED_AWAY:
|
||||
case CAYA_AWAY:
|
||||
num = kAwayIcon;
|
||||
break;
|
||||
case CAYA_DO_NOT_DISTURB:
|
||||
num = kBusyIcon;
|
||||
break;
|
||||
case CAYA_OFFLINE:
|
||||
num = kOfflineIcon;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
BBitmap* bitmap = IconFromResources(&res, num, B_MINI_ICON);
|
||||
SetBitmap(bitmap);
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright 2009, Pier Luigi Fiorini. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _STATUS_MENU_ITEM_H
|
||||
#define _STATUS_MENU_ITEM_H
|
||||
|
||||
#include <MenuItem.h>
|
||||
|
||||
#include <libinterface/BitmapMenuItem.h>
|
||||
|
||||
#include "CayaConstants.h"
|
||||
|
||||
class BBitmap;
|
||||
|
||||
const int32 kSetStatus = 'SEST';
|
||||
|
||||
class StatusMenuItem : public BitmapMenuItem {
|
||||
public:
|
||||
StatusMenuItem(const char* label, CayaStatus status, bool custom = false,
|
||||
char shortcut = 0, uint32 modifiers = 0);
|
||||
|
||||
CayaStatus Status() const;
|
||||
bool IsCustom() const;
|
||||
|
||||
private:
|
||||
CayaStatus fStatus;
|
||||
bool fCustom;
|
||||
|
||||
void SetIcon();
|
||||
};
|
||||
|
||||
#endif // _STATUS_MENU_ITEM_H
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* Copyright 2009, Pier Luigi Fiorini. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
|
||||
*/
|
||||
|
||||
#include <Bitmap.h>
|
||||
#include <GroupLayout.h>
|
||||
#include <GroupLayoutBuilder.h>
|
||||
#include <Message.h>
|
||||
#include <MenuField.h>
|
||||
#include <MenuItem.h>
|
||||
#include <PopUpMenu.h>
|
||||
|
||||
#include <libinterface/BitmapMenuItem.h>
|
||||
|
||||
#include "AccountManager.h"
|
||||
#include "BitmapView.h"
|
||||
#include "CayaUtils.h"
|
||||
#include "NicknameTextControl.h"
|
||||
#include "StatusMenuItem.h"
|
||||
#include "StatusView.h"
|
||||
|
||||
const int32 kSetNickname = 'NICH';
|
||||
|
||||
|
||||
StatusView::StatusView(const char* name)
|
||||
: BView(name, B_WILL_DRAW)
|
||||
{
|
||||
// Nick name
|
||||
fNickname = new NicknameTextControl("nickname", new BMessage(kSetNickname));
|
||||
|
||||
// Status menu
|
||||
fStatusMenu = new BPopUpMenu("-");
|
||||
|
||||
// Add status menu items
|
||||
int32 s = CAYA_ONLINE;
|
||||
while (s >= CAYA_ONLINE && s < CAYA_STATUSES) {
|
||||
StatusMenuItem* item = new StatusMenuItem(CayaStatusToString(
|
||||
(CayaStatus)s), (CayaStatus)s);
|
||||
fStatusMenu->AddItem(item);
|
||||
|
||||
// Add items for custom messages
|
||||
if (s == CAYA_ONLINE || s == CAYA_DO_NOT_DISTURB) {
|
||||
item = new StatusMenuItem("Custom...", (CayaStatus)s, true);
|
||||
fStatusMenu->AddItem(item);
|
||||
fStatusMenu->AddItem(new BSeparatorItem());
|
||||
}
|
||||
|
||||
// Mark offline status by default
|
||||
if (s == CAYA_OFFLINE)
|
||||
item->SetMarked(true);
|
||||
|
||||
s++;
|
||||
}
|
||||
|
||||
// Menu field
|
||||
BMenuField* statusField = new BMenuField("statusField", NULL,
|
||||
fStatusMenu, NULL);
|
||||
|
||||
// Icon
|
||||
fAvatar = new BitmapView("icon");
|
||||
|
||||
// Set layout
|
||||
SetLayout(new BGroupLayout(B_VERTICAL));
|
||||
AddChild(BGroupLayoutBuilder(B_HORIZONTAL, 5)
|
||||
.AddGroup(B_VERTICAL)
|
||||
.Add(fNickname)
|
||||
.Add(statusField)
|
||||
.AddGlue()
|
||||
.End()
|
||||
.Add(fAvatar)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StatusView::AttachedToWindow()
|
||||
{
|
||||
fNickname->SetTarget(this);
|
||||
fStatusMenu->SetTargetForItems(this);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StatusView::MessageReceived(BMessage* msg)
|
||||
{
|
||||
switch (msg->what) {
|
||||
case kSetNickname:
|
||||
{
|
||||
AccountManager* accountManager = AccountManager::Get();
|
||||
accountManager->SetNickname(fNickname->Text());
|
||||
break;
|
||||
}
|
||||
case kSetStatus:
|
||||
{
|
||||
int32 status;
|
||||
|
||||
if (msg->FindInt32("status", &status) != B_OK)
|
||||
return;
|
||||
|
||||
AccountManager* accountManager = AccountManager::Get();
|
||||
accountManager->SetStatus((CayaStatus)status, "");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
BView::MessageReceived(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StatusView::SetName(BString name)
|
||||
{
|
||||
fNickname->SetText(name.String());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StatusView::SetStatus(CayaStatus status)
|
||||
{
|
||||
for (int32 i = 0; i < fStatusMenu->CountItems(); i++) {
|
||||
StatusMenuItem* item
|
||||
= reinterpret_cast<StatusMenuItem*>(fStatusMenu->ItemAt(i));
|
||||
if (item && item->Status() == status && !item->IsCustom())
|
||||
item->SetMarked(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StatusView::SetAvatar(BBitmap* bitmap)
|
||||
{
|
||||
BBitmap* b = RescaleBitmap(bitmap, 49, 49);
|
||||
fAvatar->SetBitmap(b);
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright 2009, Pier Luigi Fiorini. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _STATUS_VIEW_H
|
||||
#define _STATUS_VIEW_H
|
||||
|
||||
#include <View.h>
|
||||
|
||||
#include "CayaConstants.h"
|
||||
|
||||
class BPopUpMenu;
|
||||
|
||||
class BitmapView;
|
||||
class NicknameTextControl;
|
||||
|
||||
class StatusView : public BView {
|
||||
public:
|
||||
StatusView(const char* name);
|
||||
|
||||
virtual void AttachedToWindow();
|
||||
virtual void MessageReceived(BMessage* msg);
|
||||
|
||||
void SetName(BString name);
|
||||
void SetStatus(CayaStatus status);
|
||||
void SetAvatar(BBitmap* bitmap);
|
||||
|
||||
private:
|
||||
BPopUpMenu* fStatusMenu;
|
||||
NicknameTextControl* fNickname;
|
||||
BitmapView* fAvatar;
|
||||
};
|
||||
|
||||
#endif // _STATUS_VIEW_H
|
|
@ -0,0 +1,113 @@
|
|||
# BuildSettings
|
||||
#
|
||||
# Setup global variables.
|
||||
|
||||
# C and C++ flags
|
||||
if $(OSPLAT) = PPC {
|
||||
# filter out -nosyspath
|
||||
CFLAGS = [ FFilter $(CFLAGS) : -nosyspath ] ;
|
||||
C++FLAGS = [ FFilter $(C++FLAGS) : -nosyspath ] ;
|
||||
LINKFLAGS += -warn -export pragma ;
|
||||
}
|
||||
|
||||
# Use copyattr for copying.
|
||||
CP = copyattr --data ;
|
||||
|
||||
# Default paths for bison and flex:
|
||||
BISON = bison ;
|
||||
LEX = flex ;
|
||||
|
||||
# mkdir shall not fail, if the directory already exists.
|
||||
MKDIR = mkdir -p ;
|
||||
|
||||
# by default we do not strip and do not build tests:
|
||||
STRIP_APPS ?= 0 ;
|
||||
BUILD_TESTS ?= 0 ;
|
||||
|
||||
# Enable debugging by default
|
||||
DEBUG ?= 1 ;
|
||||
|
||||
rule SetUpSubDirBuildSettings
|
||||
{
|
||||
# SetUpSubDirBuildSettings <dir> ;
|
||||
#
|
||||
# Sets up the compiler flags and defines based on the WARNINGS, DEBUG, and
|
||||
# OPTIMIZE variables. Also sets the locations for the targets (objects,
|
||||
# libraries and executables).
|
||||
#
|
||||
# <dir>: Parameters as passed to the SubDir rule, i.e. the name of the
|
||||
# TOP variable and the subdir tokens.
|
||||
#
|
||||
local dir = $(1) ;
|
||||
|
||||
# warnings settings
|
||||
if $(WARNINGS) != 0 {
|
||||
if $(OSPLAT) = X86 {
|
||||
CCFLAGS += -Wall -Wno-multichar -Wpointer-arith
|
||||
-Wmissing-prototypes -Wcast-align -Wsign-compare ;
|
||||
C++FLAGS += -Wall -Wno-multichar -Wno-ctor-dtor-privacy -Woverloaded-virtual
|
||||
-Wconversion -Wpointer-arith -Wcast-align
|
||||
-Wsign-compare -Wno-reorder -Wno-unknown-pragmas ;
|
||||
} else {
|
||||
CCFLAGS += -w on -requireprotos ;
|
||||
}
|
||||
}
|
||||
|
||||
local gccString = ;
|
||||
if $(IS_GCC4_PLATFORM) {
|
||||
gccString += gcc4 ;
|
||||
} else {
|
||||
gccString += gcc2 ;
|
||||
}
|
||||
|
||||
local binModeString = ;
|
||||
if $(DEBUG) && $(DEBUG) != 0 {
|
||||
binModeString += debug ;
|
||||
} else {
|
||||
binModeString += release ;
|
||||
}
|
||||
|
||||
# debugging settings
|
||||
if $(DEBUG) && $(DEBUG) != 0 {
|
||||
OPTIMIZE = 0 ;
|
||||
STRIP_APPS = 0 ;
|
||||
DEFINES += DEBUG=$(DEBUG) BM_REF_DEBUGGING ;
|
||||
CCFLAGS += -g ;
|
||||
C++FLAGS += -g -fno-inline ;
|
||||
LINKFLAGS += -g ;
|
||||
}
|
||||
|
||||
DISTRO_DIR = [ FDirName $(TOP) generated distro-$(OS:L)-$(OSPLAT:L)-$(gccString)-$(binModeString) ] ;
|
||||
OBJECTS_DIR = [ FDirName $(TOP) generated objects-$(OS:L)-$(OSPLAT:L)-$(gccString)-$(binModeString) ] ;
|
||||
|
||||
# optimization settings
|
||||
if $(OPTIMIZE) = 0 {
|
||||
if $(OSPLAT) = X86 {
|
||||
OPTIM = -O0 ;
|
||||
} else {
|
||||
OPTIM = -O0 ;
|
||||
}
|
||||
} else {
|
||||
if $(OSPLAT) = X86 {
|
||||
OPTIM ?= -O3 -fstrict-aliasing ;
|
||||
} else {
|
||||
OPTIM ?= -O7 ;
|
||||
}
|
||||
}
|
||||
|
||||
# setup objects location
|
||||
local objdir = [ FDirName $(OBJECTS_DIR) $(dir[2-]) ] ;
|
||||
SEARCH_SOURCE += $(objdir) ;
|
||||
LOCATE_SOURCE = $(objdir) ;
|
||||
LOCATE_TARGET = $(objdir) ;
|
||||
|
||||
# setup main targets location
|
||||
LOCATE_MAIN_TARGET ?= [ FDirName $(DISTRO_DIR) ] ;
|
||||
}
|
||||
|
||||
# The LOCATE_MAIN_TARGET variable shall be reset for each subdirectory.
|
||||
AUTO_SET_UP_CONFIG_VARIABLES += LOCATE_MAIN_TARGET ;
|
||||
|
||||
# Add the rules setting up the build settings for a subdirectory to the
|
||||
# rules invoked by SubDir.
|
||||
SUBDIRRULES += SetUpSubDirBuildSettings ;
|
|
@ -0,0 +1,104 @@
|
|||
# CheckRules
|
||||
#
|
||||
# Common checks.
|
||||
|
||||
rule CheckGccPlatform
|
||||
{
|
||||
# CheckGccPlatform ;
|
||||
# Detects if we are using gcc4 and set IS_GCC4_PLATFORM according.
|
||||
|
||||
# First find out which gcc version the platform uses.
|
||||
IS_GCC4_PLATFORM = ;
|
||||
if $(OS) = HAIKU {
|
||||
# Only Haiku might use gcc 4. We use the existence of a libstdc++.r4.so in
|
||||
# /boot/develop/lib/x86 to judge whether this is a BeOS compatible and thus
|
||||
# gcc 2 platform. This is not entirely correct, but should be good enough
|
||||
# for the time being.
|
||||
local haveLibStdC++.R4 = [ Glob /boot/develop/lib/x86 : libstdc++.r4.so ] ;
|
||||
if ! $(haveLibStdC++.R4) {
|
||||
IS_GCC4_PLATFORM = 1 ;
|
||||
Echo Using GCC4 platform ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rule CheckOpenSSL
|
||||
{
|
||||
# CheckOpenSSL ;
|
||||
# Check for OpenSSL and defined HAVE_OPENSSL according, it also defines
|
||||
# OPENSSL_INCLUDE_DIR and OPENSSL_LIBRARY_DIR with location of respectively
|
||||
# include and library files.
|
||||
|
||||
HAVE_OPENSSL = ;
|
||||
OPENSSL_INCLUDE_DIR = ;
|
||||
OPENSSL_LIBRARY_DIR = ;
|
||||
|
||||
local haveHeaders = [ Glob $(COMMON_INCLUDE_DIRECTORY)/openssl : ssl.h ] ;
|
||||
if $(haveHeaders) {
|
||||
OPENSSL_INCLUDE_DIR = $(COMMON_INCLUDE_DIRECTORY)/openssl ;
|
||||
|
||||
local haveLibs = [ Glob $(COMMON_LIB_DIRECTORY) : libssl.so ] ;
|
||||
if $(haveLibs) {
|
||||
OPENSSL_LIBRARY_DIR = $(COMMON_LIB_DIRECTORY) ;
|
||||
|
||||
Echo OpenSSL Headers: $(OPENSSL_INCLUDE_DIR) ;
|
||||
Echo OpenSSL Libs: $(OPENSSL_LIBRARY_DIR) ;
|
||||
}
|
||||
|
||||
HAVE_OPENSSL = $(haveLibs) ;
|
||||
}
|
||||
}
|
||||
|
||||
rule CheckLibYahoo2
|
||||
{
|
||||
# CheckLibYahoo2
|
||||
# Check for LibYahoo2 and defined HAVE_LIBYAHOO2 according, it also defines
|
||||
# LIBYAHOO2_INCLUDE_DIR and LIBYAHOO2_LIBRARY_DIR with location of respectively
|
||||
# include and library files.
|
||||
|
||||
HAVE_LIBYAHOO2 = ;
|
||||
LIBYAHOO2_INCLUDE_DIR = ;
|
||||
LIBYAHOO2_LIBRARY_DIR = ;
|
||||
|
||||
local haveHeaders = [ Glob $(COMMON_INCLUDE_DIRECTORY)/libyahoo2 : yahoo2.h ] ;
|
||||
if $(haveHeaders) {
|
||||
LIBYAHOO2_INCLUDE_DIR = $(COMMON_INCLUDE_DIRECTORY)/libyahoo2 ;
|
||||
|
||||
local haveLibs = [ Glob $(COMMON_LIB_DIRECTORY) : libyahoo2.so ] ;
|
||||
if $(haveLibs) {
|
||||
LIBYAHOO2_LIBRARY_DIR = $(COMMON_LIB_DIRECTORY) ;
|
||||
|
||||
Echo Yahoo Headers: $(LIBYAHOO2_INCLUDE_DIR) ;
|
||||
Echo Yahoo Libs: $(LIBYAHOO2_LIBRARY_DIR) ;
|
||||
}
|
||||
|
||||
HAVE_LIBYAHOO2 = $(haveLibs) ;
|
||||
}
|
||||
}
|
||||
|
||||
rule CheckInfoPopper
|
||||
{
|
||||
# CheckInfoPopper
|
||||
# Check for InfoPopper and defined HAVE_INFOPOPPER according, it also defines
|
||||
# INFOPOPPER_INCLUDE_DIR and INFOPOPPER_LIBRARY_DIR with location of respectively
|
||||
# include and library files.
|
||||
|
||||
HAVE_INFOPOPPER = ;
|
||||
INFOPOPPER_INCLUDE_DIR = ;
|
||||
INFOPOPPER_LIBRARY_DIR = ;
|
||||
|
||||
local haveHeaders = [ Glob $(COMMON_INCLUDE_DIRECTORY)/infopopper : InfoPopper.h ] ;
|
||||
if $(haveHeaders) {
|
||||
INFOPOPPER_INCLUDE_DIR = $(COMMON_INCLUDE_DIRECTORY)/infopopper ;
|
||||
|
||||
local haveLibs = [ Glob $(COMMON_LIB_DIRECTORY) : libinfopopper.so ] ;
|
||||
if $(haveLibs) {
|
||||
INFOPOPPER_LIBRARY_DIR = $(COMMON_LIB_DIRECTORY) ;
|
||||
|
||||
Echo InfoPopper Headers: $(INFOPOPPER_INCLUDE_DIR) ;
|
||||
Echo InfoPopper Libs: $(INFOPOPPER_LIBRARY_DIR) ;
|
||||
}
|
||||
|
||||
HAVE_INFOPOPPER = $(haveLibs) ;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,146 @@
|
|||
# ConfigRules
|
||||
#
|
||||
# Contains rules providing the config variable feature. It allows to set the
|
||||
# values for certain variables for subdirectories in a central place. That is
|
||||
# one can, for instance, specify in a file like UserBuildConfig for which
|
||||
# directories to enable debugging, warnings, set special defines, compiler
|
||||
# flags and the like without needing to edit the Jamfiles for the respective
|
||||
# dirs.
|
||||
|
||||
rule ConfigObject
|
||||
{
|
||||
# ConfigObject <dir> ;
|
||||
#
|
||||
# Private rule. Returns the dummy object on which the config variables are
|
||||
# set for a given subdir.
|
||||
#
|
||||
# <dir>: Parameters as passed to the SubDir rule, i.e. the name of the
|
||||
# TOP variable and the subdir tokens.
|
||||
#
|
||||
local config = __config__ ;
|
||||
local grist = [ FGrist root $(1) ] ;
|
||||
return $(config:G=$(grist)) ;
|
||||
}
|
||||
|
||||
rule SetConfigVar
|
||||
{
|
||||
# SetConfigVar <var> : <dir> : <value> [ : <scope> ] ;
|
||||
#
|
||||
# Sets a config variable for a specified directory to the given value.
|
||||
#
|
||||
# <var>: The name of the variable to be set.
|
||||
# <dir>: Parameters as passed to the SubDir rule, i.e. the name of the
|
||||
# TOP variable and the subdir tokens.
|
||||
# <value>: The value to which the variable shall be set.
|
||||
# <scope>: Either "global" or "local". The former implies that the variable
|
||||
# value shall also be used for subdirectories (recursively), if
|
||||
# for them the variable has not been set. The latter has the same
|
||||
# effect regarding subdirs as if the variable for the directory
|
||||
# is not set. Defaults to "global".
|
||||
#
|
||||
local var = $(1[1]) ;
|
||||
local config = [ ConfigObject $(2) ] ;
|
||||
local scope = $(4) ;
|
||||
if ! $(scope) {
|
||||
scope = global ;
|
||||
}
|
||||
$(var) on $(config) = $(3) ;
|
||||
__set_$(var) on $(config) = $(scope) ;
|
||||
}
|
||||
|
||||
rule AppendToConfigVar
|
||||
{
|
||||
# AppendToConfigVar <var> : <dir> : <value> [ : <scope> ] ;
|
||||
#
|
||||
# Appends a value to a config variable for a specified directory. Shortcut
|
||||
# for
|
||||
# SetConfigVar <var> : <dir> : [ ConfigVar <var> : <dir> ] <value
|
||||
# : <scope> ;
|
||||
#
|
||||
# <var>: The name of the variable to be set.
|
||||
# <dir>: Parameters as passed to the SubDir rule, i.e. the name of the
|
||||
# TOP variable and the subdir tokens.
|
||||
# <value>: The value which to append to the variables current value.
|
||||
# <scope>: Either "global" or "local". The former implies that the variable
|
||||
# value shall also be used for subdirectories (recursively), if
|
||||
# for them the variable has not been set. The latter has the same
|
||||
# effect regarding subdirs as if the variable for the directory
|
||||
# is not set. Defaults to "global".
|
||||
#
|
||||
SetConfigVar $(1) : $(2) : [ ConfigVar $(1) : $(2) ] $(3) : $(4) ;
|
||||
}
|
||||
|
||||
rule ConfigVar
|
||||
{
|
||||
# ConfigVar <var> : <dir> [ : <scope> ] ;
|
||||
#
|
||||
# Returns the value of a configuration variable for a given subdir.
|
||||
# If the variable is not set for the subdir, the rule is invoked
|
||||
# recursively for the parent directory with the scope "global". When
|
||||
# the root is reached without yielding a value, the value of the global
|
||||
# variable <var> is returned.
|
||||
#
|
||||
# <var>: The name of the variable whose value shall be returned.
|
||||
# <dir>: Parameters as passed to the SubDir rule, i.e. the name of the
|
||||
# TOP variable and the subdir tokens.
|
||||
# <scope>: If not given any scope passed to SetConfigVar for the given
|
||||
# directory will be accepted, otherwise it must match the scope
|
||||
# passed to SetConfigVar.
|
||||
#
|
||||
local var = $(1[1]) ;
|
||||
local dir = $(2) ;
|
||||
local config = [ ConfigObject $(dir) ] ;
|
||||
local scope = $(3) ;
|
||||
local varScope = [ on $(config) return $(__set_$(var)) ] ;
|
||||
if ( ! $(scope) && $(varScope) )
|
||||
|| ( $(scope) && $(scope) = $(varScope) )
|
||||
|| ! $(dir) {
|
||||
on $(config) return $($(var)) ;
|
||||
} else {
|
||||
dir = [ FReverse $(dir) ] ;
|
||||
return [ ConfigVar $(var) : [ FReverse $(dir[2-]) ] : global ] ;
|
||||
}
|
||||
}
|
||||
|
||||
rule SetUpConfigVars {
|
||||
# SetUpConfigVars <dir> ;
|
||||
#
|
||||
# Sets the global variables defined in AUTO_SET_UP_CONFIG_VARIABLES to the
|
||||
# values specified for the subdirectory <dir>.
|
||||
#
|
||||
# <dir>: Parameters as passed to the SubDir rule, i.e. the name of the
|
||||
# TOP variable and the subdir tokens.
|
||||
#
|
||||
local dir = $(1) ;
|
||||
|
||||
# Backup the global variable value on first invocation, otherwise restore
|
||||
# them, so that ConfigVar returns the right values for not explicity set
|
||||
# local variables.
|
||||
local var ;
|
||||
if ! $(__config_var_backup__) {
|
||||
__config_var_backup__ = true ;
|
||||
for var in $(AUTO_SET_UP_CONFIG_VARIABLES) {
|
||||
__config_var_backup_$(var)__ = $($(var)) ;
|
||||
}
|
||||
} else {
|
||||
for var in $(AUTO_SET_UP_CONFIG_VARIABLES) {
|
||||
$(var) = $(__config_var_backup_$(var)__) ;
|
||||
}
|
||||
}
|
||||
|
||||
# Set the variables to their configured values.
|
||||
for var in $(AUTO_SET_UP_CONFIG_VARIABLES) {
|
||||
$(var) = [ ConfigVar $(var) : $(dir) ] ;
|
||||
}
|
||||
}
|
||||
|
||||
# Add the SetUpConfigVars rule to the rules that are invoked at the end of the
|
||||
# SubDir rule. Prepend it, so that the variables are set up before any other
|
||||
# rule is invoked.
|
||||
SUBDIRRULES = SetUpConfigVars $(SUBDIRRULES) ;
|
||||
|
||||
# Some config variables that should be set up automatically for subdirs.
|
||||
AUTO_SET_UP_CONFIG_VARIABLES +=
|
||||
CCFLAGS C++FLAGS DEBUG DEFINES HDRS LINKFLAGS OPTIM OPTIMIZE
|
||||
SYSHDRS WARNINGS
|
||||
;
|
|
@ -0,0 +1,35 @@
|
|||
# DistroRules
|
||||
#
|
||||
# Rules to archive binary distributions.
|
||||
|
||||
rule Distro
|
||||
{
|
||||
local target = $(1) ;
|
||||
|
||||
NotFile $(target) ;
|
||||
Always $(target) ;
|
||||
}
|
||||
|
||||
actions Distro
|
||||
{
|
||||
echo "== Making distro $(DISTRO_DIR) ==" ;
|
||||
mimeset $(DISTRO_DIR) ;
|
||||
}
|
||||
|
||||
Depends fulldistro : distro ;
|
||||
|
||||
rule FullDistro
|
||||
{
|
||||
local target = $(1) ;
|
||||
|
||||
NotFile $(target) ;
|
||||
Always $(target) ;
|
||||
}
|
||||
|
||||
actions FullDistro
|
||||
{
|
||||
echo "== Making full distro $(FULL_DISTRO_DIR) ==" ;
|
||||
rm -rf $(FULL_DISTRO_DIR) ;
|
||||
cp -a $(DISTRO_DIR) $(FULL_DISTRO_DIR) ;
|
||||
mimeset $(FULL_DISTRO_DIR) ;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
# FileRules
|
||||
#
|
||||
# Rules for files and symbolic links.
|
||||
|
||||
rule SymLink
|
||||
{
|
||||
# SymLink <target> : <source> : <makeDefaultDependencies> ;
|
||||
# Links <target> to <source>.
|
||||
# <source> is the exact link contents. No binding is done.
|
||||
# <makeDefaultDependencies> If true, <target> will be made a dependency
|
||||
# of the `all' pseudo target, i.e. it will be made by default, and removed
|
||||
# on `jam clean'.
|
||||
|
||||
local target = $(1) ;
|
||||
local source = $(2) ;
|
||||
local makeDefaultDependencies = $(3) ;
|
||||
if ! $(makeDefaultDependencies) {
|
||||
makeDefaultDependencies = true ;
|
||||
}
|
||||
LINKCONTENTS on $(target) = $(source) ;
|
||||
SymLink1 $(target) ;
|
||||
if $(makeDefaultDependencies) = true {
|
||||
LocalDepends files : $(target) ;
|
||||
LocalClean clean : $(target) ;
|
||||
}
|
||||
}
|
||||
|
||||
actions SymLink1
|
||||
{
|
||||
$(RM) "$(1)" && $(LN) -s "$(LINKCONTENTS)" "$(1)"
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
# HelperRules
|
||||
#
|
||||
# Helper rules without side effects.
|
||||
|
||||
rule FFilter
|
||||
{
|
||||
# FFilter <list> : <excludes> ;
|
||||
#
|
||||
# Removes all occurrences of <excludes> in <list>.
|
||||
|
||||
local list = $(1) ;
|
||||
local excludes = $(2) ;
|
||||
local newList ;
|
||||
local item ;
|
||||
for item in $(list) {
|
||||
local skip ;
|
||||
local exclude ;
|
||||
for exclude in $(excludes) {
|
||||
if $(item) = $(exclude) {
|
||||
skip = true ;
|
||||
}
|
||||
}
|
||||
if ! $(skip) {
|
||||
newList += $(item) ;
|
||||
}
|
||||
}
|
||||
return $(newList) ;
|
||||
}
|
||||
|
||||
rule FSplitPath
|
||||
{
|
||||
# FSplitPath <path> ;
|
||||
#
|
||||
# Decomposes a path into its components.
|
||||
#
|
||||
# <path>: The path to be decomposed.
|
||||
#
|
||||
local path = $(1:G=) ;
|
||||
|
||||
local components ;
|
||||
# $(path:D) for "/" is "/". Therefore the second condition.
|
||||
while $(path:D) && $(path:D) != $(path)
|
||||
{
|
||||
# Note: $(path:B) returns "." for "..", but $(path:D=) is fine.
|
||||
components = $(path:D=) $(components) ;
|
||||
path = $(path:D) ;
|
||||
}
|
||||
components = $(components) ;
|
||||
# Use this to return initial /
|
||||
#components = $(path) $(components) ;
|
||||
return $(components) ;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
# InstallRules
|
||||
#
|
||||
# Missing rules for installation.
|
||||
|
||||
rule InstallSymLink
|
||||
{
|
||||
# InstallSymlink linkname : source ;
|
||||
|
||||
LocalDepends install : $(>) ;
|
||||
LocalDepends install : $(<) ;
|
||||
LocalClean uninstall : $(<) ;
|
||||
|
||||
NoCare $(>) ;
|
||||
InstallSymLink1 $(<) : $(>) ;
|
||||
}
|
||||
|
||||
actions InstallSymLink1
|
||||
{
|
||||
$(RM) $(<) && $(LN) -s $(>) $(<)
|
||||
}
|
||||
|
||||
rule UninstallTarget
|
||||
{
|
||||
# UninstallTarget target ;
|
||||
|
||||
LocalClean uninstall : $(<) ;
|
||||
}
|
|
@ -0,0 +1,380 @@
|
|||
# MainBuildRules
|
||||
#
|
||||
# Rules that specify what to build and how to do it.
|
||||
|
||||
rule AddResources
|
||||
{
|
||||
# AddResources <name> : <resourcefiles> ;
|
||||
#
|
||||
# Adds resources to the application.
|
||||
#
|
||||
# <name>: Name of the application.
|
||||
# <resourcefiles>: List of resource files. Grist will be set.
|
||||
#
|
||||
local resfiles ;
|
||||
local file ;
|
||||
for file in $(2) {
|
||||
if ! $(file:G) {
|
||||
file = [ FGristFiles $(file) ] ;
|
||||
}
|
||||
resfiles += $(file) ;
|
||||
}
|
||||
|
||||
SEARCH on $(resfile) += $(SEARCH_SOURCE) ;
|
||||
|
||||
for file in $(resfiles) {
|
||||
if $(file:S) = .rdef {
|
||||
local rdef = $(file) ;
|
||||
file = $(rdef:S=.rsrc) ;
|
||||
ResComp $(file) : $(rdef) ;
|
||||
}
|
||||
RESFILES on $(1) += $(file) ;
|
||||
}
|
||||
}
|
||||
|
||||
rule Application
|
||||
{
|
||||
# Application <name> : <sources> : <libraries> : <res> ;
|
||||
#
|
||||
# Creates an application from sources.
|
||||
#
|
||||
# <name>: Name of the application. Grist is allowed.
|
||||
# <sources>: List of source files. Grist will be set.
|
||||
# <libraries>: List of libraries to link against.
|
||||
# <res>: List of resource files. Grist will be set.
|
||||
#
|
||||
local app = $(1) ;
|
||||
local sources = $(2) ;
|
||||
local libs = $(3) ;
|
||||
local res = $(4) ;
|
||||
|
||||
AddResources $(app) : $(res) ;
|
||||
Main $(app) : $(sources) ;
|
||||
MakeLocate $(app) : $(LOCATE_MAIN_TARGET) ;
|
||||
LinkAgainst $(app) : $(libs) ;
|
||||
}
|
||||
|
||||
actions Strip
|
||||
{
|
||||
strip "$(1)" ;
|
||||
}
|
||||
|
||||
rule AddOn
|
||||
{
|
||||
# AddOn <name> : <sources> : <libraries> : <res> ;
|
||||
#
|
||||
# Creates an add-on from sources.
|
||||
#
|
||||
# <name>: Name of the add-on. Grist is allowed.
|
||||
# <sources>: List of source files. Grist will be set.
|
||||
# <libraries>: List of libraries to link against.
|
||||
# <res>: List of resource files. Grist will be set.
|
||||
#
|
||||
SharedLibrary $(1) : $(2) : $(3) : $(4) ;
|
||||
}
|
||||
|
||||
rule SharedLibrary
|
||||
{
|
||||
# SharedLibrary <name> : <sources> : <libraries> : <res> ;
|
||||
#
|
||||
# Creates a shared library from sources.
|
||||
#
|
||||
# <name>: Name of the shared library. Grist is allowed.
|
||||
# <sources>: List of source files. Grist will be set.
|
||||
# <libraries>: List of libraries to link against.
|
||||
# <res>: List of resource files. Grist will be set.
|
||||
#
|
||||
local lib = $(1) ;
|
||||
local sources = $(2) ;
|
||||
local libs = $(3) ;
|
||||
local res = $(4) ;
|
||||
|
||||
AddResources $(lib) : $(res) ;
|
||||
Main $(lib) : $(sources) ;
|
||||
MakeLocate $(lib) : $(LOCATE_MAIN_TARGET) ;
|
||||
local linkFlags ;
|
||||
if $(OSPLAT) = X86 {
|
||||
linkFlags = -nostart -Xlinker -soname=\"$(lib)\" -Xlinker --no-undefined ;
|
||||
} else {
|
||||
linkFlags = -xms ;
|
||||
}
|
||||
LINKFLAGS on $(lib) = [ on $(lib) return $(LINKFLAGS) ] $(linkFlags) ;
|
||||
LinkAgainst $(lib) : $(libs) ;
|
||||
}
|
||||
|
||||
rule StaticLibrary
|
||||
{
|
||||
# StaticLibrary <name> : <sources> ;
|
||||
#
|
||||
# Creates a static library from sources.
|
||||
#
|
||||
# <name>: Name of the static library. Grist is allowed.
|
||||
# <source>: List of source files. Grist will be set.
|
||||
#
|
||||
local lib = $(1) ;
|
||||
Library $(lib) : $(2) ;
|
||||
MakeLocate $(lib) : $(LOCATE_MAIN_TARGET) ;
|
||||
|
||||
# If KEEPOBJS is set, Library doesn't make the library depend on `lib'.
|
||||
if $(KEEPOBJS) {
|
||||
Depends lib : $(lib) ;
|
||||
}
|
||||
}
|
||||
|
||||
rule LinkAgainst
|
||||
{
|
||||
# LinkAgainst <name> : <libs> ;
|
||||
#
|
||||
# Adds libraries to the list of libraries a (Main) target shall be linked
|
||||
# against.
|
||||
#
|
||||
# <name>: The name of the target for which to add libraries.
|
||||
# <libs>: The libraries (actually arbitrary shared objects and static
|
||||
# libraries) to be added. Valid elements are e.g. "be" or
|
||||
# "libopenbeos.so" or "/boot/.../libfoo.so". If the basename starts
|
||||
# with "lib" or the thingy has a dirname or grist, it is added to
|
||||
# the NEEDLIBS variable (i.e. the file will be bound!), otherwise
|
||||
# it is prefixed "-l" and added to LINKLIBS. If you want to specify
|
||||
# a target that isn't a library and also has neither grist nor a
|
||||
# dirname, you can prepend "<nogrist>" as grist; it will be
|
||||
# stripped by this rule.
|
||||
#
|
||||
for i in $(>)
|
||||
{
|
||||
local isfile = ;
|
||||
if $(i:D) || $(i:G) {
|
||||
isfile = true ;
|
||||
if $(i:G) = <nogrist> {
|
||||
i = $(i:G=) ;
|
||||
}
|
||||
} else {
|
||||
switch $(i:B)
|
||||
{
|
||||
# XXX: _APP_ and _KERNEL_ should not be needed for ELF.
|
||||
case _APP_ : isfile = true ;
|
||||
case _KERNEL_ : isfile = true ;
|
||||
case lib* : isfile = true ;
|
||||
case * : isfile = ;
|
||||
}
|
||||
if ! $(isfile) && ( $(i:S) = .so || $(i:S) = .o || $(i:S) = .a ) {
|
||||
isfile = true ;
|
||||
}
|
||||
}
|
||||
if $(isfile) {
|
||||
NEEDLIBS on $(1) = [ on $(1) return $(NEEDLIBS) ] $(i) ;
|
||||
Depends $(1) : $(i) ;
|
||||
} else {
|
||||
LINKLIBS on $(1) = [ on $(1) return $(LINKLIBS) ] -l$(i) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rule XRes
|
||||
{
|
||||
# XRes <target> : <resource files> ;
|
||||
#
|
||||
# Adds resources to a file.
|
||||
#
|
||||
# <target>: The files to which resources shall be added.
|
||||
# <resource files>: The resource files.
|
||||
#
|
||||
if $(2)
|
||||
{
|
||||
Depends $(1) : $(2) ;
|
||||
XRes1 $(1) : $(2) ;
|
||||
}
|
||||
}
|
||||
|
||||
rule ResComp
|
||||
{
|
||||
# ResComp <resource file> : <rdef file> ;
|
||||
#
|
||||
# Creates a binary resource file from a rdef script.
|
||||
#
|
||||
# <resource file>: The resource file. Grist is required.
|
||||
# <rdef file>: The rdef script. Grist is required.
|
||||
#
|
||||
local defines ;
|
||||
|
||||
on $(1) {
|
||||
defines = $(DEFINES) ;
|
||||
}
|
||||
|
||||
DEFINES on $(1) = $(defines) ;
|
||||
CCDEFS on $(1) = [ FDefines $(defines) ] ;
|
||||
HDRS on $(1) = [ on $(1) FIncludes $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ]
|
||||
$(HDRS_INCLUDES_SEPARATOR) ;
|
||||
RCHDRS on $(1) = [ FRcIncludes $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ] ;
|
||||
|
||||
SEARCH on $(2) += $(SEARCH_SOURCE) ;
|
||||
MakeLocate $(1) : $(LOCATE_TARGET) ;
|
||||
Depends $(1) : $(2) $(RC) ;
|
||||
LocalClean clean : $(1) ;
|
||||
ResComp1 $(1) : $(RC) $(2) ;
|
||||
}
|
||||
|
||||
# Note: We pipe the input files into the preprocessor, since *.rdef files are
|
||||
# considered linker scripts, and thus we can use preprocessor features.
|
||||
actions ResComp1
|
||||
{
|
||||
cat "$(2[2-])" | $(CC) -E $(CCDEFS) $(HDRS) - | egrep -v '^#' | $(2[1]) $(RCHDRS) --auto-names -o "$(1)" -
|
||||
}
|
||||
|
||||
actions XRes1
|
||||
{
|
||||
xres -o "$(1)" "$(2)" ;
|
||||
}
|
||||
|
||||
actions MimeSet
|
||||
{
|
||||
mimeset -f "$(1)" ;
|
||||
}
|
||||
|
||||
rule LexC++
|
||||
{
|
||||
Depends $(1) : $(2) ;
|
||||
MakeLocate $(1) : $(LOCATE_SOURCE) ;
|
||||
Clean clean : $(1) ;
|
||||
}
|
||||
|
||||
actions LexC++
|
||||
{
|
||||
$(LEX) -i -P$(<:B) -o$(1) $(2)
|
||||
}
|
||||
|
||||
rule Bison
|
||||
{
|
||||
local _h ;
|
||||
|
||||
_h = $(1:S=.h) ;
|
||||
|
||||
MakeLocate $(<) $(_h) : $(LOCATE_SOURCE) ;
|
||||
|
||||
Depends $(<) : $(>) ;
|
||||
BisonC++ $(<) : $(>) ;
|
||||
Clean clean : $(<) $(_h) ;
|
||||
|
||||
# make sure someone includes $(_h) else it will be
|
||||
# a deadly independent target
|
||||
|
||||
Includes $(<) : $(_h) ;
|
||||
}
|
||||
|
||||
actions BisonC++
|
||||
{
|
||||
$(BISON) -v -d -p $(2:B) -o $(1) $(2)
|
||||
}
|
||||
|
||||
rule Rez
|
||||
{
|
||||
Depends $(<) : $(>) ;
|
||||
}
|
||||
|
||||
rule PreCompile
|
||||
{
|
||||
# PreCompile <hdr> : <src>
|
||||
#
|
||||
# precompiles the given src (a headerfile) into the specified header.
|
||||
#
|
||||
local _hdr = $(1) ;
|
||||
local _src = $(2) ;
|
||||
MakeLocate $(_hdr) : $(LOCATE_TARGET) ;
|
||||
PreComp $(_hdr) : $(_src) ;
|
||||
Clean clean : $(_hdr) ;
|
||||
}
|
||||
|
||||
rule PreComp
|
||||
{
|
||||
Depends $(<) : $(>) ;
|
||||
}
|
||||
|
||||
actions PreComp
|
||||
{
|
||||
mwcc -precompile $(<) -lang cplus "$(>)" ;
|
||||
}
|
||||
|
||||
rule SubDirSysHdrs
|
||||
{
|
||||
# SubDirSysHdrs <dirs> ;
|
||||
#
|
||||
# Adds directories to the system include search paths for the current
|
||||
# subdirectory. Counterpart of SubDirHdrs which adds non-system include
|
||||
# search paths.
|
||||
#
|
||||
# <dirs>: The directories to be added to the current subdir's system
|
||||
# include search paths.
|
||||
#
|
||||
SUBDIRSYSHDRS += [ FDirName $(1) ] ;
|
||||
}
|
||||
|
||||
rule ObjectSysHdrs
|
||||
{
|
||||
# SubDirSysHdrs <sources or objects> : <dirs> ;
|
||||
#
|
||||
# Adds directories to the system include search paths for the given
|
||||
# sources or objects. Counterpart of ObjectHdrs which adds non-system
|
||||
# include search paths.
|
||||
#
|
||||
# NOTE: This rule must be invoked *after* the rule that generates the
|
||||
# objects.
|
||||
#
|
||||
# <sources or objects>: The targets for which to add system include
|
||||
# search paths.
|
||||
# <dirs>: The directories to be added to the given objects' system
|
||||
# include search paths.
|
||||
#
|
||||
|
||||
local s ;
|
||||
for s in [ FGristFiles $(<:S=$(SUFOBJ)) ] {
|
||||
SYSHDRS on $(s) += $(>) ;
|
||||
CCHDRS on $(s) = [ on $(s) FIncludes $(HDRS) ]
|
||||
$(HDRS_INCLUDES_SEPARATOR) [ on $(s) FSysIncludes $(SYSHDRS) ] ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# FSysIncludes <dirs> ;
|
||||
#
|
||||
# Counterpart of FIncludes for system include search paths.
|
||||
#
|
||||
if $(OSPLAT) = X86 {
|
||||
rule FSysIncludes { return -I$(<) ; }
|
||||
} else {
|
||||
rule FSysIncludes { return "-i "$(<) ; }
|
||||
}
|
||||
|
||||
# FRcIncludes <dirs> ;
|
||||
#
|
||||
# Counterpart of FIncludes for *.rdef scripts.
|
||||
#
|
||||
rule FRcIncludes
|
||||
{
|
||||
return "-I "$(<) ;
|
||||
}
|
||||
|
||||
# Variable referring to the STL.
|
||||
if $(OSPLAT) = X86 {
|
||||
if $(IS_GCC4_PLATFORM) = 1 {
|
||||
TARGET_LIBSTDC++ = stdc++ ;
|
||||
} else {
|
||||
TARGET_LIBSTDC++ = stdc++.r4 ;
|
||||
}
|
||||
} else {
|
||||
TARGET_LIBSTDC++ = mslcpp_4_0 ;
|
||||
}
|
||||
|
||||
|
||||
rule CreateSVNRevisionFile file
|
||||
{
|
||||
# CreateSVNRevisionFile <file>
|
||||
|
||||
local svnEntries = <svn>entries ;
|
||||
SEARCH on $(svnEntries) = [ FDirName $(TOP) .svn ] ;
|
||||
Depends $(file) : $(svnEntries) ;
|
||||
}
|
||||
|
||||
actions CreateSVNRevisionFile
|
||||
{
|
||||
(LANG=C svn info $(TOP) 2> /dev/null || echo Revision: 0) |
|
||||
grep Revision | awk '{printf $2}' > $(1)
|
||||
}
|
|
@ -0,0 +1,218 @@
|
|||
# OverriddenJamRules
|
||||
#
|
||||
# Jam rules that need to be overridden for good reasons.
|
||||
|
||||
# Overridden to allow for spaces in file names and to support resources.
|
||||
# Also set the on target LINKFLAGS variable to prevent later changes to
|
||||
# the global variable from having an effect on the setting for the target.
|
||||
rule Link
|
||||
{
|
||||
local dbg = [ on $(1) return $(DEBUG) ] ;
|
||||
if $(STRIP_APPS) && $(STRIP_APPS) != 0 && (!$(dbg) || $(dbg) = 0) {
|
||||
# strip app if requested so and if not in debug mode!
|
||||
Strip $(1) ;
|
||||
}
|
||||
# Note: RESFILES must be set before invocation.
|
||||
MODE on $(1) = $(EXEMODE) ;
|
||||
on $(1) XRes $(1) : $(RESFILES) ;
|
||||
Chmod $(1) ;
|
||||
MimeSet $(1) ;
|
||||
LINKFLAGS on $(1) = [ on $(1) return $(LINKFLAGS) ] ;
|
||||
}
|
||||
|
||||
actions Link bind NEEDLIBS
|
||||
{
|
||||
$(LINK) $(LINKFLAGS) -o "$(1)" $(UNDEFS) "$(2)" "$(NEEDLIBS)" $(LINKLIBS)
|
||||
}
|
||||
|
||||
|
||||
# Overridden to allow for spaces in file names.
|
||||
actions Chmod1
|
||||
{
|
||||
$(CHMOD) "$(MODE)" "$(1)"
|
||||
}
|
||||
|
||||
# Overridden to allow for spaces in file names.
|
||||
actions piecemeal together existing Clean
|
||||
{
|
||||
$(RM) -rf "$(>)"
|
||||
}
|
||||
|
||||
# Changes to rules for sake of discrimination between system and non-system
|
||||
# headers.
|
||||
|
||||
if $(OSPLAT) = X86 {
|
||||
if $(IS_GCC4_PLATFORM) = 1 {
|
||||
HDRS_INCLUDES_SEPARATOR = -iquote- ;
|
||||
} else {
|
||||
HDRS_INCLUDES_SEPARATOR = -I- ;
|
||||
}
|
||||
} else {
|
||||
HDRS_INCLUDES_SEPARATOR = -i- ;
|
||||
}
|
||||
|
||||
rule Cc
|
||||
{
|
||||
Depends $(<) : $(>) ;
|
||||
|
||||
# If the compiler's -o flag doesn't work, relocate the .o
|
||||
|
||||
if $(RELOCATE)
|
||||
{
|
||||
CcMv $(<) : $(>) ;
|
||||
}
|
||||
|
||||
# Just to clarify here: this sets the per-target CCFLAGS to
|
||||
# be the current value of (global) CCFLAGS and SUBDIRCCFLAGS.
|
||||
# CCHDRS and CCDEFS must be reformatted each time for some
|
||||
# compiles (VMS, NT) that malign multiple -D or -I flags.
|
||||
|
||||
CCFLAGS on $(<) += $(CCFLAGS) $(SUBDIRCCFLAGS) $(OPTIM) ;
|
||||
|
||||
CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ]
|
||||
$(HDRS_INCLUDES_SEPARATOR) [ on $(<) FSysIncludes $(SYSHDRS) ] ;
|
||||
CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ;
|
||||
}
|
||||
|
||||
rule C++
|
||||
{
|
||||
Depends $(<) : $(>) ;
|
||||
|
||||
if $(RELOCATE)
|
||||
{
|
||||
CcMv $(<) : $(>) ;
|
||||
}
|
||||
|
||||
C++FLAGS on $(<) += $(C++FLAGS) $(SUBDIRC++FLAGS) $(OPTIM) ;
|
||||
|
||||
CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ]
|
||||
$(HDRS_INCLUDES_SEPARATOR) [ on $(<) FSysIncludes $(SYSHDRS) ] ;
|
||||
CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ;
|
||||
}
|
||||
|
||||
rule Object
|
||||
{
|
||||
# locate object and search for source, if wanted
|
||||
|
||||
Clean clean : $(<) ;
|
||||
|
||||
MakeLocate $(<) : $(LOCATE_TARGET) ;
|
||||
SEARCH on $(>) = $(SEARCH_SOURCE) ;
|
||||
|
||||
# Save HDRS for -I$(HDRS) on compile.
|
||||
# We shouldn't need -I$(SEARCH_SOURCE) as cc can find headers
|
||||
# in the .c file's directory, but generated .c files (from
|
||||
# yacc, lex, etc) are located in $(LOCATE_TARGET), possibly
|
||||
# different from $(SEARCH_SOURCE).
|
||||
|
||||
HDRS on $(<) = $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ;
|
||||
SYSHDRS on $(<) = $(SUBDIRSYSHDRS) $(SYSHDRS) ;
|
||||
|
||||
# handle #includes for source: Jam scans for headers with
|
||||
# the regexp pattern $(HDRSCAN) and then invokes $(HDRRULE)
|
||||
# with the scanned file as the target and the found headers
|
||||
# as the sources. HDRSEARCH is the value of SEARCH used for
|
||||
# the found header files. Finally, if jam must deal with
|
||||
# header files of the same name in different directories,
|
||||
# they can be distinguished with HDRGRIST.
|
||||
|
||||
# $(SEARCH_SOURCE:E) is where cc first looks for #include
|
||||
# "foo.h" files. If the source file is in a distant directory,
|
||||
# look there. Else, look in "" (the current directory).
|
||||
|
||||
HDRRULE on $(>) = HdrRule ;
|
||||
HDRSCAN on $(>) = $(HDRPATTERN) ;
|
||||
HDRSEARCH on $(>) =
|
||||
$(SEARCH_SOURCE:E) $(SUBDIRHDRS) $(HDRS) $(SYSHDRS) $(STDHDRS) ;
|
||||
|
||||
HDRGRIST on $(>) = $(HDRGRIST) ;
|
||||
|
||||
# propagate target specific-defines
|
||||
|
||||
DEFINES on $(<) += $(DEFINES) ;
|
||||
|
||||
# if source is not .c, generate .c with specific rule
|
||||
|
||||
switch $(>:S)
|
||||
{
|
||||
case .asm : As $(<) : $(>) ;
|
||||
case .c : Cc $(<) : $(>) ;
|
||||
case .C : C++ $(<) : $(>) ;
|
||||
case .cc : C++ $(<) : $(>) ;
|
||||
case .cpp : C++ $(<) : $(>) ;
|
||||
case .f : Fortran $(<) : $(>) ;
|
||||
case .l : Cc $(<) : $(<:S=.c) ;
|
||||
LexC++ $(<:S=.c) : $(>) ;
|
||||
case .s : As $(<) : $(>) ;
|
||||
case .y : Cc $(<) : $(<:S=.c) ;
|
||||
Bison $(<:S=.c) : $(>) ;
|
||||
case * : UserObject $(<) : $(>) ;
|
||||
}
|
||||
}
|
||||
|
||||
rule ObjectHdrs
|
||||
{
|
||||
local s ;
|
||||
for s in [ FGristFiles $(<:S=$(SUFOBJ)) ] {
|
||||
HDRS on $(s) += $(>) ;
|
||||
CCHDRS on $(s) = [ on $(s) FIncludes $(HDRS) ]
|
||||
$(HDRS_INCLUDES_SEPARATOR) [ on $(s) FSysIncludes $(SYSHDRS) ] ;
|
||||
}
|
||||
}
|
||||
|
||||
# Override Jam 2.5rc3 MakeLocate and MkDir to deal more intelligently
|
||||
# with grist set on the supplied directory name.
|
||||
rule MakeLocate
|
||||
{
|
||||
if $(2[1])
|
||||
{
|
||||
local dir = $(2[1]) ;
|
||||
if ! $(dir:G) {
|
||||
dir = $(dir:G=dir) ;
|
||||
}
|
||||
LOCATE on $(1) = $(dir:G=) ;
|
||||
Depends $(1) : $(dir) ;
|
||||
MkDir $(dir) ;
|
||||
}
|
||||
}
|
||||
|
||||
rule MkDir
|
||||
{
|
||||
# If dir exists, don't update it
|
||||
# Do this even for $(DOT).
|
||||
|
||||
local dir = $(<) ;
|
||||
if ! $(dir:G) {
|
||||
dir = $(dir:G=dir) ;
|
||||
}
|
||||
|
||||
NoUpdate $(dir) ;
|
||||
|
||||
if $(dir:G=) != $(DOT) && ! $($(dir:G=)-mkdir) {
|
||||
local s ;
|
||||
|
||||
# Cheesy gate to prevent multiple invocations on same dir
|
||||
# MkDir1 has the actions
|
||||
# Arrange for jam dirs
|
||||
|
||||
$(dir:G=)-mkdir = true ;
|
||||
MkDir1 $(dir) ;
|
||||
Depends dirs : $(dir) ;
|
||||
|
||||
# Recursively make parent directories.
|
||||
# $(dir:P) = $(dir)'s parent, & we recurse until root
|
||||
|
||||
s = $(dir:P) ; # parent keeps grist
|
||||
|
||||
if $(s:G=) && $(s) != $(dir) {
|
||||
Depends $(dir) : $(s) ;
|
||||
MkDir $(s) ;
|
||||
} else if $(s) {
|
||||
NotFile $(s) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Add SUBDIRSYSHDRS to the variables that shall be reset automatically by the
|
||||
# SubDir rule.
|
||||
SUBDIRRESET += SYSHDRS ;
|
|
@ -0,0 +1,247 @@
|
|||
# PackageRules
|
||||
#
|
||||
# Rules to create archives for binary distribution
|
||||
|
||||
rule Copy
|
||||
{
|
||||
if $(2) {
|
||||
SEARCH on $(2) += $(SEARCH_SOURCE) ;
|
||||
Depends $(1) : $(COPYATTR) $(2) ;
|
||||
Copy1 $(1) : $(COPYATTR) $(2) ;
|
||||
}
|
||||
}
|
||||
|
||||
actions Copy1
|
||||
{
|
||||
"$(2[1])" -d "$(2[2-])" "$(1)"
|
||||
}
|
||||
|
||||
rule Packages
|
||||
{
|
||||
local packagenames = $(1) ;
|
||||
local packagefiles = $(2) ;
|
||||
local path = $(3) ;
|
||||
for name in $(packagenames) {
|
||||
Package $(name) : $(packagefiles) : $(path) ;
|
||||
}
|
||||
}
|
||||
|
||||
rule FPackageConfigSubPath
|
||||
{
|
||||
# FPackageConfigSubPath <packagename>
|
||||
#
|
||||
local packagename = $(1) ;
|
||||
|
||||
local configSubPath ;
|
||||
on $(packagename) {
|
||||
configSubPath = $(OS:L) $(OSPLAT:L) ;
|
||||
|
||||
if $(DEBUG) = 0 {
|
||||
configSubPath += release ;
|
||||
} else {
|
||||
configSubPath += debug_$(DEBUG) ;
|
||||
}
|
||||
}
|
||||
|
||||
return $(configSubPath) ;
|
||||
}
|
||||
|
||||
rule Package
|
||||
{
|
||||
local packagename = $(1) ;
|
||||
local packagefiles = $(2) ;
|
||||
local path = $(3) ;
|
||||
|
||||
local configSubPath = [ FPackageConfigSubPath $(packagename) ] ;
|
||||
#local packagezip = $(packagename:S=.zip:G=_packages) ;
|
||||
local packagezip = $(packagename:S=-$(VERSION).zip:G=_packages) ;
|
||||
local targetDir = [ FDirName $(PACKAGE_DIR) $(configSubPath) ] ;
|
||||
local packagedir = [ FDirName $(targetDir) $(packagename) ] ;
|
||||
|
||||
local installscript = install.sh ;
|
||||
local packageinstallscript = $(installscript:G=_packages!$(packagename)) ;
|
||||
local installzip = install.zip ;
|
||||
local packageinstallzip = $(installzip:G=_packages!$(packagename)) ;
|
||||
|
||||
local packageobjectdir = [ FDirName $(PACKAGE_OBJECT_DIR)
|
||||
$(configSubPath) $(packagename) ] ;
|
||||
local packagefiledir = [ FDirName $(packageobjectdir) $(path) ] ;
|
||||
local packagefileinstallzip
|
||||
= $(installzip:G=_package_objects!$(packagename)) ;
|
||||
|
||||
# add the files to the install.zip
|
||||
local packagefilegrist = [ FGrist _package_files $(packagename) $(path) ] ;
|
||||
for file in $(packagefiles) {
|
||||
if $(path[0]) = "boot" {
|
||||
local packagefile = $(file:G=$(packagefilegrist)) ;
|
||||
MakeLocate $(packagefile) : $(packagefiledir) ;
|
||||
Copy $(packagefile) : $(file) ;
|
||||
Clean cleanPackages : $(packagefile) ;
|
||||
PackageInstallZip $(packagefileinstallzip) : $(packagefile) ;
|
||||
} else {
|
||||
local packagefile = $(file:G=_packages!$(packagename)) ;
|
||||
MakeLocate $(packagefile) : $(packagedir) ;
|
||||
Copy $(packagefile) : [ FGristFiles $(file) ] ;
|
||||
Clean cleanPackages : $(packagefile) ;
|
||||
Depends $(packagezip) : $(packagefile) ;
|
||||
}
|
||||
}
|
||||
|
||||
# general setup for this package -- only on first invocation
|
||||
if ! $(_setup_$(packagename)) {
|
||||
_setup_$(packagename) = true ;
|
||||
|
||||
NotFile $(packagename) ;
|
||||
LocalDepends packages : $(packagename) ;
|
||||
|
||||
MakeLocate $(packagezip) : $(targetDir) ;
|
||||
MakeLocate $(packageinstallscript) : $(packagedir) ;
|
||||
MakeLocate $(packageinstallzip) : $(packagedir) ;
|
||||
MakeLocate $(packagefileinstallzip) : $(packageobjectdir) ;
|
||||
|
||||
PackageInstallScript $(packageinstallscript) : $(packagedir) ;
|
||||
LinkInstallZip $(packageinstallzip) : $(packagefileinstallzip) ;
|
||||
Depends $(packagename) : $(packagezip) ;
|
||||
PackageZip $(packagezip) : $(packagedir)
|
||||
: $(packageinstallscript) $(packageinstallzip) ;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
rule PackageSymLink
|
||||
{
|
||||
# PackageSymLink <packageName> : <symlink path components>
|
||||
# : <symlink target>
|
||||
#
|
||||
local packagename = $(1) ;
|
||||
local symlinkPath = $(2) ;
|
||||
local symlinkTarget = $(3) ;
|
||||
|
||||
local configSubPath = [ FPackageConfigSubPath $(packagename) ] ;
|
||||
|
||||
local symlinkDir = [ FReverse $(symlinkPath) ] ;
|
||||
local symlink = $(symlinkDir[1]) ;
|
||||
symlinkDir = [ FReverse $(symlinkDir[2-]) ] ;
|
||||
local symlinkGrist = [ FGrist _package $(packagename) $(symlinkDir) ] ;
|
||||
symlink = $(symlink:G=$(symlinkGrist)) ;
|
||||
|
||||
if $(symlinkDir[1]) = boot {
|
||||
local installzip = install.zip ;
|
||||
local packagefileinstallzip
|
||||
= $(installzip:G=_package_objects!$(packagename)) ;
|
||||
|
||||
local packageobjectdir = [ FDirName $(PACKAGE_OBJECT_DIR)
|
||||
$(configSubPath) $(packagename) ] ;
|
||||
symlinkDir = [ FDirName $(packageobjectdir) $(symlinkDir) ] ;
|
||||
|
||||
PackageInstallZip $(packagefileinstallzip) : $(symlink) ;
|
||||
|
||||
} else {
|
||||
#local packagezip = $(packagename:S=.zip:G=_packages) ;
|
||||
local packagezip = $(packagename:S=-$(VERSION).zip:G=_packages) ;
|
||||
|
||||
local packagedir = [ FDirName $(PACKAGE_DIR) $(configSubPath)
|
||||
$(packagename) ] ;
|
||||
symlinkDir = [ FDirName $(packagedir) $(symlinkDir) ] ;
|
||||
|
||||
Depends $(packagezip) : $(symlink) ;
|
||||
}
|
||||
|
||||
MakeLocate $(symlink) : $(symlinkDir) ;
|
||||
SymLink $(symlink) : $(symlinkTarget) : false ;
|
||||
Clean cleanPackages : $(symlink) ;
|
||||
}
|
||||
|
||||
rule PackageDriverSymLink
|
||||
{
|
||||
# PackageDriverSymLink <packageName> : <devRelativeSymlinkComponents> ;
|
||||
# <packageName>: Package name.
|
||||
# <devRelativeSymlinkComponents>: Path components relative to the
|
||||
# /boot/home/config/add-ons/kernel/drivers/dev directory, e.g.
|
||||
# "graphics mga.driver" (no quotation, of course).
|
||||
#
|
||||
local packageName = $(1) ;
|
||||
local symlinkComponents = $(2) ;
|
||||
|
||||
# construct the symlink contents
|
||||
local symlinkPath = [ FReverse $(symlinkComponents) ] ;
|
||||
symlinkPath = bin $(symlinkPath[1]) ;
|
||||
|
||||
for i in $(symlinkComponents) {
|
||||
symlinkPath = $(DOTDOT) $(symlinkPath) ;
|
||||
}
|
||||
|
||||
PackageSymLink $(packageName)
|
||||
: boot home config add-ons kernel drivers dev $(symlinkComponents)
|
||||
: [ FDirName $(symlinkPath) ] ;
|
||||
}
|
||||
|
||||
rule PackageZip
|
||||
{
|
||||
local dir = $(2:G=dir) ;
|
||||
Depends $(1) : $(dir) $(3) ;
|
||||
Clean cleanPackages : $(1) ;
|
||||
PackageZip1 $(1) : $(dir) ;
|
||||
}
|
||||
|
||||
actions together PackageZip1 {
|
||||
cd "$(2:P)" ;
|
||||
zip -rq "$(1:BS)" "$(2:BS)" ;
|
||||
}
|
||||
|
||||
rule PackageInstallScript
|
||||
{
|
||||
MakeLocate $(1) : $(2) ;
|
||||
Clean cleanPackages : $(1) ;
|
||||
PackageInstallScript1 $(1) : $(2:G=dir) ;
|
||||
}
|
||||
|
||||
actions together PackageInstallScript1
|
||||
{
|
||||
echo '#!/bin/sh
|
||||
base=`dirname "$0"`
|
||||
cd "$base"
|
||||
if [ -n "$TTY" ]
|
||||
then
|
||||
unzip -d / install.zip
|
||||
else
|
||||
response=`alert "Would you like to automatically overwrite existing files, or receive a prompt?" "Overwrite" "Prompt"`
|
||||
if [ $response == "Overwrite" ]
|
||||
then
|
||||
unzip -od / install.zip
|
||||
alert "Finished installing" "Thanks"
|
||||
else
|
||||
if [ -e /boot/beos/apps/Terminal ]
|
||||
then
|
||||
terminal=/boot/beos/apps/Terminal
|
||||
else
|
||||
terminal=`query Terminal | head -1`
|
||||
fi
|
||||
$terminal -t "installer" /bin/sh "$0"
|
||||
fi
|
||||
fi' > "$(1)" ;
|
||||
chmod 755 "$(1)" ;
|
||||
}
|
||||
|
||||
rule PackageInstallZip
|
||||
{
|
||||
Depends $(1) : $(2) ;
|
||||
Clean cleanPackages : $(1) ;
|
||||
}
|
||||
|
||||
actions together PackageInstallZip
|
||||
{
|
||||
cd "$(1:P)" ;
|
||||
zip -rqy "$(1:BS)" boot ;
|
||||
}
|
||||
|
||||
rule LinkInstallZip
|
||||
{
|
||||
Depends $(1) : $(2) ;
|
||||
Clean cleanPackages : $(1) ;
|
||||
}
|
||||
|
||||
actions together LinkInstallZip
|
||||
{
|
||||
ln -sf "`pwd`/$(2)" "$(1)" ;
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
# UserBuildConfig
|
||||
#
|
||||
# Sample of a UserBuildConfig file. It is a central place where the user can
|
||||
# set variables affecting certain aspects of the build, such as debug,
|
||||
# warnings and optimization settings.
|
||||
#
|
||||
# The following variables can be set:
|
||||
#
|
||||
# BUILD_TESTS - If not empty, all tests (TestBeam) will be build, too.
|
||||
# Default is 0, i.e. no tests.
|
||||
# CCFLAGS, C++FLAGS - Flags passed to the C/C++ compiler.
|
||||
# DEBUG - If not empty, will turn on debugging, i.e. will
|
||||
# add respective C/C++ compiler and linker flags and
|
||||
# the CPP DEBUG macro.
|
||||
# DEFINES - CPP macros to be defined, e.g. something like
|
||||
# `SPECIAL_FEATURE' or `CACHE_SIZE=1024'.
|
||||
# HDRS - List of directories to be added to the local include
|
||||
# search paths.
|
||||
# LINKFLAGS - Flags passed to the linker.
|
||||
# LOCATE_MAIN_TARGET - Directory where the main targets (i.e. applications,
|
||||
# libraries shall be placed). Should usually not be
|
||||
# tampered with by the user.
|
||||
# OPTIM - Optimization specific flags passed to the C/C++
|
||||
# compiler. Usually you want to use OPTIMIZE instead.
|
||||
# OPTIMIZE - If not set to `0', will turn on optimization, i.e.
|
||||
# will set the respective C/C++ compiler flags
|
||||
# (i.e. the OPTIM variable).
|
||||
# STRIP_APPS - if not set to '0', will cause all generated apps to
|
||||
# be stripped. Default is '0', i.e. no stripping
|
||||
# SYSHDRS - List of directories to be added to the system include
|
||||
# search paths.
|
||||
# WARNINGS - If not set to `0', will turn on warnings, i.e. will
|
||||
# set the respective C/C++ compiler flags.
|
||||
|
||||
# Examples:
|
||||
|
||||
# Globally turn off debugging:
|
||||
#
|
||||
# DEBUG = 0 ;
|
||||
|
||||
# Globally activate debugging:
|
||||
#
|
||||
# DEBUG = 1 ;
|
||||
|
||||
# ... e.g. like this, for the `add-ons/catalogs' directory and all its
|
||||
# subdirectories.
|
||||
#
|
||||
# SetConfigVar WARNINGS : TOP add-ons catalogs : 1 ;
|
||||
|
||||
# Turn on debugging for the the directory `Languages' and all its subdirectories.
|
||||
#
|
||||
# SetConfigVar DEBUG : TOP Languages : 1 ;
|
||||
|
||||
# Turn off optimization for the `rez' directory and all its subdirectories.
|
||||
#
|
||||
# SetConfigVar OPTIMIZE : TOP rez : 0 ;
|
||||
|
||||
# Define the CPP macro INSANE_DEBUGGING_LEVEL to the value `100' in the
|
||||
# `lpe' directory, but NOT in its subdirectories (note the use of the
|
||||
# optional fourth parameter `local', which works for both SetConfigVar and
|
||||
# AppendToConfigVar).
|
||||
#
|
||||
# AppendToConfigVar DEFINES : TOP lpe : INSANE_DEBUGGING_LEVEL=100 : local ;
|
|
@ -0,0 +1,144 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Copyright 2009, Pier Luigi Fiorini.
|
||||
# Distributed under the terms of the MIT License.
|
||||
#
|
||||
# Authors:
|
||||
# Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
|
||||
#
|
||||
|
||||
current_dir=`pwd`
|
||||
defines=""
|
||||
|
||||
# Binaries
|
||||
jambin=`which jam`
|
||||
rcbin=`which rc`
|
||||
xresbin=`which xres`
|
||||
settypebin=`which settype`
|
||||
mimesetbin=`which mimeset`
|
||||
setversionbin=`which setversion`
|
||||
copyattrbin=`which copyattr`
|
||||
|
||||
# Check operating system
|
||||
platform=`uname -s`
|
||||
release=`uname -r`
|
||||
echo -n "Checking operating system... "
|
||||
case "$platform" in
|
||||
BeOS)
|
||||
case "$release" in
|
||||
4.*)
|
||||
echo "*** BeOS R4 is not supported!"
|
||||
exit 1
|
||||
;;
|
||||
5.*)
|
||||
echo "*** BeOS R5 is not supported!"
|
||||
exit 1
|
||||
;;
|
||||
6.*)
|
||||
echo "*** Zeta is not supported!"
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
echo "*** Unsupported BeOS platform!"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
Haiku)
|
||||
defines="HAIKU_TARGET_PLATFORM_HAIKU=1"
|
||||
;;
|
||||
*)
|
||||
echo "*** Unsupported $platform operating system!"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
echo "$platform $release"
|
||||
|
||||
# Check whether jam exists
|
||||
echo -n "Checking whether jam exists... "
|
||||
if [ -z "$jambin" ]; then
|
||||
echo "not found"
|
||||
echo "*** Caya requires jam, please read our Build.txt file."
|
||||
exit 1
|
||||
else
|
||||
echo "found"
|
||||
fi
|
||||
|
||||
# Check for rc
|
||||
echo -n "Checking for rc... "
|
||||
if [ -z "$rcbin" ]; then
|
||||
echo "not found"
|
||||
exit 1
|
||||
fi
|
||||
echo $rcbin
|
||||
|
||||
# Check for xres
|
||||
echo -n "Checking for xres..."
|
||||
if [ -z "$xresbin" ]; then
|
||||
echo "not found"
|
||||
exit 1
|
||||
fi
|
||||
echo $xresbin
|
||||
|
||||
# Check for settype
|
||||
echo -n "Checking for settype..."
|
||||
if [ -z "$settypebin" ]; then
|
||||
echo "not found"
|
||||
exit 1
|
||||
fi
|
||||
echo $settypebin
|
||||
|
||||
# Check for mimeset
|
||||
echo -n "Checking for mimeset..."
|
||||
if [ -z "$mimesetbin" ]; then
|
||||
echo "not found"
|
||||
exit 1
|
||||
fi
|
||||
echo $mimesetbin
|
||||
|
||||
# Check for setverion
|
||||
echo -n "Checking for setversion..."
|
||||
if [ -z "$setversionbin" ]; then
|
||||
echo "not found"
|
||||
exit 1
|
||||
fi
|
||||
echo $setversionbin
|
||||
|
||||
# Check for copyattr
|
||||
echo -n "Checking for copyattr..."
|
||||
if [ -z "$copyattrbin" ]; then
|
||||
echo "not found"
|
||||
exit 1
|
||||
fi
|
||||
echo $copyattrbin
|
||||
|
||||
# Create the build configuration
|
||||
mkdir -p $current_dir/generated
|
||||
cat > $current_dir/generated/BuildConfig << EOF
|
||||
RC = ${rcbin} ;
|
||||
XRES = ${xresbin} ;
|
||||
SETTYPE = ${settypebin} ;
|
||||
MIMESET = ${mimesetbin} ;
|
||||
SETVERSION = ${setversionbin} ;
|
||||
COPYATTR = ${copyattrbin} ;
|
||||
|
||||
COMMON_DIRECTORY = $(finddir B_COMMON_DIRECTORY) ;
|
||||
COMMON_BIN_DIRECTORY = $(finddir B_COMMON_BIN_DIRECTORY) ;
|
||||
COMMON_INCLUDE_DIRECTORY = $(finddir B_COMMON_DIRECTORY)/include ;
|
||||
COMMON_LIB_DIRECTORY = $(finddir B_COMMON_LIB_DIRECTORY) ;
|
||||
COMMON_SERVERS_DIRECTORY = $(finddir B_COMMON_SERVERS_DIRECTORY) ;
|
||||
COMMON_ADDONS_DIRECTORY = $(finddir B_COMMON_ADDONS_DIRECTORY) ;
|
||||
COMMON_DEVELOP_DIRECTORY = $(finddir B_COMMON_DEVELOP_DIRECTORY) ;
|
||||
USER_CONFIG_DIRECTORY = $(finddir B_USER_CONFIG_DIRECTORY) ;
|
||||
USER_INCLUDE_DIRECTORY = $(finddir B_USER_CONFIG_DIRECTORY)/include ;
|
||||
SYSTEM_DIRECTORY = $(finddir B_SYSTEM_DIRECTORY) ;
|
||||
SYSTEM_LIB_DIRECTORY = $(finddir B_SYSTEM_LIB_DIRECTORY) ;
|
||||
BEOS_PREFERENCES_DIRECTORY = $(finddir B_BEOS_PREFERENCES_DIRECTORY) ;
|
||||
PREFERENCES_DIRECTORY = $(finddir B_PREFERENCES_DIRECTORY) ;
|
||||
USER_PREFERENCES_DIRECTORY = $(finddir B_USER_CONFIG_DIRECTORY)/be/Preferences ;
|
||||
APPS_DIRECTORY = $(finddir B_APPS_DIRECTORY) ;
|
||||
|
||||
DEFINES += ${defines} ;
|
||||
EOF
|
||||
|
||||
echo "Configuration done."
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,7 @@
|
|||
SubDir TOP libs ;
|
||||
|
||||
# Include all the components.
|
||||
SubInclude TOP libs libjabber ;
|
||||
SubInclude TOP libs librunview ;
|
||||
SubInclude TOP libs libinterface ;
|
||||
SubInclude TOP libs libsupport ;
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
BitmapListItem.cpp: A BMenuItem with an optional picture
|
||||
Written by DarkWyrm <darkwyrm@earthlink.net>, Copyright 2007
|
||||
Released under the MIT license.
|
||||
*/
|
||||
#include "BitmapMenuItem.h"
|
||||
#include <Bitmap.h>
|
||||
|
||||
BitmapMenuItem::BitmapMenuItem(const char *label, BMessage *msg,
|
||||
BBitmap *bitmap, char shortcut,
|
||||
uint32 modifiers)
|
||||
: BMenuItem(label,msg,shortcut,modifiers),
|
||||
fBitmap(bitmap)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BitmapMenuItem::BitmapMenuItem(BMessage *data)
|
||||
: BMenuItem(data)
|
||||
{
|
||||
fBitmap = (BBitmap*) BBitmap::Instantiate(data);
|
||||
}
|
||||
|
||||
|
||||
BitmapMenuItem::~BitmapMenuItem(void)
|
||||
{
|
||||
delete fBitmap;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BitmapMenuItem::Archive(BMessage *data, bool deep) const
|
||||
{
|
||||
status_t status = BMenuItem::Archive(data,deep);
|
||||
|
||||
if (status == B_OK && fBitmap)
|
||||
status = fBitmap->Archive(data,deep);
|
||||
|
||||
if (status == B_OK)
|
||||
status = data->AddString("class","BitmapMenuItem");
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BitmapMenuItem::GetContentSize(float *width, float *height)
|
||||
{
|
||||
float w,h;
|
||||
BMenuItem::GetContentSize(&w,&h);
|
||||
if (fBitmap)
|
||||
w += (fBitmap->Bounds().Width() *
|
||||
(Frame().Height() / fBitmap->Bounds().Height())) + 20;
|
||||
|
||||
if (width)
|
||||
*width = w;
|
||||
|
||||
if (height)
|
||||
*height = h;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BitmapMenuItem::DrawContent(void)
|
||||
{
|
||||
if (!Label() && !fBitmap)
|
||||
return;
|
||||
|
||||
float width, height;
|
||||
GetContentSize(&width, &height);
|
||||
|
||||
BRect drawrect(Frame());
|
||||
drawrect.bottom--;
|
||||
drawrect.top++;
|
||||
drawrect.left = ContentLocation().x;
|
||||
if (fBitmap) {
|
||||
// Scale the fBitmap down to completely fit within the field's height
|
||||
if (fBitmap->Bounds().Height() > drawrect.Height()) {
|
||||
drawrect.right = drawrect.left +
|
||||
(fBitmap->Bounds().Width() *
|
||||
(Frame().Height() / fBitmap->Bounds().Height()));
|
||||
} else {
|
||||
drawrect.right = drawrect.left + fBitmap->Bounds().Width();
|
||||
}
|
||||
} else {
|
||||
drawrect.right = drawrect.left - 5;
|
||||
}
|
||||
|
||||
BPoint stringpoint(ContentLocation());
|
||||
stringpoint.x = drawrect.right + 10;
|
||||
Menu()->MovePenTo(stringpoint);
|
||||
BMenuItem::DrawContent();
|
||||
|
||||
if (fBitmap) {
|
||||
Menu()->PushState();
|
||||
Menu()->SetDrawingMode(B_OP_ALPHA);
|
||||
Menu()->DrawBitmap(fBitmap, fBitmap->Bounds(), drawrect);
|
||||
Menu()->PopState();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BitmapMenuItem::SetBitmap(BBitmap *bitmap)
|
||||
{
|
||||
delete fBitmap;
|
||||
fBitmap = bitmap;
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
BitmapListItem.h: A BMenuItem with an optional picture
|
||||
Written by DarkWyrm <darkwyrm@earthlink.net>, Copyright 2007
|
||||
Released under the MIT license.
|
||||
*/
|
||||
#ifndef BITMAP_MENU_ITEM_H
|
||||
#define BITMAP_MENU_ITEM_H
|
||||
|
||||
#include <MenuItem.h>
|
||||
|
||||
/*
|
||||
BitmapMenuItems are simple little items, really. They provide the
|
||||
ability to show a menu item with some text, a picture, or both. The item
|
||||
takes ownership of the BBitmap given to it, so please do not delete it.
|
||||
Note that it is still possible to see the checkmark on marked
|
||||
BitmapMenuItems -- the bitmap does not obscure the checkmark.
|
||||
*/
|
||||
|
||||
class BitmapMenuItem : public BMenuItem
|
||||
{
|
||||
public:
|
||||
BitmapMenuItem(const char *label, BMessage *msg,
|
||||
BBitmap *bitmap, char shortcut = 0,
|
||||
uint32 modifiers = 0);
|
||||
BitmapMenuItem(BMessage *data);
|
||||
virtual ~BitmapMenuItem(void);
|
||||
virtual status_t Archive(BMessage *data, bool deep = true) const;
|
||||
|
||||
virtual void GetContentSize(float *width, float *height);
|
||||
virtual void DrawContent(void);
|
||||
|
||||
virtual void SetBitmap(BBitmap *bitmap);
|
||||
BBitmap * Bitmap(void) const;
|
||||
|
||||
private:
|
||||
BBitmap *fBitmap;
|
||||
float fBaselineOffset;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright 2009-2010, Pier Luigi Fiorini. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
|
||||
*/
|
||||
|
||||
#include <Path.h>
|
||||
|
||||
#include <private/IconUtils.h>
|
||||
|
||||
#include "BitmapUtils.h"
|
||||
|
||||
#define BEOS_ICON_ATTRIBUTE "BEOS:ICON"
|
||||
#define BEOS_MINI_ICON_ATTRIBUTE "BEOS:M:STD_ICON"
|
||||
#define BEOS_LARGE_ICON_ATTRIBUTE "BEOS:L:STD_ICON"
|
||||
|
||||
|
||||
BBitmap*
|
||||
ReadNodeIcon(const char* name, icon_size size, bool followSymlink)
|
||||
{
|
||||
BEntry entry(name, followSymlink);
|
||||
entry_ref ref;
|
||||
|
||||
entry.GetRef(&ref);
|
||||
|
||||
BNode node(BPath(&ref).Path());
|
||||
|
||||
BBitmap* ret = new BBitmap(BRect(0, 0, (float)size - 1, (float)size - 1), B_RGBA32);
|
||||
if (BIconUtils::GetIcon(&node, BEOS_ICON_ATTRIBUTE, BEOS_MINI_ICON_ATTRIBUTE,
|
||||
BEOS_LARGE_ICON_ATTRIBUTE, size, ret) != B_OK) {
|
||||
delete ret;
|
||||
ret = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
BBitmap* IconFromResources(BResources* res, int32 num, icon_size size)
|
||||
{
|
||||
if (!res)
|
||||
return NULL;
|
||||
|
||||
size_t nbytes = 0;
|
||||
type_code type = B_VECTOR_ICON_TYPE;
|
||||
color_space cspace = B_RGBA32;
|
||||
|
||||
// Try to find a vector icon
|
||||
const void* data = res->LoadResource(type, num, &nbytes);
|
||||
if (data == NULL) {
|
||||
// Determine resource type from icon size
|
||||
switch (size) {
|
||||
case B_MINI_ICON:
|
||||
type = B_MINI_ICON_TYPE;
|
||||
break;
|
||||
case B_LARGE_ICON:
|
||||
type = B_LARGE_ICON_TYPE;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Get bitmap icon
|
||||
data = res->LoadResource(type, num, &nbytes);
|
||||
if (data == NULL)
|
||||
return NULL;
|
||||
|
||||
cspace = B_CMAP8;
|
||||
}
|
||||
|
||||
BBitmap* icon = new BBitmap(BRect(0, 0, size - 1, size - 1), cspace);
|
||||
if (icon->InitCheck() != B_OK)
|
||||
return NULL;
|
||||
|
||||
switch (type) {
|
||||
case B_VECTOR_ICON_TYPE:
|
||||
if (BIconUtils::GetVectorIcon((const uint8*)data, nbytes, icon) != B_OK) {
|
||||
delete icon;
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
icon->SetBits(data, size * size, 0, cspace);
|
||||
}
|
||||
|
||||
return icon;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Copyright 2009-2010, Pier Luigi Fiorini. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _BITMAP_UTILS_H
|
||||
#define _BITMAP_UTILS_H
|
||||
|
||||
#include <Bitmap.h>
|
||||
#include <Mime.h>
|
||||
#include <Resources.h>
|
||||
|
||||
BBitmap* ReadNodeIcon(const char* name, icon_size size, bool followSymlink);
|
||||
BBitmap* IconFromResources(BResources* res, int32 num, icon_size size);
|
||||
|
||||
#endif // _BITMAP_UTILS_H
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright 2009, Pier Luigi Fiorini. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
|
||||
*/
|
||||
|
||||
#include <Bitmap.h>
|
||||
#include <TranslationUtils.h>
|
||||
|
||||
#include "BitmapView.h"
|
||||
|
||||
|
||||
BitmapView::BitmapView(const char* name, uint32 flags)
|
||||
: BView(name, flags),
|
||||
fBitmap(NULL),
|
||||
fWidth(0.0f),
|
||||
fHeight(0.0f)
|
||||
{
|
||||
// Set transparent
|
||||
//SetViewColor(B_TRANSPARENT_COLOR);
|
||||
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
}
|
||||
|
||||
|
||||
BitmapView::~BitmapView()
|
||||
{
|
||||
delete fBitmap;
|
||||
fBitmap = NULL;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BitmapView::InitCheck()
|
||||
{
|
||||
if (fBitmap != NULL)
|
||||
return B_OK;
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BitmapView::SetBitmap(BBitmap* bitmap)
|
||||
{
|
||||
delete fBitmap;
|
||||
fBitmap = bitmap;
|
||||
|
||||
if (fBitmap != NULL) {
|
||||
BRect frame(fBitmap->Bounds());
|
||||
|
||||
fWidth = frame.Width();
|
||||
fHeight = frame.Height();
|
||||
|
||||
ResizeTo(fWidth, fHeight);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BSize
|
||||
BitmapView::MinSize()
|
||||
{
|
||||
return BSize(fWidth, fHeight);
|
||||
}
|
||||
|
||||
|
||||
BSize
|
||||
BitmapView::MaxSize()
|
||||
{
|
||||
return MinSize();
|
||||
}
|
||||
|
||||
|
||||
BSize
|
||||
BitmapView::PreferredSize()
|
||||
{
|
||||
return MinSize();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BitmapView::Draw(BRect frame)
|
||||
{
|
||||
SetDrawingMode(B_OP_ALPHA);
|
||||
SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
|
||||
|
||||
if (fBitmap != NULL)
|
||||
DrawBitmap(fBitmap, BPoint(0, 0));
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright 2009, Pier Luigi Fiorini. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _BITMAP_VIEW_H
|
||||
#define _BITMAP_VIEW_H
|
||||
|
||||
#include <View.h>
|
||||
|
||||
class BBitmap;
|
||||
|
||||
class BitmapView : public BView {
|
||||
public:
|
||||
BitmapView(const char* name, uint32 flags = B_WILL_DRAW);
|
||||
~BitmapView();
|
||||
|
||||
status_t InitCheck();
|
||||
|
||||
void SetBitmap(BBitmap* bitmap);
|
||||
|
||||
virtual BSize MinSize();
|
||||
virtual BSize MaxSize();
|
||||
virtual BSize PreferredSize();
|
||||
|
||||
virtual void Draw(BRect frame);
|
||||
|
||||
private:
|
||||
BBitmap* fBitmap;
|
||||
float fWidth;
|
||||
float fHeight;
|
||||
};
|
||||
|
||||
#endif // _BITMAP_VIEW_H
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* Copyright 2009-2010, Pier Luigi Fiorini. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
|
||||
*/
|
||||
|
||||
#include <Message.h>
|
||||
|
||||
#include "Divider.h"
|
||||
|
||||
const float kResizeWidgetRatio = 0.1f;
|
||||
const float kResizeWidgetPadding = 2.0f;
|
||||
const float kResizeWidgetCircleRadius = 2.0f;
|
||||
const float kResizeWidgetSpacing = 10.0f;
|
||||
const int kResizeWidgetCircleCount = 2;
|
||||
|
||||
|
||||
Divider::Divider(const char* name, uint32 flags)
|
||||
: BView(name, flags),
|
||||
fOrient(B_HORIZONTAL)
|
||||
{
|
||||
SetViewColor (ui_color (B_PANEL_BACKGROUND_COLOR));
|
||||
}
|
||||
|
||||
|
||||
Divider::Divider(BMessage* archive)
|
||||
: BView(archive)
|
||||
{
|
||||
if (archive->FindInt32("orientation", (int32*)&fOrient) != B_OK)
|
||||
fOrient = B_HORIZONTAL;
|
||||
}
|
||||
|
||||
|
||||
Divider::~Divider()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Divider::Draw(BRect updateRect)
|
||||
{
|
||||
BRect bounds = Bounds();
|
||||
|
||||
rgb_color view_color = ViewColor();
|
||||
|
||||
rgb_color line = tint_color(view_color, B_DARKEN_1_TINT);
|
||||
rgb_color shadow = tint_color(view_color, B_DARKEN_2_TINT);
|
||||
|
||||
PushState();
|
||||
|
||||
SetHighColor(view_color);
|
||||
FillRect(bounds);
|
||||
|
||||
if (fOrient == B_HORIZONTAL) {
|
||||
BPoint left(bounds.left, (bounds.Height() / 2) + bounds.top);
|
||||
BPoint right(bounds.right, left.y);
|
||||
|
||||
BPoint fudge(PenSize(), PenSize());
|
||||
|
||||
left -= fudge;
|
||||
right -= fudge;
|
||||
SetHighColor(line);
|
||||
StrokeLine(left, right);
|
||||
|
||||
left += fudge;
|
||||
right += fudge;
|
||||
SetHighColor(shadow);
|
||||
StrokeLine(left, right);
|
||||
} else {
|
||||
BPoint top((bounds.Width() / 2) + bounds.left, bounds.top);
|
||||
BPoint bottom(top.x, bounds.bottom);
|
||||
|
||||
BPoint fudge(PenSize(), PenSize());
|
||||
|
||||
top -= fudge;
|
||||
bottom -= fudge;
|
||||
SetHighColor(line);
|
||||
StrokeLine(top, bottom);
|
||||
|
||||
top += fudge;
|
||||
bottom += fudge;
|
||||
SetHighColor(shadow);
|
||||
StrokeLine(top, bottom);
|
||||
}
|
||||
|
||||
PopState();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Divider::GetPreferredSize(float* width, float* height)
|
||||
{
|
||||
if (fOrient == B_HORIZONTAL) {
|
||||
*width = Bounds().Width();
|
||||
*height = (PenSize() * 4); // Two widths for padding (either side) + line + shadow
|
||||
} else {
|
||||
*height = Bounds().Height();
|
||||
*width = (PenSize() * 4); // Two widths for padding (either side) + line + shadow
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Divider::Archive(BMessage* archive, bool deep) const
|
||||
{
|
||||
archive->AddInt32("orientation", fOrient);
|
||||
return BView::Archive(archive, false);
|
||||
}
|
||||
|
||||
|
||||
BArchivable*
|
||||
Divider::Instantiate(BMessage* archive)
|
||||
{
|
||||
BArchivable *instance = NULL;
|
||||
|
||||
if (validate_instantiation(archive, "Divider"))
|
||||
instance = new Divider(archive);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
orientation
|
||||
Divider::Orientation()
|
||||
{
|
||||
return fOrient;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Divider::Orientation(orientation orient)
|
||||
{
|
||||
fOrient = orient;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright 2009-2010, Pier Luigi Fiorini. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _DIVIDER_H
|
||||
#define _DIVIDER_H
|
||||
|
||||
#include <View.h>
|
||||
|
||||
class BMessage;
|
||||
class BMessenger;
|
||||
|
||||
class Divider : public BView {
|
||||
public:
|
||||
Divider(const char* name, uint32 flags = B_FRAME_EVENTS | B_WILL_DRAW);
|
||||
virtual ~Divider();
|
||||
|
||||
Divider(BMessage* archive);
|
||||
|
||||
virtual void Draw(BRect updateRect);
|
||||
virtual void GetPreferredSize(float* width, float* height);
|
||||
|
||||
status_t Archive(BMessage* archive, bool deep = true) const;
|
||||
|
||||
static BArchivable* Instantiate(BMessage* archive);
|
||||
|
||||
orientation Orientation();
|
||||
void Orientation(orientation orient);
|
||||
|
||||
private:
|
||||
orientation fOrient;
|
||||
};
|
||||
|
||||
#endif // _DIVIDER_H
|
|
@ -0,0 +1,12 @@
|
|||
SubDir TOP libs libinterface ;
|
||||
|
||||
SubDirSysHdrs [ FDirName $(TOP) libs ] ;
|
||||
|
||||
StaticLibrary libinterface.a :
|
||||
BitmapMenuItem.cpp
|
||||
BitmapUtils.cpp
|
||||
BitmapView.cpp
|
||||
Divider.cpp
|
||||
NotifyingTextView.cpp
|
||||
PictureView.cpp
|
||||
;
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright 2009-2010, Pier Luigi Fiorini. All rights reserved.
|
||||
* Copyright 2009, Michael Davidson. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Michael Davidson, slaad@bong.com.au
|
||||
* Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
|
||||
*/
|
||||
|
||||
#include <Messenger.h>
|
||||
|
||||
#include "NotifyingTextView.h"
|
||||
|
||||
|
||||
NotifyingTextView::NotifyingTextView(const char* name, uint32 flags)
|
||||
: BTextView(name, flags),
|
||||
fMessenger(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
NotifyingTextView::~NotifyingTextView()
|
||||
{
|
||||
if (fMessenger != NULL)
|
||||
delete fMessenger;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
NotifyingTextView::SetTarget(const BHandler* handler)
|
||||
{
|
||||
if (fMessenger != NULL)
|
||||
delete fMessenger;
|
||||
fMessenger = new BMessenger(handler);
|
||||
}
|
||||
|
||||
|
||||
BMessage*
|
||||
NotifyingTextView::Message() const
|
||||
{
|
||||
return fMessage;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
NotifyingTextView::SetMessage(BMessage* msg)
|
||||
{
|
||||
fMessage = msg;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
NotifyingTextView::InsertText(const char* text, int32 length, int32 offset,
|
||||
const text_run_array* runs)
|
||||
{
|
||||
if ((fMessenger != NULL) && fMessenger->IsValid()) {
|
||||
BMessage msg(*fMessage);
|
||||
msg.AddPointer("source", this);
|
||||
fMessenger->SendMessage(&msg);
|
||||
}
|
||||
|
||||
BTextView::InsertText(text, length, offset, runs);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
NotifyingTextView::DeleteText(int32 start, int32 finish)
|
||||
{
|
||||
if ((fMessenger != NULL) && fMessenger->IsValid()) {
|
||||
BMessage msg(*fMessage);
|
||||
msg.AddPointer("source", this);
|
||||
fMessenger->SendMessage(&msg);
|
||||
}
|
||||
|
||||
BTextView::DeleteText(start, finish);
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright 2009-2010, Pier Luigi Fiorini. All rights reserved.
|
||||
* Copyright 2009, Michael Davidson. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _NOTIFYING_TEXT_VIEW_H
|
||||
#define _NOTIFYING_TEXT_VIEW_H
|
||||
|
||||
#include <Handler.h>
|
||||
#include <Message.h>
|
||||
#include <TextView.h>
|
||||
|
||||
class BMessenger;
|
||||
|
||||
class NotifyingTextView : public BTextView {
|
||||
public:
|
||||
NotifyingTextView(const char* name, uint32 flags
|
||||
= B_WILL_DRAW | B_PULSE_NEEDED);
|
||||
~NotifyingTextView();
|
||||
|
||||
void SetTarget(const BHandler* handler);
|
||||
|
||||
BMessage* Message() const;
|
||||
void SetMessage(BMessage* msg);
|
||||
|
||||
protected:
|
||||
virtual void InsertText(const char* text, int32 length, int32 offset,
|
||||
const text_run_array* runs = NULL);
|
||||
virtual void DeleteText(int32 start, int32 finish);
|
||||
|
||||
private:
|
||||
BMessenger* fMessenger;
|
||||
BMessage* fMessage;
|
||||
};
|
||||
|
||||
#endif // _NOTIFYING_TEXT_VIEW_H
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright 2009, Pier Luigi Fiorini. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
|
||||
*/
|
||||
|
||||
#include <Bitmap.h>
|
||||
#include <TranslationUtils.h>
|
||||
|
||||
#include "PictureView.h"
|
||||
|
||||
|
||||
PictureView::PictureView(const char* name, const char* filename, uint32 flags)
|
||||
: BView(name, flags),
|
||||
fBitmap(NULL),
|
||||
fWidth(0.0f),
|
||||
fHeight(0.0f)
|
||||
{
|
||||
// Set transparent
|
||||
SetViewColor(B_TRANSPARENT_COLOR);
|
||||
|
||||
// Try to get the image
|
||||
fBitmap = BTranslationUtils::GetBitmap(filename);
|
||||
|
||||
if (fBitmap) {
|
||||
BRect frame(fBitmap->Bounds());
|
||||
|
||||
fWidth = frame.Width();
|
||||
fHeight = frame.Height();
|
||||
} else
|
||||
return;
|
||||
|
||||
ResizeTo(fWidth, fHeight);
|
||||
}
|
||||
|
||||
|
||||
PictureView::~PictureView()
|
||||
{
|
||||
delete fBitmap;
|
||||
fBitmap = NULL;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PictureView::InitCheck()
|
||||
{
|
||||
if (fBitmap != NULL)
|
||||
return B_OK;
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
BSize
|
||||
PictureView::MinSize()
|
||||
{
|
||||
return BSize(fWidth, fHeight);
|
||||
}
|
||||
|
||||
|
||||
BSize
|
||||
PictureView::MaxSize()
|
||||
{
|
||||
return MinSize();
|
||||
}
|
||||
|
||||
|
||||
BSize
|
||||
PictureView::PreferredSize()
|
||||
{
|
||||
return MinSize();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PictureView::Draw(BRect frame)
|
||||
{
|
||||
SetDrawingMode(B_OP_ALPHA);
|
||||
SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
|
||||
|
||||
if (fBitmap)
|
||||
DrawBitmap(fBitmap, BPoint(0, 0));
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright 2009, Pier Luigi Fiorini. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _PICTURE_VIEW_H
|
||||
#define _PICTURE_VIEW_H
|
||||
|
||||
#include <View.h>
|
||||
|
||||
class BBitmap;
|
||||
|
||||
class PictureView : public BView {
|
||||
public:
|
||||
PictureView(const char* name, const char* filename,
|
||||
uint32 flags = B_WILL_DRAW);
|
||||
~PictureView();
|
||||
|
||||
status_t InitCheck();
|
||||
|
||||
virtual BSize MinSize();
|
||||
virtual BSize MaxSize();
|
||||
virtual BSize PreferredSize();
|
||||
|
||||
virtual void Draw(BRect frame);
|
||||
|
||||
private:
|
||||
BBitmap* fBitmap;
|
||||
float fWidth;
|
||||
float fHeight;
|
||||
};
|
||||
|
||||
#endif // _PICTURE_VIEW_H
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* Copyright 2009, Pier Luigi Fiorini.
|
||||
* Copyright 2004-2009, René Nyffenegge
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
// Based on original code from:
|
||||
// http://www.adp-gmbh.ch/cpp/common/base64.html
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "Base64.h"
|
||||
|
||||
static const BString chars =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+/";
|
||||
|
||||
|
||||
Base64::Base64()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BString
|
||||
Base64::Encode(const uchar* data, size_t length)
|
||||
{
|
||||
BString encoded;
|
||||
int32 i = 0;
|
||||
uchar array3[3], array4[4];
|
||||
|
||||
while (length--) {
|
||||
array3[i++] = *(data++);
|
||||
|
||||
if (i == 3) {
|
||||
array4[0] = (uchar)((array3[0] & 0xfc) >> 2);
|
||||
array4[1] = (uchar)(((array3[0] & 0x03) << 4) + ((array3[1] & 0xf0) >> 4));
|
||||
array4[2] = (uchar)(((array3[1] & 0x0f) << 2) + ((array3[2] & 0xc0) >> 6));
|
||||
array4[3] = (uchar)(((array4[2] & 0x3) << 6) + array4[3]);
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
encoded += array3[i];
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i) {
|
||||
for (int32 j = i; j < 4; j++)
|
||||
array4[j] = 0;
|
||||
|
||||
for (int32 j = 0; j < 4; j++)
|
||||
array4[j] = (uchar)chars.FindFirst(array4[j]);
|
||||
|
||||
array3[0] = (uchar)((array4[0] << 2) + ((array4[i] & 0x30) >> 4));
|
||||
array3[1] = (uchar)(((array4[1] & 0xf) << 4) + ((array4[2] & 0x3c) >> 2));
|
||||
array3[2] = (uchar)(((array4[2] & 0x3) << 6) + array4[3]);
|
||||
|
||||
for (int32 j = 0; j < i - 1; j++)
|
||||
encoded += array3[j];
|
||||
}
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Base64::IsBase64(uchar c)
|
||||
{
|
||||
return isalnum(c) || (c == '+') || (c == '/');
|
||||
}
|
||||
|
||||
|
||||
BString
|
||||
Base64::Decode(const BString& data)
|
||||
{
|
||||
int32 length = data.Length();
|
||||
int32 i = 0;
|
||||
int32 index = 0;
|
||||
uchar array4[4], array3[3];
|
||||
BString decoded;
|
||||
|
||||
while (length-- && (data[index] != '=') && IsBase64(data[index])) {
|
||||
array4[i++] = data[index];
|
||||
index++;
|
||||
|
||||
if (i == 4) {
|
||||
for (i = 0; i < 4; i++)
|
||||
array4[i] = (uchar)chars.FindFirst(array4[i]);
|
||||
|
||||
array3[0] = (uchar)((array4[0] << 2) + ((array4[1] & 0x30)>> 4));
|
||||
array3[1] = (uchar)(((array4[1] & 0xf) << 4) + ((array4[2] & 0x3c) >> 2));
|
||||
array3[2] = (uchar)(((array4[2] & 0x3) << 6) + array4[3]);
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
decoded += array3[i];
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i) {
|
||||
int32 j;
|
||||
|
||||
for (j = i; j < 4; j++)
|
||||
array4[j] = 0;
|
||||
|
||||
for (j = 0; j < 4; j++)
|
||||
array4[j] = (uchar)chars.FindFirst(array4[j]);
|
||||
|
||||
array3[0] = (uchar)((array4[0] << 2) + ((array4[1] & 0x30) >> 4));
|
||||
array3[1] = (uchar)(((array4[1] & 0xf) << 4) + ((array4[2] & 0x3c) >> 2));
|
||||
array3[2] = (uchar)(((array4[2] & 0x3) << 6) + array4[3]);
|
||||
|
||||
for (j = 0; j < i - 1; j++)
|
||||
decoded += array3[j];
|
||||
}
|
||||
|
||||
return decoded;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright 2009, Pier Luigi Fiorini.
|
||||
* Copyright 2004-2009, René Nyffenegge
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _BASE_64_H
|
||||
#define _BASE_64_H
|
||||
|
||||
#include <String.h>
|
||||
|
||||
class Base64 {
|
||||
public:
|
||||
static bool IsBase64(uchar c);
|
||||
static BString Encode(const uchar* data, size_t length);
|
||||
static BString Decode(const BString& data);
|
||||
|
||||
private:
|
||||
Base64();
|
||||
};
|
||||
|
||||
#endif // _BASE_64_H
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* Copyright 2002, The Olmeki Team.
|
||||
* Distributed under the terms of the Olmeki License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "JabberAgent.h"
|
||||
#include "Logger.h"
|
||||
|
||||
|
||||
JabberAgent::JabberAgent()
|
||||
: fGroupChat(false),
|
||||
fSearchable(false),
|
||||
fTransport(false),
|
||||
fRegistration(false),
|
||||
fService(""),
|
||||
fName(""),
|
||||
fJid("")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
JabberAgent::~JabberAgent()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JabberAgent::PrintToStream()
|
||||
{
|
||||
logmsg("JabberAgent:");
|
||||
logmsg(" Name: %s", fName.String());
|
||||
logmsg(" Service: %s", fService.String());
|
||||
logmsg(" Jid: %s", fJid.String());
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
JabberAgent::HasGroupChat()
|
||||
{
|
||||
return fGroupChat;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
JabberAgent::IsTransport()
|
||||
{
|
||||
return fTransport;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
JabberAgent::Searchable()
|
||||
{
|
||||
return fSearchable;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
JabberAgent::AllowsRegistration()
|
||||
{
|
||||
return fRegistration;
|
||||
}
|
||||
|
||||
|
||||
BString
|
||||
JabberAgent::GetService() const
|
||||
{
|
||||
return fService;
|
||||
}
|
||||
|
||||
|
||||
BString
|
||||
JabberAgent::GetName() const
|
||||
{
|
||||
return fName;
|
||||
}
|
||||
|
||||
|
||||
BString
|
||||
JabberAgent::GetJid() const
|
||||
{
|
||||
return fJid;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JabberAgent::SetService(const BString& service)
|
||||
{
|
||||
fService = service;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JabberAgent::SetName(const BString& name)
|
||||
{
|
||||
fName = name;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JabberAgent::SetJid(const BString& jid)
|
||||
{
|
||||
fJid = jid;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JabberAgent::SetGroupChat(bool groupChat)
|
||||
{
|
||||
fGroupChat = groupChat;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JabberAgent::SetSearchable(bool searchable)
|
||||
{
|
||||
fSearchable = searchable;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JabberAgent::SetTransport(bool transport)
|
||||
{
|
||||
fTransport = transport;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JabberAgent::SetRegistration(bool registration)
|
||||
{
|
||||
fRegistration = registration;
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright 2002, The Olmeki Team.
|
||||
* Distributed under the terms of the Olmeki License.
|
||||
*/
|
||||
#ifndef _JABBER_AGENT_H
|
||||
#define _JABBER_AGENT_H
|
||||
|
||||
#include <String.h>
|
||||
|
||||
class JabberAgent {
|
||||
public:
|
||||
JabberAgent();
|
||||
~JabberAgent();
|
||||
|
||||
void PrintToStream();
|
||||
|
||||
bool HasGroupChat();
|
||||
bool Searchable();
|
||||
bool IsTransport();
|
||||
bool AllowsRegistration();
|
||||
|
||||
BString GetService() const;
|
||||
BString GetName() const;
|
||||
BString GetJid() const;
|
||||
BString GetInstructions() const;
|
||||
|
||||
void SetGroupChat(bool groupChat);
|
||||
void SetSearchable(bool searchable);
|
||||
void SetTransport(bool transport);
|
||||
void SetRegistration(bool registration);
|
||||
void SetService(const BString& service);
|
||||
void SetName(const BString& name);
|
||||
void SetJid(const BString& jid);
|
||||
|
||||
private:
|
||||
bool fGroupChat;
|
||||
bool fSearchable;
|
||||
bool fTransport;
|
||||
bool fRegistration;
|
||||
BString fService;
|
||||
BString fName;
|
||||
BString fJid;
|
||||
};
|
||||
|
||||
#endif // _JABBER_AGENT_H
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* Copyright 2002, The Olmeki Team.
|
||||
* Distributed under the terms of the Olmeki License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "JabberContact.h"
|
||||
#include "Logger.h"
|
||||
|
||||
JabberContact::JabberContact()
|
||||
: fPresence(new JabberPresence()),
|
||||
fId(""), fVCard(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
JabberContact::~JabberContact()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JabberContact::PrintToStream()
|
||||
{
|
||||
logmsg("JabberContact:");
|
||||
logmsg(" Name: %s", fName.String());
|
||||
logmsg(" Group: %s", fGroup.String());
|
||||
logmsg(" Jid: %s", fJid.String());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JabberContact::SetName(const BString& name)
|
||||
{
|
||||
fName = name;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JabberContact::SetGroup(const BString& group)
|
||||
{
|
||||
fGroup = group;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JabberContact::SetPresence(JabberPresence* presence)
|
||||
{
|
||||
fPresence = presence;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JabberContact::SetPresence()
|
||||
{
|
||||
delete fPresence;
|
||||
fPresence = new JabberPresence();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JabberContact::SetJid(const BString& jid)
|
||||
{
|
||||
fJid = jid;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JabberContact::SetVCard(JabberVCard* vCard)
|
||||
{
|
||||
fVCard = vCard;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JabberContact::SetSubscription(const BString& subscription)
|
||||
{
|
||||
fSubscription = subscription;
|
||||
}
|
||||
|
||||
|
||||
BString
|
||||
JabberContact::GetSubscription() const
|
||||
{
|
||||
return fSubscription;
|
||||
}
|
||||
|
||||
|
||||
BString
|
||||
JabberContact::GetName() const
|
||||
{
|
||||
return fName;
|
||||
}
|
||||
|
||||
|
||||
BString
|
||||
JabberContact::GetGroup() const
|
||||
{
|
||||
return fGroup;
|
||||
}
|
||||
|
||||
JabberPresence*
|
||||
JabberContact::GetPresence()
|
||||
{
|
||||
return fPresence;
|
||||
}
|
||||
|
||||
|
||||
BString
|
||||
JabberContact::GetJid() const
|
||||
{
|
||||
return fJid;
|
||||
}
|
||||
|
||||
|
||||
JabberVCard*
|
||||
JabberContact::GetVCard() const
|
||||
{
|
||||
return fVCard;
|
||||
}
|
||||
|
||||
|
||||
BString
|
||||
JabberContact::GetLastMessageID() const
|
||||
{
|
||||
return fId;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JabberContact::SetLastMessageID(const BString& id)
|
||||
{
|
||||
fId = id;
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright 2002, The Olmeki Team.
|
||||
* Distributed under the terms of the Olmeki License.
|
||||
*/
|
||||
#ifndef _JABBER_CONTACT_H
|
||||
#define _JABBER_CONTACT_H
|
||||
|
||||
#include <String.h>
|
||||
|
||||
#include "JabberPresence.h"
|
||||
#include "JabberVCard.h"
|
||||
|
||||
class JabberContact {
|
||||
public:
|
||||
JabberContact();
|
||||
virtual ~JabberContact();
|
||||
|
||||
void SetName(const BString& name);
|
||||
void SetGroup(const BString& group);
|
||||
void SetSubscription(const BString& group);
|
||||
virtual void SetPresence();
|
||||
virtual void SetPresence(JabberPresence* presence);
|
||||
void SetJid(const BString& jid);
|
||||
void SetVCard(JabberVCard* vCard);
|
||||
void PrintToStream();
|
||||
BString GetName() const;
|
||||
BString GetGroup() const;
|
||||
BString GetSubscription() const;
|
||||
JabberPresence* GetPresence();
|
||||
BString GetJid() const;
|
||||
JabberVCard* GetVCard() const;
|
||||
|
||||
BString GetLastMessageID() const;
|
||||
void SetLastMessageID(const BString& id);
|
||||
|
||||
private:
|
||||
BString fJid;
|
||||
BString fGroup;
|
||||
JabberPresence* fPresence;
|
||||
BString fName;
|
||||
BString fId;
|
||||
BString fSubscription;
|
||||
JabberVCard* fVCard;
|
||||
};
|
||||
|
||||
#endif // JABBER_CONTACT_H
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Copyright 2002, The Olmeki Team.
|
||||
* Distributed under the terms of the Olmeki License.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "JabberElement.h"
|
||||
|
||||
JabberElement::JabberElement()
|
||||
: fName(""),
|
||||
fData(""),
|
||||
fAttr(NULL),
|
||||
fAttrCount(-1)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
JabberElement::~JabberElement()
|
||||
{
|
||||
Free();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JabberElement::SetName(const BString& name)
|
||||
{
|
||||
fName = name;
|
||||
}
|
||||
|
||||
|
||||
BString
|
||||
JabberElement::GetName() const
|
||||
{
|
||||
return fName;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JabberElement::SetData(const BString& data)
|
||||
{
|
||||
fData = data;
|
||||
}
|
||||
|
||||
|
||||
BString
|
||||
JabberElement::GetData() const
|
||||
{
|
||||
return fData;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JabberElement::SetAttr(const char** attr)
|
||||
{
|
||||
Free();
|
||||
if (attr) {
|
||||
const char** a = attr;
|
||||
|
||||
fAttrCount = 0;
|
||||
|
||||
while (*a) {
|
||||
fAttrCount++;
|
||||
a++;
|
||||
}
|
||||
|
||||
fAttr = new char *[fAttrCount + 1];
|
||||
for (int32 i = 0; i < fAttrCount; i++) {
|
||||
fAttr[i] = new char[strlen(attr[i]) + 1];
|
||||
strcpy(fAttr[i], attr[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const char**
|
||||
JabberElement::GetAttr() const
|
||||
{
|
||||
return (const char **)fAttr;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
JabberElement::GetAttrCount() const
|
||||
{
|
||||
return fAttrCount;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JabberElement::Free()
|
||||
{
|
||||
if (fAttrCount != -1) {
|
||||
for (int32 i = 0; i < fAttrCount; i++)
|
||||
delete [] fAttr[i];
|
||||
delete fAttr;
|
||||
fAttr = NULL;
|
||||
fAttrCount = -1;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Ŝarĝante…
Reference in New Issue