aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--connection.cpp155
-rw-r--r--connection.h32
-rw-r--r--connectiondata.cpp8
-rw-r--r--connectiondata.h4
-rw-r--r--connectionprivate.cpp126
-rw-r--r--connectionprivate.h66
-rw-r--r--events/event.cpp10
-rw-r--r--events/event.h12
-rw-r--r--jobs/basejob.cpp2
-rw-r--r--jobs/roommessagesjob.cpp7
-rw-r--r--jobs/roommessagesjob.h5
-rw-r--r--jobs/syncjob.cpp3
-rw-r--r--jobs/syncjob.h5
-rw-r--r--room.cpp96
-rw-r--r--room.h3
-rw-r--r--settings.cpp102
-rw-r--r--settings.h97
18 files changed, 382 insertions, 353 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8be4be70..ea340476 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -37,11 +37,11 @@ message( STATUS )
set(libqmatrixclient_SRCS
connectiondata.cpp
connection.cpp
- connectionprivate.cpp
room.cpp
user.cpp
logmessage.cpp
state.cpp
+ settings.cpp
events/event.cpp
events/roommessageevent.cpp
events/roomnameevent.cpp
diff --git a/connection.cpp b/connection.cpp
index 904649bc..98ff914a 100644
--- a/connection.cpp
+++ b/connection.cpp
@@ -18,7 +18,7 @@
#include "connection.h"
#include "connectiondata.h"
-#include "connectionprivate.h"
+//#include "connectionprivate.h"
#include "user.h"
#include "events/event.h"
#include "room.h"
@@ -33,15 +33,42 @@
#include "jobs/syncjob.h"
#include "jobs/mediathumbnailjob.h"
+#include <QtNetwork/QDnsLookup>
#include <QtCore/QDebug>
using namespace QMatrixClient;
+class Connection::Private
+{
+ public:
+ explicit Private(QUrl serverUrl)
+ : q(nullptr)
+ , data(new ConnectionData(serverUrl))
+ , isConnected(false)
+ , syncJob(nullptr)
+ { }
+ Private(Private&) = delete;
+ ~Private() { delete data; }
+
+ Connection* q;
+ ConnectionData* data;
+ QHash<QString, Room*> roomMap;
+ QHash<QString, User*> userMap;
+ bool isConnected;
+ QString username;
+ QString password;
+ QString userId;
+
+ SyncJob* syncJob;
+
+ SyncJob* startSyncJob(const QString& filter, int timeout);
+};
+
Connection::Connection(QUrl server, QObject* parent)
: QObject(parent)
+ , d(new Private(server))
{
- d = new ConnectionPrivate(this);
- d->data = new ConnectionData(server);
+ d->q = this; // All d initialization should occur before this line
}
Connection::Connection()
@@ -56,14 +83,32 @@ Connection::~Connection()
void Connection::resolveServer(QString domain)
{
- d->resolveServer( domain );
+ // Find the Matrix server for the given domain.
+ QScopedPointer<QDnsLookup, QScopedPointerDeleteLater> dns { new QDnsLookup() };
+ dns->setType(QDnsLookup::SRV);
+ dns->setName("_matrix._tcp." + domain);
+
+ dns->lookup();
+ connect(dns.data(), &QDnsLookup::finished, [&]() {
+ // Check the lookup succeeded.
+ if (dns->error() != QDnsLookup::NoError ||
+ dns->serviceRecords().isEmpty()) {
+ emit resolveError("DNS lookup failed");
+ return;
+ }
+
+ // Handle the results.
+ auto record = dns->serviceRecords().front();
+ d->data->setHost(record.target());
+ d->data->setPort(record.port());
+ emit resolved();
+ });
}
void Connection::connectToServer(QString user, QString password)
{
PasswordLogin* loginJob = new PasswordLogin(d->data, user, password);
connect( loginJob, &PasswordLogin::success, [=] () {
- qDebug() << "Our user ID: " << loginJob->id();
connectWithToken(loginJob->id(), loginJob->token());
});
connect( loginJob, &PasswordLogin::failure, [=] () {
@@ -79,7 +124,9 @@ void Connection::connectWithToken(QString userId, QString token)
d->isConnected = true;
d->userId = userId;
d->data->setToken(token);
- qDebug() << "Connected with token:";
+ qDebug() << "Accessing" << d->data->baseUrl()
+ << "by user" << userId
+ << "with the following access token:";
qDebug() << token;
emit connected();
}
@@ -98,6 +145,12 @@ void Connection::reconnect()
loginJob->start();
}
+void Connection::disconnectFromServer()
+{
+ d->syncJob->abandon();
+ d->isConnected = false;
+}
+
void Connection::logout()
{
auto job = new LogoutJob(d->data);
@@ -107,27 +160,39 @@ void Connection::logout()
SyncJob* Connection::sync(int timeout)
{
- QString filter = "{\"room\": { \"timeline\": { \"limit\": 100 } } }";
- SyncJob* syncJob = new SyncJob(d->data, d->data->lastEvent());
- syncJob->setFilter(filter);
- syncJob->setTimeout(timeout);
- connect( syncJob, &SyncJob::success, [=] () {
- d->data->setLastEvent(syncJob->nextBatch());
- for( const auto roomData: syncJob->roomData() )
+ if (d->syncJob)
+ return d->syncJob;
+
+ const QString filter = "{\"room\": { \"timeline\": { \"limit\": 100 } } }";
+ auto job = d->startSyncJob(filter, timeout);
+ connect( job, &SyncJob::success, [=] () {
+ d->data->setLastEvent(job->nextBatch());
+ for( const auto& roomData: job->roomData() )
{
- if ( Room* r = d->provideRoom(roomData.roomId) )
+ if ( Room* r = provideRoom(roomData.roomId) )
r->updateData(roomData);
}
+ d->syncJob = nullptr;
emit syncDone();
});
- connect( syncJob, &SyncJob::failure, [=] () {
- if (syncJob->error() == BaseJob::ContentAccessError)
- emit loginError(syncJob->errorString());
+ connect( job, &SyncJob::failure, [=] () {
+ d->syncJob = nullptr;
+ if (job->error() == BaseJob::ContentAccessError)
+ emit loginError(job->errorString());
else
- emit connectionError(syncJob->errorString());
+ emit connectionError(job->errorString());
});
+ return job;
+}
+
+SyncJob* Connection::Private::startSyncJob(const QString& filter, int timeout)
+{
+ syncJob = new SyncJob(data, data->lastEvent());
+ syncJob->setFilter(filter);
+ syncJob->setTimeout(timeout);
syncJob->start();
return syncJob;
+
}
void Connection::postMessage(Room* room, QString type, QString message)
@@ -147,7 +212,7 @@ void Connection::joinRoom(QString roomAlias)
{
JoinRoomJob* job = new JoinRoomJob(d->data, roomAlias);
connect( job, &SyncJob::success, [=] () {
- if ( Room* r = d->provideRoom(job->roomId()) )
+ if ( Room* r = provideRoom(job->roomId()) )
emit joinedRoom(r);
});
job->start();
@@ -159,12 +224,12 @@ void Connection::leaveRoom(Room* room)
job->start();
}
-void Connection::getMembers(Room* room)
-{
- RoomMembersJob* job = new RoomMembersJob(d->data, room);
- connect( job, &RoomMembersJob::result, d, &ConnectionPrivate::gotRoomMembers );
- job->start();
-}
+//void Connection::getMembers(Room* room)
+//{
+// RoomMembersJob* job = new RoomMembersJob(d->data, room);
+// connect( job, &RoomMembersJob::result, d, &ConnectionPrivate::gotRoomMembers );
+// job->start();
+//}
RoomMessagesJob* Connection::getMessages(Room* room, QString from)
{
@@ -180,6 +245,11 @@ MediaThumbnailJob* Connection::getThumbnail(QUrl url, int requestedWidth, int re
return job;
}
+QUrl Connection::homeserver() const
+{
+ return d->data->baseUrl();
+}
+
User* Connection::user(QString userId)
{
if( d->userMap.contains(userId) )
@@ -196,14 +266,19 @@ User *Connection::user()
return user(d->userId);
}
-QString Connection::userId()
+QString Connection::userId() const
{
return d->userId;
}
-QString Connection::token()
+QString Connection::token() const
{
- return d->data->token();
+ return accessToken();
+}
+
+QString Connection::accessToken() const
+{
+ return d->data->accessToken();
}
QHash< QString, Room* > Connection::roomMap() const
@@ -221,6 +296,30 @@ ConnectionData* Connection::connectionData()
return d->data;
}
+Room* Connection::provideRoom(QString id)
+{
+ if (id.isEmpty())
+ {
+ qDebug() << "Connection::provideRoom() with empty id, doing nothing";
+ return nullptr;
+ }
+
+ if (d->roomMap.contains(id))
+ return d->roomMap.value(id);
+
+ // Not yet in the map, create a new one.
+ Room* room = createRoom(id);
+ if (room)
+ {
+ d->roomMap.insert( id, room );
+ emit newRoom(room);
+ } else {
+ qCritical() << "Failed to create a room!!!" << id;
+ }
+
+ return room;
+}
+
User* Connection::createUser(QString userId)
{
return new User(userId, this);
diff --git a/connection.h b/connection.h
index f3a15cba..c221d7eb 100644
--- a/connection.h
+++ b/connection.h
@@ -20,6 +20,7 @@
#define QMATRIXCLIENT_CONNECTION_H
#include <QtCore/QObject>
+#include <QtCore/QUrl>
namespace QMatrixClient
{
@@ -48,6 +49,7 @@ namespace QMatrixClient
Q_INVOKABLE virtual void connectToServer( QString user, QString password );
Q_INVOKABLE virtual void connectWithToken( QString userId, QString token );
Q_INVOKABLE virtual void reconnect();
+ Q_INVOKABLE virtual void disconnectFromServer();
Q_INVOKABLE virtual void logout();
Q_INVOKABLE virtual SyncJob* sync(int timeout=-1);
@@ -55,14 +57,17 @@ namespace QMatrixClient
Q_INVOKABLE virtual PostReceiptJob* postReceipt( Room* room, Event* event );
Q_INVOKABLE virtual void joinRoom( QString roomAlias );
Q_INVOKABLE virtual void leaveRoom( Room* room );
- Q_INVOKABLE virtual void getMembers( Room* room );
+// Q_INVOKABLE virtual void getMembers( Room* room );
Q_INVOKABLE virtual RoomMessagesJob* getMessages( Room* room, QString from );
virtual MediaThumbnailJob* getThumbnail( QUrl url, int requestedWidth, int requestedHeight );
- Q_INVOKABLE virtual User* user(QString userId);
- Q_INVOKABLE virtual User* user();
- Q_INVOKABLE virtual QString userId();
- Q_INVOKABLE virtual QString token();
+ Q_INVOKABLE QUrl homeserver() const;
+ Q_INVOKABLE User* user(QString userId);
+ Q_INVOKABLE User* user();
+ Q_INVOKABLE QString userId() const;
+ /** @deprecated Use accessToken() instead. */
+ Q_INVOKABLE QString token() const;
+ Q_INVOKABLE QString accessToken() const;
signals:
void resolved();
@@ -81,11 +86,22 @@ namespace QMatrixClient
protected:
/**
- * Access the underlying ConnectionData class
+ * @brief Access the underlying ConnectionData class
*/
ConnectionData* connectionData();
/**
+ * @brief Find a (possibly new) Room object for the specified id
+ * Use this method whenever you need to find a Room object in
+ * the local list of rooms. Note that this does not interact with
+ * the server; in particular, does not automatically create rooms
+ * on the server.
+ * @return a pointer to a Room object with the specified id; nullptr
+ * if roomId is empty if createRoom() failed to create a Room object.
+ */
+ Room* provideRoom(QString roomId);
+
+ /**
* makes it possible for derived classes to have its own User class
*/
virtual User* createUser(QString userId);
@@ -96,8 +112,8 @@ namespace QMatrixClient
virtual Room* createRoom(QString roomId);
private:
- friend class ConnectionPrivate;
- ConnectionPrivate* d;
+ class Private;
+ Private* d;
};
}
diff --git a/connectiondata.cpp b/connectiondata.cpp
index 4a3bd47f..72e8f3d8 100644
--- a/connectiondata.cpp
+++ b/connectiondata.cpp
@@ -29,7 +29,7 @@ class ConnectionData::Private
QUrl baseUrl;
//bool isConnected;
- QString token;
+ QString accessToken;
QString lastEvent;
QNetworkAccessManager* nam;
};
@@ -52,9 +52,9 @@ ConnectionData::~ConnectionData()
// return d->isConnected;
// }
-QString ConnectionData::token() const
+QString ConnectionData::accessToken() const
{
- return d->token;
+ return d->accessToken;
}
QUrl ConnectionData::baseUrl() const
@@ -69,7 +69,7 @@ QNetworkAccessManager* ConnectionData::nam() const
void ConnectionData::setToken(QString token)
{
- d->token = token;
+ d->accessToken = token;
}
void ConnectionData::setHost(QString host)
diff --git a/connectiondata.h b/connectiondata.h
index 6407780c..5c8342d7 100644
--- a/connectiondata.h
+++ b/connectiondata.h
@@ -32,11 +32,11 @@ namespace QMatrixClient
virtual ~ConnectionData();
//bool isConnected() const;
- QString token() const;
+ QString accessToken() const;
QUrl baseUrl() const;
QNetworkAccessManager* nam() const;
- void setToken( QString token );
+ void setToken( QString accessToken );
void setHost( QString host );
void setPort( int port );
diff --git a/connectionprivate.cpp b/connectionprivate.cpp
deleted file mode 100644
index 6556a8ee..00000000
--- a/connectionprivate.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-/******************************************************************************
- * Copyright (C) 2015 Felix Rohrbach <kde@fxrh.de>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "connectionprivate.h"
-#include "connection.h"
-#include "state.h"
-#include "room.h"
-#include "user.h"
-#include "jobs/passwordlogin.h"
-#include "jobs/syncjob.h"
-#include "jobs/joinroomjob.h"
-#include "jobs/roommembersjob.h"
-#include "events/event.h"
-#include "events/roommessageevent.h"
-#include "events/roommemberevent.h"
-
-#include <QtCore/QDebug>
-#include <QtNetwork/QDnsLookup>
-
-using namespace QMatrixClient;
-
-ConnectionPrivate::ConnectionPrivate(Connection* parent)
- : q(parent)
-{
- isConnected = false;
- data = nullptr;
-}
-
-ConnectionPrivate::~ConnectionPrivate()
-{
- delete data;
-}
-
-void ConnectionPrivate::resolveServer(QString domain)
-{
- // Find the Matrix server for the given domain.
- QDnsLookup* dns = new QDnsLookup();
- dns->setType(QDnsLookup::SRV);
- dns->setName("_matrix._tcp." + domain);
-
- connect(dns, &QDnsLookup::finished, [this,dns]() {
- // Check the lookup succeeded.
- if (dns->error() != QDnsLookup::NoError ||
- dns->serviceRecords().isEmpty()) {
- emit q->resolveError("DNS lookup failed");
- dns->deleteLater();
- return;
- }
-
- // Handle the results.
- QDnsServiceRecord record = dns->serviceRecords().first();
- data->setHost(record.target());
- data->setPort(record.port());
- emit q->resolved();
- dns->deleteLater();
- });
- dns->lookup();
-}
-
-void ConnectionPrivate::processState(State* state)
-{
- if( state->event()->type() == QMatrixClient::EventType::RoomMember )
- {
- QMatrixClient::RoomMemberEvent* e = static_cast<QMatrixClient::RoomMemberEvent*>(state->event());
- User* user = q->user(e->userId());
- user->processEvent(e);
- }
-
- if ( Room* r = provideRoom(state->event()->roomId()) )
- r->addInitialState(state);
-}
-
-Room* ConnectionPrivate::provideRoom(QString id)
-{
- if (id.isEmpty())
- {
- qDebug() << "ConnectionPrivate::provideRoom() with empty id, doing nothing";
- return nullptr;
- }
-
- if (roomMap.contains(id))
- return roomMap.value(id);
-
- // Not yet in the map, create a new one.
- Room* room = q->createRoom(id);
- if (!room)
- qCritical() << "Failed to create a room!!!" << id;
-
- roomMap.insert( id, room );
- emit q->newRoom(room);
- return room;
-}
-
-void ConnectionPrivate::gotRoomMembers(BaseJob* job)
-{
- RoomMembersJob* membersJob = static_cast<RoomMembersJob*>(job);
- if( !membersJob->error() )
- {
- for( State* state: membersJob->states() )
- {
- processState(state);
- }
- qDebug() << membersJob->states().count() << " processed...";
- }
- else
- {
- qDebug() << "MembersJob error: " <<membersJob->errorString();
- if( membersJob->error() == BaseJob::NetworkError )
- emit q->connectionError( membersJob->errorString() );
- }
-}
diff --git a/connectionprivate.h b/connectionprivate.h
deleted file mode 100644
index 424ef998..00000000
--- a/connectionprivate.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/******************************************************************************
- * Copyright (C) 2015 Felix Rohrbach <kde@fxrh.de>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef QMATRIXCLIENT_CONNECTIONPRIVATE_H
-#define QMATRIXCLIENT_CONNECTIONPRIVATE_H
-
-#include <QtCore/QObject>
-#include <QtCore/QHash>
-#include <QtCore/QJsonObject>
-
-#include "connection.h"
-#include "connectiondata.h"
-
-namespace QMatrixClient
-{
- class Connection;
- class Event;
- class State;
- class User;
- class BaseJob;
- class SyncRoomData;
-
- class ConnectionPrivate : public QObject
- {
- Q_OBJECT
- public:
- ConnectionPrivate(Connection* parent);
- ~ConnectionPrivate();
-
- void resolveServer( QString domain );
-
- void processState( State* state );
-
- /** Finds a room with this id or creates a new one and adds it to roomMap. */
- Room* provideRoom( QString id );
-
- Connection* q;
- ConnectionData* data;
- QHash<QString, Room*> roomMap;
- QHash<QString, User*> userMap;
- bool isConnected;
- QString username;
- QString password;
- QString userId;
-
- public slots:
- void gotRoomMembers(BaseJob* job);
- };
-}
-
-#endif // QMATRIXCLIENT_CONNECTIONPRIVATE_H
diff --git a/events/event.cpp b/events/event.cpp
index d05d666f..0c7700ee 100644
--- a/events/event.cpp
+++ b/events/event.cpp
@@ -151,11 +151,11 @@ bool Event::parseJson(const QJsonObject& obj)
return correct;
}
-QList<Event*> QMatrixClient::eventListFromJson(const QJsonArray& json)
+Events QMatrixClient::eventsFromJson(const QJsonArray& json)
{
- QList<Event*> l;
- l.reserve(json.size());
+ Events evs;
+ evs.reserve(json.size());
for (auto event: json)
- l.push_back(Event::fromJson(event.toObject()));
- return l;
+ evs.push_back(Event::fromJson(event.toObject()));
+ return evs;
}
diff --git a/events/event.h b/events/event.h
index 72d26208..d9316747 100644
--- a/events/event.h
+++ b/events/event.h
@@ -24,6 +24,7 @@
#include <QtCore/QString>
#include <QtCore/QDateTime>
#include <QtCore/QJsonObject>
+#include <QtCore/QVector>
class QJsonArray;
@@ -38,7 +39,8 @@ namespace QMatrixClient
class Event
{
public:
- Event(EventType type);
+ explicit Event(EventType type);
+ Event(Event&) = delete;
virtual ~Event();
EventType type() const;
@@ -57,8 +59,9 @@ namespace QMatrixClient
class Private;
Private* d;
};
+ using Events = QVector<Event*>;
- QList<Event*> eventListFromJson(const QJsonArray& contents);
+ Events eventsFromJson(const QJsonArray& contents);
/**
* Finds a place in the timeline where a new event/message could be inserted.
@@ -71,6 +74,11 @@ namespace QMatrixClient
{
return std::lower_bound (timeline.begin(), timeline.end(), item,
[](const typename ContT::value_type a, const ItemT * b) {
+ // FIXME: We should not order the message list by origin timestamp.
+ // Rather, an order of receiving should be used (which actually
+ // poses a question on whether this method is needed at all -
+ // or we'd just prepend and append, depending on whether we
+ // received something from /sync or from /messages.
return a->timestamp() < b->timestamp();
}
);
diff --git a/jobs/basejob.cpp b/jobs/basejob.cpp
index e0dff287..20b45a15 100644
--- a/jobs/basejob.cpp
+++ b/jobs/basejob.cpp
@@ -92,7 +92,7 @@ void BaseJob::start()
url.setPath( url.path() + "/" + apiPath() );
QUrlQuery query = this->query();
if( d->needsToken )
- query.addQueryItem("access_token", connection()->token());
+ query.addQueryItem("access_token", connection()->accessToken());
url.setQuery(query);
QNetworkRequest req = QNetworkRequest(url);
req.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
diff --git a/jobs/roommessagesjob.cpp b/jobs/roommessagesjob.cpp
index ba075007..f880713d 100644
--- a/jobs/roommessagesjob.cpp
+++ b/jobs/roommessagesjob.cpp
@@ -18,7 +18,6 @@
#include "roommessagesjob.h"
#include "../room.h"
-#include "../events/event.h"
#include <QtCore/QJsonObject>
#include <QtCore/QJsonArray>
@@ -35,7 +34,7 @@ class RoomMessagesJob::Private
FetchDirectory dir;
int limit;
- QList<Event*> events;
+ Events events;
QString end;
};
@@ -54,7 +53,7 @@ RoomMessagesJob::~RoomMessagesJob()
delete d;
}
-QList<Event*> RoomMessagesJob::events()
+Events RoomMessagesJob::events()
{
return d->events;
}
@@ -84,7 +83,7 @@ QUrlQuery RoomMessagesJob::query() const
BaseJob::Status RoomMessagesJob::parseJson(const QJsonDocument& data)
{
QJsonObject obj = data.object();
- d->events = eventListFromJson(obj.value("chunk").toArray());
+ d->events = eventsFromJson(obj.value("chunk").toArray());
d->end = obj.value("end").toString();
return Success;
}
diff --git a/jobs/roommessagesjob.h b/jobs/roommessagesjob.h
index 52a72f70..9bedcad9 100644
--- a/jobs/roommessagesjob.h
+++ b/jobs/roommessagesjob.h
@@ -21,10 +21,11 @@
#include "basejob.h"
+#include "../events/event.h"
+
namespace QMatrixClient
{
class Room;
- class Event;
enum class FetchDirectory { Backwards, Forward };
@@ -34,7 +35,7 @@ namespace QMatrixClient
RoomMessagesJob(ConnectionData* data, Room* room, QString from, FetchDirectory dir = FetchDirectory::Backwards, int limit=10);
virtual ~RoomMessagesJob();
- QList<Event*> events();
+ Events events();
QString end();
protected:
diff --git a/jobs/syncjob.cpp b/jobs/syncjob.cpp
index a9865b55..2b2705b1 100644
--- a/jobs/syncjob.cpp
+++ b/jobs/syncjob.cpp
@@ -26,7 +26,6 @@
#include "../room.h"
#include "../connectiondata.h"
-#include "../events/event.h"
using namespace QMatrixClient;
@@ -139,7 +138,7 @@ BaseJob::Status SyncJob::parseJson(const QJsonDocument& data)
void SyncRoomData::EventList::fromJson(const QJsonObject& roomContents)
{
- auto l = eventListFromJson(roomContents[jsonKey].toObject()["events"].toArray());
+ auto l = eventsFromJson(roomContents[jsonKey].toObject()["events"].toArray());
swap(l);
}
diff --git a/jobs/syncjob.h b/jobs/syncjob.h
index f08a6b56..ed99b38b 100644
--- a/jobs/syncjob.h
+++ b/jobs/syncjob.h
@@ -22,15 +22,14 @@
#include "basejob.h"
#include "../joinstate.h"
+#include "../events/event.h"
namespace QMatrixClient
{
- class Event;
-
class SyncRoomData
{
public:
- class EventList : public QList<Event*>
+ class EventList : public Events
{
private:
QString jsonKey;
diff --git a/room.cpp b/room.cpp
index 768a0dac..161f5385 100644
--- a/room.cpp
+++ b/room.cpp
@@ -51,8 +51,6 @@ class Room::Private
Room* q;
- //static LogMessage* parseMessage(const QJsonObject& message);
-
// This updates the room displayname field (which is the way a room
// should be shown in the room list) It should be called whenever the
// list of members or the room name (m.room.name) or canonical alias change.
@@ -330,18 +328,6 @@ QString Room::roomMembername(QString userId) const
return roomMembername(connection()->user(userId));
}
-void Room::addMessage(Event* event)
-{
- processMessageEvent(event);
- emit newMessage(event);
- //d->addState(event);
-}
-
-void Room::addInitialState(State* state)
-{
- processStateEvent(state->event());
-}
-
void Room::updateData(const SyncRoomData& data)
{
if( d->prevBatch.isEmpty() )
@@ -578,85 +564,3 @@ void Room::Private::updateDisplayname()
if (old_name != displayname)
emit q->displaynameChanged(q);
}
-
-// void Room::setAlias(QString alias)
-// {
-// d->alias = alias;
-// emit aliasChanged(this);
-// }
-//
-// bool Room::parseEvents(const QJsonObject& json)
-// {
-// QList<LogMessage*> newMessages;
-// QJsonValue value = json.value("messages").toObject().value("chunk");
-// if( !value.isArray() )
-// {
-// return false;
-// }
-// QJsonArray messages = value.toArray();
-// for(const QJsonValue& val: messages )
-// {
-// if( !val.isObject() )
-// continue;
-// LogMessage* msg = Private::parseMessage(val.toObject());
-// if( msg )
-// {
-// newMessages.append(msg);
-// }
-//
-// }
-// addMessages(newMessages);
-// return true;
-// }
-//
-// bool Room::parseSingleEvent(const QJsonObject& json)
-// {
-// qDebug() << "parseSingleEvent";
-// LogMessage* msg = Private::parseMessage(json);
-// if( msg )
-// {
-// addMessage(msg);
-// return true;
-// }
-// return false;
-// }
-//
-// bool Room::parseState(const QJsonObject& json)
-// {
-// QJsonValue value = json.value("state");
-// if( !value.isArray() )
-// {
-// return false;
-// }
-// QJsonArray states = value.toArray();
-// for( const QJsonValue& val: states )
-// {
-// QJsonObject state = val.toObject();
-// QString type = state.value("type").toString();
-// if( type == "m.room.aliases" )
-// {
-// QJsonArray aliases = state.value("content").toObject().value("aliases").toArray();
-// if( aliases.count() > 0 )
-// {
-// setAlias(aliases.at(0).toString());
-// }
-// }
-// }
-// return true;
-// }
-//
-// LogMessage* Room::Private::parseMessage(const QJsonObject& message)
-// {
-// if( message.value("type") == "m.room.message" )
-// {
-// QJsonObject content = message.value("content").toObject();
-// if( content.value("msgtype").toString() != "m.text" )
-// return 0;
-// QString user = message.value("user_id").toString();
-// QString body = content.value("body").toString();
-// LogMessage* msg = new LogMessage( LogMessage::UserMessage, body, user );
-// return msg;
-// }
-// return 0;
-// }
-
diff --git a/room.h b/room.h
index 8cf393a2..25eae11b 100644
--- a/room.h
+++ b/room.h
@@ -30,7 +30,6 @@
namespace QMatrixClient
{
class Event;
- class State;
class Connection;
class User;
@@ -65,8 +64,6 @@ namespace QMatrixClient
*/
Q_INVOKABLE QString roomMembername(QString userId) const;
- Q_INVOKABLE void addMessage( Event* event );
- Q_INVOKABLE void addInitialState( State* state );
Q_INVOKABLE void updateData( const SyncRoomData& data );
Q_INVOKABLE void setJoinState( JoinState state );
diff --git a/settings.cpp b/settings.cpp
new file mode 100644
index 00000000..45af33e3
--- /dev/null
+++ b/settings.cpp
@@ -0,0 +1,102 @@
+#include "settings.h"
+
+#include <QtCore/QUrl>
+#include <QtCore/QDebug>
+
+using namespace QMatrixClient;
+
+Settings::~Settings()
+{ }
+
+void Settings::setValue(const QString& key, const QVariant& value)
+{
+// qDebug() << "Setting" << key << "to" << value;
+ QSettings::setValue(key, value);
+}
+
+QVariant Settings::value(const QString& key, const QVariant& defaultValue) const
+{
+ return QSettings::value(key, defaultValue);
+}
+
+SettingsGroup::~SettingsGroup()
+{ }
+
+void SettingsGroup::setValue(const QString& key, const QVariant& value)
+{
+ Settings::setValue(groupPath + "/" + key, value);
+}
+
+bool SettingsGroup::contains(const QString& key) const
+{
+ return Settings::contains(groupPath + "/" + key);
+}
+
+QVariant SettingsGroup::value(const QString& key, const QVariant& defaultValue) const
+{
+ return Settings::value(groupPath + "/" + key, defaultValue);
+}
+
+QString SettingsGroup::group() const
+{
+ return groupPath;
+}
+
+QStringList SettingsGroup::childGroups() const
+{
+ const_cast<SettingsGroup*>(this)->beginGroup(groupPath);
+ QStringList l { Settings::childGroups() };
+ const_cast<SettingsGroup*>(this)->endGroup();
+ return l;
+}
+
+void SettingsGroup::remove(const QString& key)
+{
+ QString fullKey { groupPath };
+ if (!key.isEmpty())
+ fullKey += "/" + key;
+ Settings::remove(fullKey);
+}
+
+AccountSettings::~AccountSettings()
+{ }
+
+bool AccountSettings::keepLoggedIn() const
+{
+ return value("keep_logged_in", false).toBool();
+}
+
+void AccountSettings::setKeepLoggedIn(bool newSetting)
+{
+ setValue("keep_logged_in", newSetting);
+}
+
+QUrl AccountSettings::homeserver() const
+{
+ return QUrl::fromUserInput(value("homeserver").toString());
+}
+
+void AccountSettings::setHomeserver(const QUrl& url)
+{
+ setValue("homeserver", url.toString());
+}
+
+QString AccountSettings::userId() const
+{
+ return group().section('/', -1);
+}
+
+QString AccountSettings::accessToken() const
+{
+ return value("access_token").toString();
+}
+
+void AccountSettings::setAccessToken(const QString& accessToken)
+{
+ setValue("access_token", accessToken);
+}
+
+void AccountSettings::clearAccessToken()
+{
+ remove("access_token");
+}
diff --git a/settings.h b/settings.h
new file mode 100644
index 00000000..10b2bb0a
--- /dev/null
+++ b/settings.h
@@ -0,0 +1,97 @@
+/******************************************************************************
+ * Copyright (C) 2016 Kitsune Ral <kitsune-ral@users.sf.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#pragma once
+
+#include <QtCore/QSettings>
+#include <QtCore/QVector>
+
+class QVariant;
+class QUrl;
+
+namespace QMatrixClient
+{
+ class Settings: public QSettings
+ {
+ public:
+#if defined(_MSC_VER) && _MSC_VER < 1900
+ // VS 2013 (and probably older) aren't friends with 'using' statements
+ // that involve private constructors
+ explicit Settings(QObject* parent = 0) : QSettings(parent) { }
+#else
+ using QSettings::QSettings;
+#endif
+ virtual ~Settings();
+
+ Q_INVOKABLE void setValue(const QString &key,
+ const QVariant &value);
+ Q_INVOKABLE QVariant value(const QString &key,
+ const QVariant &defaultValue = {}) const;
+ };
+
+ class SettingsGroup: public Settings
+ {
+ public:
+ template <typename... ArgTs>
+ explicit SettingsGroup(const QString& path, ArgTs... qsettingsArgs)
+ : Settings(qsettingsArgs...)
+ , groupPath(path)
+ { }
+ virtual ~SettingsGroup();
+
+ Q_INVOKABLE bool contains(const QString& key) const;
+ Q_INVOKABLE QVariant value(const QString &key,
+ const QVariant &defaultValue = {}) const;
+ Q_INVOKABLE QString group() const;
+ Q_INVOKABLE QStringList childGroups() const;
+ Q_INVOKABLE void setValue(const QString &key,
+ const QVariant &value);
+
+ Q_INVOKABLE void remove(const QString& key);
+
+ private:
+ QString groupPath;
+ };
+
+ class AccountSettings: public SettingsGroup
+ {
+ Q_OBJECT
+ Q_PROPERTY(QString userId READ userId)
+ Q_PROPERTY(QUrl homeserver READ homeserver WRITE setHomeserver)
+ Q_PROPERTY(bool keepLoggedIn READ keepLoggedIn WRITE setKeepLoggedIn)
+ Q_PROPERTY(QString accessToken READ accessToken WRITE setAccessToken)
+ public:
+ template <typename... ArgTs>
+ explicit AccountSettings(const QString& accountId, ArgTs... qsettingsArgs)
+ : SettingsGroup("Accounts/" + accountId, qsettingsArgs...)
+ { }
+ virtual ~AccountSettings();
+
+ QString userId() const;
+
+ QUrl homeserver() const;
+ void setHomeserver(const QUrl& url);
+
+ bool keepLoggedIn() const;
+ void setKeepLoggedIn(bool newSetting);
+
+ QString accessToken() const;
+ void setAccessToken(const QString& accessToken);
+ Q_INVOKABLE void clearAccessToken();
+ };
+}