return m;
}
+QVariantMap RibbonAccounts::context(PurpleBuddy* buddy)
+{
+ PurpleAccount* p_acct = purple_buddy_get_account(buddy);
+ QVariantMap m = context(p_acct);
+ m["buddy"] = QString::fromUtf8(purple_buddy_get_name(buddy));
+ return m;
+}
+
void RibbonAccounts::handleExternalEvent(QString method, QVariantMap params)
{
qDebug() << "called" << method << "on" << params;
RibbonAccounts(RibbonManager* parent = 0);
~RibbonAccounts();
static QVariantMap context(PurpleAccount* acct);
+ static QVariantMap context(PurpleBuddy* buddy);
public slots:
void handleExternalEvent(QString method, QVariantMap params);
signals:
#include "ribbonblist.h"
#include "ribbonmanager.h"
+#include "ribbonaccounts.h"
#include <QDebug>
+#include <QDateTime>
RibbonBlist::RibbonBlist(RibbonManager* parent) : QObject((QObject*)parent)
{
{
}
-static void buddy_signed_on(PurpleBuddy* buddy, void* data)
+static void buddy_status_changed(PurpleBuddy* buddy, PurpleStatus* old_status,
+ PurpleStatus* status, void* data)
{
- qDebug() << purple_buddy_get_contact_alias(buddy) << "signed on";
+ Q_UNUSED(old_status);
+ PurplePresence* presence = purple_status_get_presence(status);
+ PurpleStatusType* status_type = purple_status_get_type(status);
+
+ // Some debugging info
+ qDebug() << "status change:" << purple_buddy_get_contact_alias(buddy);
+ qDebug() << "\tavailable:" << purple_presence_is_available(presence);
+ qDebug() << "\tonline:" << purple_presence_is_online(presence);
+ qDebug() << "\ttype_id:" << purple_status_type_get_id(status_type);
+ qDebug() << "\ttype_name:" << purple_status_type_get_name(status_type);
+
+ // Get status message, if one is available
+ QString message("");
+ PurplePlugin* prpl = purple_find_prpl(purple_account_get_protocol_id(purple_buddy_get_account(buddy)));
+ if (prpl != NULL) {
+ PurplePluginProtocolInfo* prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
+ if (prpl_info && prpl_info->status_text && purple_account_get_connection(purple_buddy_get_account(buddy))) {
+ char* msg = prpl_info->status_text(buddy);
+ message = QString::fromUtf8(msg);
+ qDebug() << "\tstatus:" << message;
+ }
+ }
+
+ QVariantMap m = RibbonAccounts::context(buddy);
+ // Include the buddy's new status
+ QVariantMap m_status;
+ m_status["status"] = QString::fromUtf8(purple_status_type_get_id(status_type));
+ m_status["status_msg"] = message;
+ m_status["idle"] = purple_presence_is_idle(presence);
+ // Only include idle information if the user is flagged as idle
+ if (purple_presence_is_idle(presence)) {
+ // libpurple gives us a localized time_t for when the user went idle
+ QVariantMap idle_data;
+ idle_data["idle_time"] = QDateTime::fromTime_t(purple_presence_get_idle_time(presence));
+ m_status["idle_data"] = idle_data;
+ }
- PurpleAccount* acct = purple_buddy_get_account(buddy);
- QVariantMap m;
- m["proto"] = QString::fromUtf8(purple_account_get_protocol_id(acct));
- m["account"] = QString::fromUtf8(purple_account_get_username(acct));
- m["buddy"] = QString::fromUtf8(purple_buddy_get_name(buddy));
+ m["status"] = m_status;
+ RibbonBlist* blist = (RibbonBlist*)data;
+ blist->event(QString::fromUtf8("blist"),
+ QString::fromUtf8("buddy_status_changed"),
+ m);
+}
+static void buddy_signed_on(PurpleBuddy* buddy, void* data)
+{
+ qDebug() << purple_buddy_get_contact_alias(buddy) << "signed on";
+ QVariantMap m = RibbonAccounts::context(buddy);
RibbonBlist* blist = (RibbonBlist*)data;
blist->event(QString::fromUtf8("blist"),
QString::fromUtf8("buddy_signed_on"),
m);
}
+static void buddy_signed_off(PurpleBuddy* buddy, void* data)
+{
+ qDebug() << purple_buddy_get_contact_alias(buddy) << "signed off";
+ QVariantMap m = RibbonAccounts::context(buddy);
+ RibbonBlist* blist = (RibbonBlist*)data;
+ blist->event(QString::fromUtf8("blist"),
+ QString::fromUtf8("buddy_signed_off"),
+ m);
+}
+
void RibbonBlist::init()
{
/* Create and load the buddylist */
void *blist_handle = purple_blist_get_handle();
purple_signal_connect(blist_handle, "buddy-signed-on", &handle,
PURPLE_CALLBACK(buddy_signed_on), this);
+ purple_signal_connect(blist_handle, "buddy-signed-off", &handle,
+ PURPLE_CALLBACK(buddy_signed_off), this);
+ purple_signal_connect(blist_handle, "buddy-status-changed", &handle,
+ PURPLE_CALLBACK(buddy_status_changed), this);
}
#include "ribbonconversations.h"
+#include "ribbonaccounts.h"
#include "ribbonmanager.h"
#include "ribbonutil.h"
static void static_received_im_msg(PurpleAccount *account, char *sender, char *message,
PurpleConversation *conv, PurpleMessageFlags flags, void* data)
{
- Q_UNUSED(data);
- RibbonManager* r = static_cast<RibbonManager*>(account->ui_data);
- r->conversations()->received_im_msg(account, sender, message, conv, flags);
+ RibbonConversations* c = (RibbonConversations*)data;
+ c->received_im_msg(account, sender, message, conv, flags);
+}
+
+static void static_buddy_typing(PurpleAccount* account, const char* name, void* data)
+{
+ RibbonConversations* c = (RibbonConversations*)data;
+ c->buddy_typing(account, name, RibbonConversations::TYPING);
+}
+
+static void static_buddy_typing_stopped(PurpleAccount* account, const char* name, void* data)
+{
+ RibbonConversations* c = (RibbonConversations*)data;
+ c->buddy_typing(account, name, RibbonConversations::STOPPED);
}
RibbonConversations::RibbonConversations(RibbonManager* parent) : QObject((QObject*)parent)
static int handle;
void *conversations_handle = purple_conversations_get_handle();
purple_signal_connect(conversations_handle, "received-im-msg", &handle,
- PURPLE_CALLBACK(static_received_im_msg), NULL);
+ PURPLE_CALLBACK(static_received_im_msg), this);
+ purple_signal_connect(conversations_handle, "buddy-typing", &handle,
+ PURPLE_CALLBACK(static_buddy_typing), this);
+ purple_signal_connect(conversations_handle, "buddy-typing-stopped", &handle,
+ PURPLE_CALLBACK(static_buddy_typing_stopped), this);
}
void RibbonConversations::received_im_msg(PurpleAccount *account,
char *sender, char *message, PurpleConversation *conv,
PurpleMessageFlags flags) {
Q_UNUSED(flags);
- if (conv==NULL) {
+ if (conv == NULL) {
conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, sender);
}
+ QVariantMap m = RibbonAccounts::context(account);
+ m["buddy"] = QString::fromUtf8(sender);
+ m["timestamp"] = QDateTime::currentDateTimeUtc();
+ m["message"] = QString::fromUtf8(message);
+ emit event(QString::fromUtf8("conversations"),
+ QString::fromUtf8("recv_im"),
+ m);
qDebug() << QDateTime::currentDateTime().toString("hh:mm:ss") << sender << purple_conversation_get_name(conv) << message;
}
+void RibbonConversations::buddy_typing(PurpleAccount *account, const char* buddy, TypingState state)
+{
+ QVariantMap m = RibbonAccounts::context(account);
+ m["buddy"] = QString::fromUtf8(buddy);
+ switch (state) {
+ case STOPPED: m["state"] = QString::fromUtf8("stopped"); break;
+ case TYPING: m["state"] = QString::fromUtf8("typing"); break;
+ }
+ qDebug() << buddy << "type state is" << m["state"];
+ emit event(QString::fromUtf8("conversations"),
+ QString::fromUtf8("buddy_typing_state"),
+ m);
+}
+
void RibbonConversations::send_im(QString protocol, QString account, QString buddy, QString message)
{
qDebug() << "sending im from" << protocol << account << "to" << buddy << ":" << message;
PurpleAccount* p_acct = purple_accounts_find(account.toUtf8(), protocol.toUtf8());
- PurpleBuddy* p_buddy = purple_find_buddy(p_acct, buddy.toUtf8());
- // TODO: call the purple functions to send an IM
- Q_UNUSED(p_buddy);
+ if (!p_acct) {
+ qWarning() << "No such account" << protocol << account;
+ return;
+ }
+ PurpleConversation* p_conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,
+ buddy.toUtf8(), p_acct);
+ if (!p_conv) {
+ // Lazily create conversation objects if needed
+ p_conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, p_acct, buddy.toUtf8());
+ }
+ PurpleConvIm* p_conv_im = purple_conversation_get_im_data(p_conv);
+ purple_conv_im_send(p_conv_im, message.toUtf8());
}
void RibbonConversations::handleExternalEvent(QString method, QVariantMap context)
class RibbonConversations : public QObject {
Q_OBJECT
public:
+ enum TypingState {
+ STOPPED = 0,
+ TYPING = 1,
+ };
RibbonConversations(RibbonManager* parent = 0);
~RibbonConversations();
void init();
void received_im_msg(PurpleAccount *account, char *sender, char *message,
PurpleConversation *conv, PurpleMessageFlags flags);
+ void buddy_typing(PurpleAccount *account, const char* buddy, TypingState state);
void handleExternalEvent(QString method, QVariantMap context);
signals:
void event(QString source, QString signal, QVariantMap context);
void RibbonManager::handleExternalEvent(QString destination, QString method, QVariantMap context)
{
- // TODO: handle external event
- qDebug() << "TODO: do something with" << destination << "." << method << "(" << context << ")";
if (destination == "accounts") {
_accounts->handleExternalEvent(method, context);
} else if (destination == "conversations") {
_conversations->handleExternalEvent(method, context);
+ } else {
+ qDebug() << "TODO: do something with" << destination << "." << method << "(" << context << ")";
}
}