diff options
-rw-r--r-- | CMakeLists.txt | 1 | ||||
-rw-r--r-- | connection.cpp | 93 | ||||
-rw-r--r-- | connection.h | 19 | ||||
-rw-r--r-- | connectionprivate.cpp | 126 | ||||
-rw-r--r-- | connectionprivate.h | 66 |
5 files changed, 95 insertions, 210 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e5dae8f..80ffcfd7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,7 +28,6 @@ message( STATUS ) set(libqmatrixclient_SRCS connectiondata.cpp connection.cpp - connectionprivate.cpp room.cpp user.cpp logmessage.cpp diff --git a/connection.cpp b/connection.cpp index 904649bc..d357599b 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,39 @@ #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) + { } + Private(Private&) = delete; + ~Private() { delete data; } + + Room* provideRoom( QString id ); + + Connection* q; + ConnectionData* data; + QHash<QString, Room*> roomMap; + QHash<QString, User*> userMap; + bool isConnected; + QString username; + QString password; + QString userId; +}; + 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,7 +80,26 @@ 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) @@ -113,9 +156,9 @@ SyncJob* Connection::sync(int timeout) syncJob->setTimeout(timeout); connect( syncJob, &SyncJob::success, [=] () { d->data->setLastEvent(syncJob->nextBatch()); - for( const auto roomData: syncJob->roomData() ) + for( const auto& roomData: syncJob->roomData() ) { - if ( Room* r = d->provideRoom(roomData.roomId) ) + if ( Room* r = provideRoom(roomData.roomId) ) r->updateData(roomData); } emit syncDone(); @@ -147,7 +190,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 +202,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) { @@ -221,6 +264,30 @@ ConnectionData* Connection::connectionData() return d->data; } +Room* Connection::provideRoom(QString id) +{ + if (id.isEmpty()) + { + qDebug() << "ConnectionPrivate::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..2816895e 100644 --- a/connection.h +++ b/connection.h @@ -55,7 +55,7 @@ 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 ); @@ -81,11 +81,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 +107,8 @@ namespace QMatrixClient virtual Room* createRoom(QString roomId); private: - friend class ConnectionPrivate; - ConnectionPrivate* d; + class Private; + Private* d; }; } 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 |