aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt48
-rw-r--r--connectionprivate.cpp64
-rw-r--r--connectionprivate.h11
-rw-r--r--jobs/basejob.cpp67
-rw-r--r--jobs/basejob.h102
5 files changed, 143 insertions, 149 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3745f3c2..fa5abe56 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -10,25 +10,6 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
# Instruct CMake to run moc automatically when needed.
set(CMAKE_AUTOMOC ON)
-# Whether to build with the bundled KCoreAddons or system KCoreAddons
-set( BUNDLE_KCOREADDONS "AUTO" CACHE STRING "Build own KCoreAddons, one of ON, OFF and AUTO" )
-set( KCOREADDONS_DIR "kcoreaddons" CACHE STRING "Local path to bundled KCoreAddons sources, if own KCoreAddons is built" )
-
-find_package(Qt5Core 5.2.0) # For JSON (de)serialization
-find_package(Qt5Network 5.2.0) # For networking
-find_package(Qt5Gui 5.2.0) # For userpics
-
-if ( (NOT BUNDLE_KCOREADDONS STREQUAL "ON")
- AND (NOT BUNDLE_KCOREADDONS STREQUAL "OFF")
- AND (NOT BUNDLE_KCOREADDONS STREQUAL "AUTO") )
- message( FATAL_ERROR "BUNDLE_KCOREADDONS must be one of ON, OFF or AUTO" )
-endif ()
-
-if ( BUNDLE_KCOREADDONS STREQUAL "AUTO" )
- find_package(KF5CoreAddons QUIET)
-elseif ( BUNDLE_KCOREADDONS STREQUAL "OFF" )
- find_package(KF5CoreAddons REQUIRED)
-endif ()
message( STATUS )
message( STATUS "================================================================================" )
@@ -37,14 +18,6 @@ message( STATUS "===============================================================
message( STATUS "Building with: ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}" )
message( STATUS "Install Prefix: ${CMAKE_INSTALL_PREFIX}" )
message( STATUS "Path to Qt Core: ${Qt5Core_DIR}" )
-message( STATUS "Build own KCoreAddons (BUNDLE_KCOREADDONS): ${BUNDLE_KCOREADDONS}" )
-if ( NOT BUNDLE_KCOREADDONS STREQUAL "ON" )
- if ( KF5CoreAddons_FOUND )
- message( STATUS "'- Path to system KCoreAddons: ${KF5CoreAddons_DIR}" )
- else ( KF5CoreAddons_FOUND )
- message( STATUS "'- System KCoreAddons not found, using the bundled version at ${PROJECT_SOURCE_DIR}/${KCOREADDONS_DIR}" )
- endif ( KF5CoreAddons_FOUND )
-endif ( NOT BUNDLE_KCOREADDONS STREQUAL "ON" )
message( STATUS "================================================================================" )
message( STATUS )
@@ -80,16 +53,6 @@ set(libqmatrixclient_SRCS
jobs/mediathumbnailjob.cpp
jobs/logoutjob.cpp
)
-# Add bundled KCoreAddons sources if we haven't found the system sources
-# or if we ignore them
-if ( NOT KF5CoreAddons_FOUND )
- set (libqmatrixclient_SRCS ${libqmatrixclient_SRCS}
- ${KCOREADDONS_DIR}/src/lib/jobs/kjob.cpp
- ${KCOREADDONS_DIR}/src/lib/jobs/kcompositejob.cpp
- ${KCOREADDONS_DIR}/src/lib/jobs/kjobtrackerinterface.cpp
- ${KCOREADDONS_DIR}/src/lib/jobs/kjobuidelegate.cpp
- )
-endif ( NOT KF5CoreAddons_FOUND )
add_library(qmatrixclient ${libqmatrixclient_SRCS})
@@ -109,14 +72,3 @@ else ( CMAKE_VERSION VERSION_LESS "3.1" )
endif ( CMAKE_VERSION VERSION_LESS "3.1" )
target_link_libraries(qmatrixclient Qt5::Core Qt5::Network Qt5::Gui)
-if ( KF5CoreAddons_FOUND )
- # The proper way of doing things would be to make a separate config.h.in
- # file and use configure_file() command here to generate config.h with
- # needed C++ preprocessor macros. If we have more than one or two
- # dependencies like that, we should turn to that more scalable way.
- # As for now, passing a macro through -D is easier to observe and maintain.
- target_compile_definitions ( qmatrixclient PRIVATE USING_SYSTEM_KCOREADDONS )
- target_link_libraries(qmatrixclient KF5::CoreAddons)
-else ( KF5CoreAddons_FOUND )
- include_directories( ${KCOREADDONS_DIR}/src/lib/jobs )
-endif ( KF5CoreAddons_FOUND )
diff --git a/connectionprivate.cpp b/connectionprivate.cpp
index 62840473..4d49c014 100644
--- a/connectionprivate.cpp
+++ b/connectionprivate.cpp
@@ -116,69 +116,7 @@ Room* ConnectionPrivate::provideRoom(QString id)
return room;
}
-//void ConnectionPrivate::connectDone(KJob* job)
-//{
-// PasswordLogin* realJob = static_cast<PasswordLogin*>(job);
-// if( !realJob->error() )
-// {
-// isConnected = true;
-// userId = realJob->id();
-// qDebug() << "Our user ID: " << userId;
-// emit q->connected();
-// }
-// else {
-// emit q->loginError( job->errorString() );
-// }
-//}
-
-//void ConnectionPrivate::reconnectDone(KJob* job)
-//{
-// PasswordLogin* realJob = static_cast<PasswordLogin*>(job);
-// if( !realJob->error() )
-// {
-// userId = realJob->id();
-// emit q->reconnected();
-// }
-// else {
-// emit q->loginError( job->errorString() );
-// isConnected = false;
-// }
-//}
-
-//void ConnectionPrivate::syncDone(KJob* job)
-//{
-// SyncJob* syncJob = static_cast<SyncJob*>(job);
-// if( !syncJob->error() )
-// {
-// data->setLastEvent(syncJob->nextBatch());
-// processRooms(syncJob->roomData());
-// emit q->syncDone();
-// }
-// else {
-// if( syncJob->error() == BaseJob::NetworkError )
-// emit q->connectionError( syncJob->errorString() );
-// else
-// qDebug() << "syncJob failed, error:" << syncJob->error();
-// }
-//}
-
-//void ConnectionPrivate::gotJoinRoom(KJob* job)
-//{
-// qDebug() << "gotJoinRoom";
-// JoinRoomJob* joinJob = static_cast<JoinRoomJob*>(job);
-// if( !joinJob->error() )
-// {
-// if ( Room* r = provideRoom(joinJob->roomId()) )
-// emit q->joinedRoom(r);
-// }
-// else
-// {
-// if( joinJob->error() == BaseJob::NetworkError )
-// emit q->connectionError( joinJob->errorString() );
-// }
-//}
-
-void ConnectionPrivate::gotRoomMembers(KJob* job)
+void ConnectionPrivate::gotRoomMembers(BaseJob* job)
{
RoomMembersJob* membersJob = static_cast<RoomMembersJob*>(job);
if( !membersJob->error() )
diff --git a/connectionprivate.h b/connectionprivate.h
index 8e37a934..d1199081 100644
--- a/connectionprivate.h
+++ b/connectionprivate.h
@@ -19,15 +19,12 @@
#ifndef QMATRIXCLIENT_CONNECTIONPRIVATE_H
#define QMATRIXCLIENT_CONNECTIONPRIVATE_H
-class KJob;
-
#include <QtCore/QObject>
#include <QtCore/QHash>
#include <QtCore/QJsonObject>
#include "connection.h"
#include "connectiondata.h"
-#include "jobs/syncjob.h"
namespace QMatrixClient
{
@@ -35,6 +32,8 @@ namespace QMatrixClient
class Event;
class State;
class User;
+ class BaseJob;
+ class SyncRoomData;
class ConnectionPrivate : public QObject
{
@@ -60,11 +59,7 @@ namespace QMatrixClient
QString userId;
public slots:
-// void connectDone(KJob* job);
-// void reconnectDone(KJob* job);
-// void syncDone(KJob* job);
-// void gotJoinRoom(KJob* job);
- void gotRoomMembers(KJob* job);
+ void gotRoomMembers(BaseJob* job);
};
}
diff --git a/jobs/basejob.cpp b/jobs/basejob.cpp
index 6c68ab66..2c95ef11 100644
--- a/jobs/basejob.cpp
+++ b/jobs/basejob.cpp
@@ -31,24 +31,21 @@ class BaseJob::Private
{
public:
Private(ConnectionData* c, JobHttpType t, bool nt)
- : connection(c), reply(nullptr), type(t), needsToken(nt) {}
+ : connection(c), reply(nullptr), type(t), needsToken(nt), errorCode(NoError)
+ {}
ConnectionData* connection;
QNetworkReply* reply;
JobHttpType type;
bool needsToken;
+
+ int errorCode;
+ QString errorText;
};
BaseJob::BaseJob(ConnectionData* connection, JobHttpType type, QString name, bool needsToken)
: d(new Private(connection, type, needsToken))
{
- // Work around KJob inability to separate success and failure signals
- connect(this, &BaseJob::result, [this]() {
- if (error() == NoError)
- emit success(this);
- else
- emit failure(this);
- });
setObjectName(name);
qDebug() << "Job" << objectName() << " created";
}
@@ -119,6 +116,55 @@ void BaseJob::start()
// this, &BaseJob::networkError ); // http://doc.qt.io/qt-5/qnetworkreply.html#error-1
}
+void BaseJob::finishJob(bool emitResult)
+{
+ if( d->reply->isRunning() )
+ d->reply->abort();
+
+ // Notify those that are interested in any completion of the job (including killing)
+ emit finished(this);
+
+ if (emitResult) {
+ emit result(this);
+ if (error())
+ emit failure(this);
+ else
+ emit success(this);
+ }
+
+ deleteLater();
+}
+
+int BaseJob::error() const
+{
+ return d->errorCode;
+}
+
+QString BaseJob::errorString() const
+{
+ return d->errorText;
+}
+
+void BaseJob::setError(int errorCode)
+{
+ d->errorCode = errorCode;
+}
+
+void BaseJob::setErrorText(QString errorText)
+{
+ d->errorText = errorText;
+}
+
+void BaseJob::emitResult()
+{
+ finishJob(true);
+}
+
+void BaseJob::abandon()
+{
+ finishJob(false);
+}
+
void BaseJob::fail(int errorCode, QString errorString)
{
setError( errorCode );
@@ -134,11 +180,6 @@ QNetworkReply* BaseJob::networkReply() const
return d->reply;
}
-// void BaseJob::networkError(QNetworkReply::NetworkError code)
-// {
-// fail( KJob::UserDefinedError+1, d->reply->errorString() );
-// }
-
void BaseJob::gotReply()
{
switch( d->reply->error() )
diff --git a/jobs/basejob.h b/jobs/basejob.h
index 150d39e8..9d00c0ac 100644
--- a/jobs/basejob.h
+++ b/jobs/basejob.h
@@ -19,12 +19,6 @@
#ifndef QMATRIXCLIENT_BASEJOB_H
#define QMATRIXCLIENT_BASEJOB_H
-#ifdef USING_SYSTEM_KCOREADDONS
-#include <KCoreAddons/KJob>
-#else
-#include "kjob.h"
-#endif // KCOREADDONS_FOUND
-
#include <QtCore/QJsonDocument>
#include <QtCore/QJsonObject>
#include <QtCore/QUrlQuery>
@@ -36,28 +30,75 @@ namespace QMatrixClient
enum class JobHttpType { GetJob, PutJob, PostJob };
- class BaseJob: public KJob
+ class BaseJob: public QObject
{
Q_OBJECT
public:
+ /* Just in case, the values are compatible with KJob
+ * (which BaseJob used to inherit from). */
+ enum ErrorCode { NoError = 0, NetworkError = 100,
+ JsonParseError, TimeoutError, ContentAccessError,
+ UserDefinedError = 512 };
+
BaseJob(ConnectionData* connection, JobHttpType type,
QString name, bool needsToken=true);
virtual ~BaseJob();
- void start() override;
+ void start();
- enum ErrorCode { NetworkError = KJob::UserDefinedError,
- JsonParseError, TimeoutError, ContentAccessError,
- UserDefinedError = 512 };
+ /**
+ * Abandons the result of this job, arrived or unarrived.
+ *
+ * This aborts waiting for a reply from the server (if there was
+ * any pending) and deletes the job object. It is always done quietly
+ * (as opposed to KJob::kill() that can trigger emitting the result).
+ */
+ void abandon();
+
+ int error() const;
+ virtual QString errorString() const;
signals:
/**
- * Emitted together with KJob::result() but only if there's no error.
+ * Emitted when the job is finished, in any case. It is used to notify
+ * observers that the job is terminated and that progress can be hidden.
+ *
+ * This should not be emitted directly by subclasses;
+ * use emitResult() instead.
+ *
+ * In general, to be notified of a job's completion, client code
+ * should connect to success() and failure()
+ * rather than finished(), so that kill() is indeed quiet.
+ * However if you store a list of jobs and they might get killed
+ * silently, then you must connect to this instead of result(),
+ * to avoid dangling pointers in your list.
+ *
+ * @param job the job that emitted this signal
+ * @internal
+ *
+ * @see success, failure
+ */
+ void finished(BaseJob* job);
+
+ /**
+ * Emitted when the job is finished (except when killed).
+ *
+ * Use error to know if the job was finished with error.
+ *
+ * @param job the job that emitted this signal
+ *
+ * @see success, failure
+ */
+ void result(BaseJob* job);
+
+ /**
+ * Emitted together with result() but only if there's no error.
*/
void success(BaseJob*);
+
/**
- * Emitted together with KJob::result() if there's an error.
- * Same as result(), this won't be emitted in case of kill(Quietly).
+ * Emitted together with result() if there's an error.
+ * Same as result(), this won't be emitted in case of kill().
*/
void failure(BaseJob*);
@@ -70,6 +111,34 @@ namespace QMatrixClient
virtual QJsonObject data() const;
virtual void parseJson(const QJsonDocument& data);
+ /**
+ * Sets the error code.
+ *
+ * It should be called when an error is encountered in the job,
+ * just before calling emitResult(). Normally you might want to
+ * use fail() instead - it sets error code, error text, makes sure
+ * the job has finished and invokes emitResult after that.
+ *
+ * To extend the list of error codes, define an (anonymous) enum
+ * with additional values starting at BaseJob::UserDefinedError
+ *
+ * @param errorCode the error code
+ * @see emitResult(), fail()
+ */
+ void setError(int errorCode);
+ void setErrorText(QString errorText);
+
+ /**
+ * Utility function to emit the result signal, and suicide this job.
+ * It first notifies the observers to hide the progress for this job using
+ * the finished() signal.
+ *
+ * @note: Deletes this job using deleteLater().
+ *
+ * @see result()
+ * @see finished()
+ */
+ void emitResult();
void fail( int errorCode, QString errorString );
QNetworkReply* networkReply() const;
@@ -79,10 +148,9 @@ namespace QMatrixClient
void timeout();
void sslErrors(const QList<QSslError>& errors);
- //void networkError(QNetworkReply::NetworkError code);
-
-
private:
+ void finishJob(bool emitResult);
+
class Private;
Private* d;
};