Commit b651ed98 authored by geobra's avatar geobra Committed by Linus Jahn

Add Roster and deploy Roster data to qml (#12)

* Rename EchoBot to Kaidan
* Kaidan inherits QObject now
* Add RosterController and RosterItem
* Add minimal GUI for Roster (just a POC)
parent 5f264c56
# path to local compiled swift 3 lib
SWIFT3PATH = ../../swift-3.0
SWIFT3PATH = ../../../swift-3.0
# from swift-config
SWIFTCXX = -DSWIFTEN_STATIC -DBOOST_ALL_NO_LIB -DBOOST_SYSTEM_NO_DEPRECATED -DBOOST_SIGNALS_NO_DEPRECATION_WARNING -DSWIFT_EXPERIMENTAL_FT
SWIFTLIB = -lSwiften -lSwiften_Boost -lrt -lz -lssl -lcrypto -lxml2 -lresolv -lpthread -ldl -lm -lc -lstdc++
......@@ -17,12 +17,16 @@ LIBS += -L$${SWIFT3PATH}/Swiften -L$${SWIFT3PATH}/3rdParty/Boost $${SWIFTLIB}
DEFINES += BOOST_SIGNALS_NO_DEPRECATION_WARNING
SOURCES += source/main.cpp \
source/EchoBot.cpp
HEADERS += source/EchoBot.h \
source/EchoPayload.h \
source/EchoPayloadParserFactory.h \
source/EchoPayloadSerializer.h
source/Kaidan.cpp \
source/RosterContoller.cpp \
source/RosterItem.cpp
HEADERS += source/Kaidan.h \
source/EchoPayload.h \
source/EchoPayloadParserFactory.h \
source/EchoPayloadSerializer.h \
source/RosterContoller.h \
source/RosterItem.h
RESOURCES += resources/qml.qrc
......
import QtQuick 2.1
import QtQuick.Window 2.0
import harbour.kaidan 1.0
Window {
Rectangle {
visible: true
width: 360
height: 360
......@@ -17,4 +17,17 @@ Window {
text: qsTr("Hello World")
anchors.centerIn: parent
}
ListView {
width: 100; height: 100
model: kaidan.rosterController.rosterList
delegate: Rectangle {
height: 25
width: 100
Text { text: model.modelData.jid}
}
}
}
#include "EchoBot.h"
#include "Kaidan.h"
#include <iostream>
#include <boost/bind.hpp>
#include <boost/smart_ptr/make_shared.hpp>
#include "EchoPayload.h"
#include "RosterContoller.h"
EchoBot::EchoBot(NetworkFactories* networkFactories)
Kaidan::Kaidan(NetworkFactories* networkFactories, QObject *parent) :
rosterController_(new RosterController()), QObject(parent)
{
client = new Swift::Client("jid@...", "pass", networkFactories);
client->setAlwaysTrustCertificates();
client->onConnected.connect(boost::bind(&EchoBot::handleConnected, this));
client->onConnected.connect(boost::bind(&Kaidan::handleConnected, this));
client->onMessageReceived.connect(
boost::bind(&EchoBot::handleMessageReceived, this, _1));
boost::bind(&Kaidan::handleMessageReceived, this, _1));
client->onPresenceReceived.connect(
boost::bind(&EchoBot::handlePresenceReceived, this, _1));
boost::bind(&Kaidan::handlePresenceReceived, this, _1));
tracer = new Swift::ClientXMLTracer(client);
softwareVersionResponder = new Swift::SoftwareVersionResponder(client->getIQRouter());
softwareVersionResponder->setVersion("EchoBot", "1.0");
softwareVersionResponder->setVersion("Kaidan", "0.1");
softwareVersionResponder->start();
//...
client->addPayloadParserFactory(&echoPayloadParserFactory);
client->addPayloadSerializer(&echoPayloadSerializer);
//...
client->connect();
//...
}
EchoBot::~EchoBot()
Kaidan::~Kaidan()
{
client->removePayloadSerializer(&echoPayloadSerializer);
client->removePayloadParserFactory(&echoPayloadParserFactory);
//...
softwareVersionResponder->stop();
delete softwareVersionResponder;
delete tracer;
delete client;
//...
}
//...
delete rosterController_;
}
void EchoBot::handlePresenceReceived(Presence::ref presence)
void Kaidan::handlePresenceReceived(Presence::ref presence)
{
// Automatically approve subscription requests
if (presence->getType() == Swift::Presence::Subscribe)
......@@ -54,34 +54,20 @@ void EchoBot::handlePresenceReceived(Presence::ref presence)
}
}
void EchoBot::handleConnected()
{
// Request the roster
Swift::GetRosterRequest::ref rosterRequest =
Swift::GetRosterRequest::create(client->getIQRouter());
rosterRequest->onResponse.connect(
bind(&EchoBot::handleRosterReceived, this, _2));
rosterRequest->send();
}
void EchoBot::handleRosterReceived(ErrorPayload::ref error)
void Kaidan::handleConnected()
{
if (error)
{
std::cerr << "Error receiving roster. Continuing anyway.";
}
// Send initial available presence
client->sendPresence(Presence::create("Send me a message"));
// Request the roster
rosterController_->requestRosterFromClient(client);
}
//...
void EchoBot::handleMessageReceived(Message::ref message)
void Kaidan::handleMessageReceived(Message::ref message)
{
//...
// Echo back the incoming message
message->setTo(message->getFrom());
message->setFrom(JID());
//...
if (!message->getPayload<EchoPayload>())
{
boost::shared_ptr<EchoPayload> echoPayload = boost::make_shared<EchoPayload>();
......@@ -91,3 +77,7 @@ void EchoBot::handleMessageReceived(Message::ref message)
}
}
RosterController* Kaidan::getRosterController()
{
return rosterController_;
}
#ifndef ECHOBOT_H
#define ECHPBOT_H
#ifndef KAIDAN_H
#define KAIDAN_H
#include <Swiften/Swiften.h>
#include <QObject>
#include <QStringList>
#include <Swiften/Swiften.h>
#include "EchoPayloadParserFactory.h"
#include "EchoPayloadSerializer.h"
class EchoBot
class RosterController;
class Kaidan : public QObject
{
//Q_OBJECT
Q_OBJECT
Q_PROPERTY(RosterController* rosterController READ getRosterController NOTIFY rosterControllerChanged)
public:
EchoBot(Swift::NetworkFactories* networkFactories);
~EchoBot();
Kaidan(Swift::NetworkFactories* networkFactories, QObject *parent = 0);
~Kaidan();
private slots:
RosterController* getRosterController();
signals:
void rosterControllerChanged();
private:
void handlePresenceReceived(Swift::Presence::ref presence);
void handleConnected();
void handleRosterReceived(Swift::ErrorPayload::ref error);
void handleMessageReceived(Swift::Message::ref message);
private:
Swift::Client* client;
Swift::ClientXMLTracer* tracer;
Swift::SoftwareVersionResponder* softwareVersionResponder;
EchoPayloadParserFactory echoPayloadParserFactory;
EchoPayloadSerializer echoPayloadSerializer;
RosterController* rosterController_;
};
#endif
#include "RosterContoller.h"
#include <QQmlContext>
RosterController::RosterController(QObject *parent) : QObject(parent), client_(NULL), rosterList_()
{
//rosterList_.append(new RosterItem(QString("lala@lala.de"), QString("lala"), None));
}
void RosterController::requestRosterFromClient(Swift::Client *client)
{
client_ = client;
client_->requestRoster();
Swift::GetRosterRequest::ref rosterRequest = Swift::GetRosterRequest::create(client->getIQRouter());
rosterRequest->onResponse.connect(bind(&RosterController::handleRosterReceived, this, _2));
rosterRequest->send();
}
void RosterController::handleRosterReceived(Swift::ErrorPayload::ref error)
{
if (error)
{
std::cerr << "Error receiving roster. Continuing anyway.";
}
else
{
std::cout << "handleRosterReceived!!!" << std::endl;
Swift::XMPPRoster* roster = client_->getRoster();
std::vector<Swift::XMPPRosterItem> rosterItems = roster->getItems();
std::vector<Swift::XMPPRosterItem>::iterator it;
std::cout << "size: " << rosterItems.size() << std::endl;
for(it = rosterItems.begin(); it < rosterItems.end(); it++ )
{
#if 0
std::cout << "jid: " << (*it).getJID().toString() <<
", Name: " << (*it).getName() <<
", Subscription: " << (*it).getSubscription() << std::endl;
#endif
rosterList_.append(new RosterItem(QString::fromStdString((*it).getJID().toString()),
QString::fromStdString((*it).getName()),
(Subscription)(*it).getSubscription()));
emit rosterListChanged();
}
}
}
QQmlListProperty<RosterItem> RosterController::getRosterList()
{
return QQmlListProperty<RosterItem>(this, rosterList_);
}
#ifndef ROSTERCONTROLLER_H
#define ROSTERCONTROLLER_H
#include "RosterItem.h"
#include <Swiften/Swiften.h>
#include <QObject>
#include <QQmlListProperty>
class RosterController : public QObject
{
Q_OBJECT
//Q_PROPERTY(QList<QObject*> rosterList READ getRosterList NOTIFY rosterListChanged)
Q_PROPERTY(QQmlListProperty<RosterItem> rosterList READ getRosterList NOTIFY rosterListChanged)
public:
RosterController(QObject *parent = 0);
void requestRosterFromClient(Swift::Client *client);
//QList<QObject*> getRosterList();
QQmlListProperty<RosterItem> getRosterList();
signals:
void rosterListChanged();
public slots:
private:
void handleRosterReceived(Swift::ErrorPayload::ref error);
Swift::Client* client_;
//QList<QObject*> rosterList_;
QList<RosterItem*> rosterList_;
};
#endif // ROSTERCONTROLLER_H
#include "RosterItem.h"
RosterItem::RosterItem(QObject *parent) : QObject(parent), subscription_(None), jid_(""), name_("")
{
}
RosterItem::RosterItem(const QString &jid, const QString &name, const Subscription &subscription, QObject* parent) :
QObject(parent), jid_(jid), name_(name), subscription_(subscription)
{
}
QString RosterItem::getName()
{
return name_;
}
void RosterItem::setName(const QString &name)
{
name_ = name;
emit nameChanged();
}
QString RosterItem::getJid()
{
return jid_;
}
void RosterItem::setJid(const QString &jid)
{
jid_ = jid;
emit jidChanged();
}
Subscription RosterItem::getSubscription()
{
return subscription_;
}
void RosterItem::setSubscription(const Subscription &subscription)
{
subscription_ = subscription;
emit subscriptionChanged();
}
#ifndef ROSTERITEM_H
#define ROSTERITEM_H
#include <QObject>
enum Subscription
{ None,
To,
From,
Both,
Remove
};
class RosterItem : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ getName WRITE setName NOTIFY nameChanged)
Q_PROPERTY(QString jid READ getJid WRITE setJid NOTIFY jidChanged)
Q_PROPERTY(Subscription subscription READ getSubscription WRITE setSubscription NOTIFY subscriptionChanged)
public:
explicit RosterItem(QObject *parent = 0);
RosterItem(const QString& jid, const QString& name, const Subscription& subscription, QObject* parent = 0);
QString getName();
void setName(const QString& name);
QString getJid();
void setJid(const QString& jid);
Subscription getSubscription();
void setSubscription(const Subscription& subscription);
signals:
void nameChanged();
void jidChanged();
void subscriptionChanged();
public slots:
private:
QString jid_;
QString name_;
Subscription subscription_;
};
#endif // ROSTERITEM_H
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickView>
#include <QQmlContext>
#include <QtQml>
#include "Swiften/EventLoop/Qt/QtEventLoop.h"
#include "EchoBot.h"
#include "Kaidan.h"
#include "RosterContoller.h"
#include "RosterItem.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
qmlRegisterType<RosterController>( "harbour.kaidan", 1, 0, "RosterController");
qmlRegisterType<RosterItem>( "harbour.kaidan", 1, 0, "RosterItem");
// FIXME rewrite binds to qt specific versions
// FIXME test connects from QtEventLoop (Swiften) to QGuiApplication
QGuiApplication app(argc, argv);
QtEventLoop eventLoop;
BoostNetworkFactories networkFactories(&eventLoop);
EchoBot bot(&networkFactories);
Kaidan kaidan(&networkFactories);
QQuickView view;
QQmlContext *ctxt = view.rootContext();
ctxt->setContextProperty("kaidan", &kaidan);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
view.setSource(QUrl::fromLocalFile("main.qml"));
view.show();
return app.exec();
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment