From c9dc52fae0c98c61a635e190687c58768a0cebf5 Mon Sep 17 00:00:00 2001 From: Calugar George Date: Fri, 10 May 2019 10:54:12 +0300 Subject: [PATCH 1/7] Prepare suport for qml folder listing --- qtdropbox2.pri | 2 + qtdropbox2.pro | 2 +- src/FoldersModel.cpp | 56 +++++++ src/FoldersModel.h | 39 +++++ src/qdropbox2.cpp | 6 +- src/qdropbox2.h | 0 src/qdropbox2account.cpp | 0 src/qdropbox2account.h | 0 src/qdropbox2common.h | 0 src/qdropbox2entity.h | 0 src/qdropbox2entityinfo.cpp | 0 src/qdropbox2entityinfo.h | 1 + src/qdropbox2file.cpp | 4 +- src/qdropbox2file.h | 0 src/qdropbox2folder.cpp | 32 ++-- src/qdropbox2folder.h | 20 ++- src/qdropbox2global.h | 2 +- tests/config.h.in | 11 ++ tests/qtdropbox2test.cpp | 285 +++++++++++++++++++----------------- tests/qtdropbox2test.pro | 12 +- 20 files changed, 303 insertions(+), 169 deletions(-) create mode 100644 src/FoldersModel.cpp create mode 100644 src/FoldersModel.h mode change 100644 => 100755 src/qdropbox2.cpp mode change 100644 => 100755 src/qdropbox2.h mode change 100644 => 100755 src/qdropbox2account.cpp mode change 100644 => 100755 src/qdropbox2account.h mode change 100644 => 100755 src/qdropbox2common.h mode change 100644 => 100755 src/qdropbox2entity.h mode change 100644 => 100755 src/qdropbox2entityinfo.cpp mode change 100644 => 100755 src/qdropbox2entityinfo.h mode change 100644 => 100755 src/qdropbox2file.cpp mode change 100644 => 100755 src/qdropbox2file.h mode change 100644 => 100755 src/qdropbox2folder.cpp mode change 100644 => 100755 src/qdropbox2folder.h mode change 100644 => 100755 src/qdropbox2global.h create mode 100644 tests/config.h.in diff --git a/qtdropbox2.pri b/qtdropbox2.pri index 512be32..5a7a05f 100644 --- a/qtdropbox2.pri +++ b/qtdropbox2.pri @@ -1,4 +1,5 @@ SOURCES += \ + $$PWD/src/FoldersModel.cpp \ $$PWD/src/qdropbox2.cpp \ $$PWD/src/qdropbox2account.cpp \ $$PWD/src/qdropbox2file.cpp \ @@ -6,6 +7,7 @@ SOURCES += \ $$PWD/src/qdropbox2entityinfo.cpp \ HEADERS += \ + $$PWD/src/FoldersModel.h \ $$PWD/src/qdropbox2global.h \ $$PWD/src/qdropbox2common.h \ $$PWD/src/qdropbox2.h \ diff --git a/qtdropbox2.pro b/qtdropbox2.pro index 8ee6f47..75b66ae 100644 --- a/qtdropbox2.pro +++ b/qtdropbox2.pro @@ -4,7 +4,7 @@ TEMPLATE = lib #CONFIG += dll CONFIG += C++11 -QT += network xml +QT += network xml qml quick QT -= gui TARGET = QtDropbox2 diff --git a/src/FoldersModel.cpp b/src/FoldersModel.cpp new file mode 100644 index 0000000..74de7f8 --- /dev/null +++ b/src/FoldersModel.cpp @@ -0,0 +1,56 @@ +#include "FoldersModel.h" + +FoldersModel::FoldersModel(QAbstractListModel *parent): QAbstractListModel(parent) +{ + +} + +FoldersModel::~FoldersModel() +{ + +} + +QVariant FoldersModel::data(const QModelIndex &index, int role) const +{ + qDebug()<<" Data asked for "<filename(); + + } + return QVariant(); +} + +int FoldersModel::rowCount(const QModelIndex &parent) const +{ + return m_contentList.count(); +} + +int FoldersModel::count() +{ + return m_contentList.count(); +} + +QDropbox2EntityInfo *FoldersModel::at(const int index) +{ + return m_contentList.at(index); +} + +QHash FoldersModel::roleNames() const +{ + QHash roles; + roles[IdRole] = "fileId"; + roles[NameRole] = "name"; + return roles; +} + +void FoldersModel::append(QDropbox2EntityInfo *item) +{ + m_contentList.append(item); +} + +void FoldersModel::clear() +{ + m_contentList.clear(); +} diff --git a/src/FoldersModel.h b/src/FoldersModel.h new file mode 100644 index 0000000..ed69119 --- /dev/null +++ b/src/FoldersModel.h @@ -0,0 +1,39 @@ +#ifndef FOLDERSMODEL_H +#define FOLDERSMODEL_H + +#include +#include + +#include "qdropbox2entityinfo.h" + +class FoldersModel : public QAbstractListModel +{ + Q_OBJECT + +public: + enum FolderListRole { + IdRole = Qt::UserRole, // 256 + NameRole, + }; + //TODO: Change to no QDropbox2EntityInfo pointer as soon as a qml test exists + typedef QList ContentsList; + +public: + FoldersModel(QAbstractListModel *parent=nullptr); + ~FoldersModel(); + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const ; + int count(); + QDropbox2EntityInfo *at(const int index); + QHash roleNames() const; + + void append(QDropbox2EntityInfo* item); + void clear(); +private: + ContentsList m_contentList; +signals: + +public slots: +}; + +#endif // FOLDERSMODEL_H diff --git a/src/qdropbox2.cpp b/src/qdropbox2.cpp old mode 100644 new mode 100755 index 4062c7c..15a6f46 --- a/src/qdropbox2.cpp +++ b/src/qdropbox2.cpp @@ -108,7 +108,7 @@ void QDropbox2::slot_networkRequestFinished(QNetworkReply *reply) qDebug() << "response: " << reply->bytesAvailable() << "bytes" << endl; qDebug() << "status code: " << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toString() << endl; qDebug() << "== begin response ==" << endl << lastResponse << endl << "== end response ==" << endl; - qDebug() << "req#" << nr << " is of type " << requestMap[nr].type << endl; +// qDebug() << "req#" << nr << " is of type " << requestMap[nr].type << endl; #endif lastErrorCode = reply->error(); @@ -192,7 +192,7 @@ bool QDropbox2::createAPIv2Reqeust(QUrl request, QNetworkRequest& req, bool incl QNetworkReply* QDropbox2::sendPOST(QNetworkRequest& rq, QByteArray postdata) { #ifdef QTDROPBOX_DEBUG - qDebug() << "sendPOST() host = " << host << endl; +// qDebug() << "sendPOST() host = " << host << endl; #endif return QNAM.post(rq, postdata); @@ -201,7 +201,7 @@ QNetworkReply* QDropbox2::sendPOST(QNetworkRequest& rq, QByteArray postdata) QNetworkReply* QDropbox2::sendGET(QNetworkRequest& rq) { #ifdef QTDROPBOX_DEBUG - qDebug() << "sendGET() host = " << host << endl; +// qDebug() << "sendGET() host = " << host << endl; #endif return QNAM.get(rq); diff --git a/src/qdropbox2.h b/src/qdropbox2.h old mode 100644 new mode 100755 diff --git a/src/qdropbox2account.cpp b/src/qdropbox2account.cpp old mode 100644 new mode 100755 diff --git a/src/qdropbox2account.h b/src/qdropbox2account.h old mode 100644 new mode 100755 diff --git a/src/qdropbox2common.h b/src/qdropbox2common.h old mode 100644 new mode 100755 diff --git a/src/qdropbox2entity.h b/src/qdropbox2entity.h old mode 100644 new mode 100755 diff --git a/src/qdropbox2entityinfo.cpp b/src/qdropbox2entityinfo.cpp old mode 100644 new mode 100755 diff --git a/src/qdropbox2entityinfo.h b/src/qdropbox2entityinfo.h old mode 100644 new mode 100755 index 3bdb2d8..dcea4a3 --- a/src/qdropbox2entityinfo.h +++ b/src/qdropbox2entityinfo.h @@ -70,6 +70,7 @@ class QDROPBOXSHARED_EXPORT QDropbox2EntityInfo : public QObject */ QDropbox2EntityInfo& operator=(const QDropbox2EntityInfo& other); +public slots: /*! Raw Dropbox file identifier. */ diff --git a/src/qdropbox2file.cpp b/src/qdropbox2file.cpp old mode 100644 new mode 100755 index 6e1cd77..9a22ae8 --- a/src/qdropbox2file.cpp +++ b/src/qdropbox2file.cpp @@ -371,7 +371,7 @@ void QDropbox2File::resultGetFile(QNetworkReply *reply, CallbackPtr /*reply_data lastErrorCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); #ifdef QTDROPBOX_DEBUG - qDebug() << "QDropbox2File::replyFileContent jason.valid = " << json.isValid() << endl; +// qDebug() << "QDropbox2File::replyFileContent jason.valid = " << json.isValid() << endl; #endif emit signal_errorOccurred(lastErrorCode, lastErrorMessage); @@ -496,7 +496,7 @@ void QDropbox2File::resultPutFile(QNetworkReply *reply, CallbackPtr /*reply_data lastErrorCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); #ifdef QTDROPBOX_DEBUG - qDebug() << "QDropbox2File::resultPutFile jason.valid = " << json.isValid() << endl; +// qDebug() << "QDropbox2File::resultPutFile jason.valid = " << json.isValid() << endl; #endif emit signal_errorOccurred(lastErrorCode, lastErrorMessage); diff --git a/src/qdropbox2file.h b/src/qdropbox2file.h old mode 100644 new mode 100755 diff --git a/src/qdropbox2folder.cpp b/src/qdropbox2folder.cpp old mode 100644 new mode 100755 index ae09486..3f7a14e --- a/src/qdropbox2folder.cpp +++ b/src/qdropbox2folder.cpp @@ -210,7 +210,7 @@ bool QDropbox2Folder::getLatestCursor(QString& cursor, bool include_deleted) return result; } -bool QDropbox2Folder::hasChanged(ContentsList& changes) +bool QDropbox2Folder::hasChanged(FoldersModel *changes) { if(latestCursor.isEmpty()) { @@ -236,7 +236,7 @@ bool QDropbox2Folder::hasChanged(ContentsList& changes) return false; foreach(const QJsonValue& entry, data) - changes.append(QDropbox2EntityInfo(entry.toObject())); + changes->append(new QDropbox2EntityInfo(entry.toObject())); } return true; @@ -276,13 +276,13 @@ void QDropbox2Folder::hasChangedCallback(QNetworkReply* /*reply*/, CallbackPtr / } else { - QDropbox2Folder::ContentsList changes; + FoldersModel *changes = new FoldersModel(); QJsonArray data = object.value("entries").toArray(); if(data.count()) { foreach(const QJsonValue& entry, data) - changes.append(QDropbox2EntityInfo(entry.toObject())); + changes->append(new QDropbox2EntityInfo(entry.toObject())); } emit signal_hasChangedResults(changes); @@ -377,7 +377,7 @@ void QDropbox2Folder::obtainMetadata() lastErrorCode = QDropbox2::APIError; lastErrorMessage = "Metadata for the root folder is unsupported."; #ifdef QTDROPBOX_DEBUG - qDebug() << "error: " << errorText << endl; + qDebug() << "error: " << lastErrorMessage << endl; #endif emit signal_errorOccurred(lastErrorCode, lastErrorMessage); } @@ -426,7 +426,7 @@ void QDropbox2Folder::obtainMetadata() lastErrorCode = QDropbox2::APIError; lastErrorMessage = "Dropbox API did not send correct answer for file/directory metadata."; #ifdef QTDROPBOX_DEBUG - qDebug() << "error: " << errorText << endl; + qDebug() << "error: " << lastErrorMessage << endl; #endif emit signal_errorOccurred(lastErrorCode, lastErrorMessage); } @@ -637,10 +637,10 @@ bool QDropbox2Folder::requestCopy(const QString& to_path) //-------------------------------------- // List Folder -bool QDropbox2Folder::contents(QDropbox2Folder::ContentsList& contents, bool include_folders, bool include_deleted) +bool QDropbox2Folder::contents(FoldersModel *contents, bool include_folders, bool include_deleted) { bool result = false; - contents.clear(); + contents->clear(); latestCursor.clear(); // make sure we get a "current" listing, not a differential #ifdef QTDROPBOX_DEBUG @@ -677,7 +677,7 @@ bool QDropbox2Folder::contents(QDropbox2Folder::ContentsList& contents, bool inc continue; } - contents.append(QDropbox2EntityInfo(entry.toObject())); + contents->append(new QDropbox2EntityInfo(entry.toObject())); } } @@ -727,7 +727,7 @@ void QDropbox2Folder::contentsCallback(QNetworkReply* /*reply*/, CallbackPtr rep } else { - ContentsList contents_results; + FoldersModel *contents_results = new FoldersModel(); ContentsData* contents_data = reinterpret_cast(reply_data.data()); QJsonParseError jsonError; @@ -747,7 +747,7 @@ void QDropbox2Folder::contentsCallback(QNetworkReply* /*reply*/, CallbackPtr rep continue; } - contents_results.append(QDropbox2EntityInfo(entry.toObject())); + contents_results->append(new QDropbox2EntityInfo(entry.toObject())); } } @@ -810,10 +810,10 @@ bool QDropbox2Folder::getContents(QNetworkReply*& reply, const QString& cursor, //-------------------------------------- // Search -bool QDropbox2Folder::search(QDropbox2Folder::ContentsList& contents, const QString& query, quint64 max_results, const QString& mode) +bool QDropbox2Folder::search(FoldersModel *contents, const QString& query, quint64 max_results, const QString& mode) { bool result = false; - contents.clear(); + contents->clear(); #ifdef QTDROPBOX_DEBUG qDebug() << "QDropbox2Folder::search()" << endl; @@ -845,7 +845,7 @@ bool QDropbox2Folder::search(QDropbox2Folder::ContentsList& contents, const QStr { QJsonObject obj = entry.toObject(); if(obj.contains("metadata")) - contents.append(QDropbox2EntityInfo(entry.toObject())); + contents->append(new QDropbox2EntityInfo(entry.toObject())); } } @@ -891,7 +891,7 @@ void QDropbox2Folder::searchCallback(QNetworkReply* /*reply*/, CallbackPtr /*rep } else { - ContentsList search_results; + FoldersModel *search_results = new FoldersModel(); QJsonParseError jsonError; QJsonDocument json = QJsonDocument::fromJson(lastResponse.toUtf8(), &jsonError); @@ -905,7 +905,7 @@ void QDropbox2Folder::searchCallback(QNetworkReply* /*reply*/, CallbackPtr /*rep { QJsonObject obj = entry.toObject(); if(obj.contains("metadata")) - search_results.append(QDropbox2EntityInfo(entry.toObject())); + search_results->append(new QDropbox2EntityInfo(entry.toObject())); } } } diff --git a/src/qdropbox2folder.h b/src/qdropbox2folder.h old mode 100644 new mode 100755 index b81953b..6aae336 --- a/src/qdropbox2folder.h +++ b/src/qdropbox2folder.h @@ -1,11 +1,14 @@ #pragma once #include "qdropbox2common.h" +#include #include "qdropbox2.h" #include "qdropbox2entity.h" #include "qdropbox2entityinfo.h" +#import "FoldersModel.h" + //! Allows access to folders stored on Dropbox class QDROPBOXSHARED_EXPORT QDropbox2Folder : public QObject, public IQDropbox2Entity @@ -13,7 +16,8 @@ class QDROPBOXSHARED_EXPORT QDropbox2Folder : public QObject, public IQDropbox2E Q_OBJECT public: // typedefs and enums - typedef QList ContentsList; +// typedef QList ContentsList; +// typedef QList ContentsList; public: /*! @@ -162,7 +166,7 @@ class QDROPBOXSHARED_EXPORT QDropbox2Folder : public QObject, public IQDropbox2E \param changes Container to receive the changes detected. \returns true if the folder has changes or false if it has not. */ - bool hasChanged(ContentsList& changes); + bool hasChanged(FoldersModel *changes); /*! Poll a folder contents for changes since the last check. @@ -200,7 +204,7 @@ class QDROPBOXSHARED_EXPORT QDropbox2Folder : public QObject, public IQDropbox2E \param include_deleted Include deleted files in the result. \returns true if the retreival was successful or false if it was not. */ - bool contents(ContentsList& contents, bool include_folders = true, bool include_deleted = false); + bool contents(FoldersModel *contents, bool include_folders = true, bool include_deleted = false); /*! Gets and returns all the contents of the folder. @@ -230,7 +234,7 @@ class QDROPBOXSHARED_EXPORT QDropbox2Folder : public QObject, public IQDropbox2E \param mode The search mode, one of 'filename', 'filename_and_content' or 'filename_deleted'. \returns true if the folder was copied or false if there was an error. */ - bool search(ContentsList& contents, const QString& query, quint64 max_results = 100, const QString& mode = "filename"); + bool search(FoldersModel *contents, const QString& query, quint64 max_results = 100, const QString& mode = "filename"); /*! Search for files and folders that match the search query. @@ -268,9 +272,9 @@ public slots: void signal_operationAborted(); - void signal_contentsResults(const ContentsList& contents_results); - void signal_searchResults(const ContentsList& search_results); - void signal_hasChangedResults(const ContentsList& change_results); + void signal_contentsResults(const FoldersModel *contents_results); + void signal_searchResults(const FoldersModel *search_results); + void signal_hasChangedResults(const FoldersModel *change_results); private slots: void slot_networkRequestFinished(QNetworkReply* rply); @@ -352,3 +356,5 @@ private slots: }; Q_DECLARE_METATYPE(QDropbox2Folder); +//Q_DECLARE_METATYPE(FoldersModel); +Q_DECLARE_METATYPE(FoldersModel::ContentsList); diff --git a/src/qdropbox2global.h b/src/qdropbox2global.h old mode 100644 new mode 100755 index 8e3ffbc..b256704 --- a/src/qdropbox2global.h +++ b/src/qdropbox2global.h @@ -8,7 +8,7 @@ #else # define QDROPBOXSHARED_EXPORT Q_DECL_IMPORT #endif - +#define QDROPBOXSHARED_EXPORT const int MaxSingleUpload = (150*1024*1024); #ifndef QDROPBOX_V2_HTTP_ERROR_CODES diff --git a/tests/config.h.in b/tests/config.h.in new file mode 100644 index 0000000..1c06255 --- /dev/null +++ b/tests/config.h.in @@ -0,0 +1,11 @@ +#ifndef CONFIG_H_IN +#define CONFIG_H_IN + +#define QDROPBOX2_ACCOUNT_TESTS true +#define QDROPBOX2_FOLDER_TESTS true +#define QDROPBOX2_FILE_TESTS true +#define QDROPBOX2_ACCESS_TOKEN "" +#define QDROPBOX2_FOLDER "" +#define QDROPBOX2_FOLDER_NEW "NewFolder" +#define QDROPBOX2_FILE "" +#endif // CONFIG_H_IN diff --git a/tests/qtdropbox2test.cpp b/tests/qtdropbox2test.cpp index c6f82a3..9537595 100644 --- a/tests/qtdropbox2test.cpp +++ b/tests/qtdropbox2test.cpp @@ -52,19 +52,20 @@ void QtDropbox2Test::accountUser_sync() // Retrieve APIv2 account user information (synchronous) QDropbox2User info; QCOMPARE(db2->userInfo(info), true); - - //QTextStream out(stdout); - //out << info.displayName() << ":\n"; - //out << "\t id: " << info.id() << "\n"; - //out << "\t type: " << info.type() << "\n"; - //out << "\t name: " << info.displayName() << "\n"; - //out << "\t email: " << info.email() << "\n"; - //out << "\t emailVerified: " << (info.emailVerified() ? "true" : "false") << "\n"; - //out << "\t isDisabled: " << (info.isDisabled() ? "true" : "false") << "\n"; - //out << "\t locale: " << info.locale() << "\n"; - //out << "\t referralLink: " << info.referralLink().toString() << "\n"; - //out << "\t isPaired: " << (info.isPaired() ? "true" : "false") << "\n"; - //out << "\t country: " << info.country() << "\n"; +#ifdef SHOW_OUTPUT + QTextStream out(stdout); + out << info.displayName() << ":\n"; + out << "\t id: " << info.id() << "\n"; + out << "\t type: " << info.type() << "\n"; + out << "\t name: " << info.displayName() << "\n"; + out << "\t email: " << info.email() << "\n"; + out << "\t emailVerified: " << (info.emailVerified() ? "true" : "false") << "\n"; + out << "\t isDisabled: " << (info.isDisabled() ? "true" : "false") << "\n"; + out << "\t locale: " << info.locale() << "\n"; + out << "\t referralLink: " << info.referralLink().toString() << "\n"; + out << "\t isPaired: " << (info.isPaired() ? "true" : "false") << "\n"; + out << "\t country: " << info.country() << "\n"; +#endif } void QtDropbox2Test::accountUser_async() @@ -80,19 +81,20 @@ void QtDropbox2Test::accountUser_async() QTRY_COMPARE(spy.count(), 1); // make sure the signal was emitted exactly one time QDropbox2User info = qvariant_cast(spy.at(0).at(0)); - - //QTextStream out(stdout); - //out << info.displayName() << ":\n"; - //out << "\t id: " << info.id() << "\n"; - //out << "\t type: " << info.type() << "\n"; - //out << "\t name: " << info.displayName() << "\n"; - //out << "\t email: " << info.email() << "\n"; - //out << "\t emailVerified: " << (info.emailVerified() ? "true" : "false") << "\n"; - //out << "\t isDisabled: " << (info.isDisabled() ? "true" : "false") << "\n"; - //out << "\t locale: " << info.locale() << "\n"; - //out << "\t referralLink: " << info.referralLink().toString() << "\n"; - //out << "\t isPaired: " << (info.isPaired() ? "true" : "false") << "\n"; - //out << "\t country: " << info.country() << "\n"; +#ifdef SHOW_OUTPUT + QTextStream out(stdout); + out << info.displayName() << ":\n"; + out << "\t id: " << info.id() << "\n"; + out << "\t type: " << info.type() << "\n"; + out << "\t name: " << info.displayName() << "\n"; + out << "\t email: " << info.email() << "\n"; + out << "\t emailVerified: " << (info.emailVerified() ? "true" : "false") << "\n"; + out << "\t isDisabled: " << (info.isDisabled() ? "true" : "false") << "\n"; + out << "\t locale: " << info.locale() << "\n"; + out << "\t referralLink: " << info.referralLink().toString() << "\n"; + out << "\t isPaired: " << (info.isPaired() ? "true" : "false") << "\n"; + out << "\t country: " << info.country() << "\n"; +#endif } void QtDropbox2Test::accountUsage_sync() @@ -102,11 +104,12 @@ void QtDropbox2Test::accountUsage_sync() // Retrieve APIv2 account usage information (synchronous) QDropbox2Usage info; QCOMPARE(db2->usageInfo(info), true); - - //QTextStream out(stdout); - //out << "\t used: " << info.used() << "\n"; - //out << "\t allocated: " << info.allocated() << "\n"; - //out << "\tallocationType: " << info.allocationType() << "\n"; +#ifdef SHOW_OUTPUT + QTextStream out(stdout); + out << "\t used: " << info.used() << "\n"; + out << "\t allocated: " << info.allocated() << "\n"; + out << "\tallocationType: " << info.allocationType() << "\n"; +#endif } void QtDropbox2Test::accountUsage_async() @@ -122,11 +125,12 @@ void QtDropbox2Test::accountUsage_async() QTRY_COMPARE(spy.count(), 1); // make sure the signal was emitted exactly one time QDropbox2Usage info = qvariant_cast(spy.at(0).at(0)); - - //QTextStream out(stdout); - //out << "\t used: " << info.used() << "\n"; - //out << "\t allocated: " << info.allocated() << "\n"; - //out << "\tallocationType: " << info.allocationType() << "\n"; +#ifdef SHOW_OUTPUT + QTextStream out(stdout); + out << "\t used: " << info.used() << "\n"; + out << "\t allocated: " << info.allocated() << "\n"; + out << "\tallocationType: " << info.allocationType() << "\n"; +#endif } #endif // QDROPBOX2_ACCOUNT_TESTS @@ -136,7 +140,7 @@ void QtDropbox2Test::createFolder() QVERIFY(db2 != nullptr); // Create a new folder - QDropbox2Folder db_folder(QDROPBOX2_FOLDER, db2); + QDropbox2Folder db_folder(QString("%1/%2").arg(QDROPBOX2_FOLDER).arg(QDROPBOX2_FOLDER_NEW), db2); QCOMPARE(db_folder.create(), true); } @@ -145,7 +149,7 @@ void QtDropbox2Test::copyFolder() QVERIFY(db2 != nullptr); // Copys the folder created in createFolder() to another folder - QDropbox2Folder db_folder(QDROPBOX2_FOLDER, db2); + QDropbox2Folder db_folder(QString("%1/%2").arg(QDROPBOX2_FOLDER).arg(QDROPBOX2_FOLDER_NEW), db2); QCOMPARE(db_folder.copy("/QtDropbox2Folder"), true); } @@ -154,7 +158,7 @@ void QtDropbox2Test::removeFolder1() QVERIFY(db2 != nullptr); // Removes the folder created in createFolder() - QDropbox2Folder db_folder(QDROPBOX2_FOLDER, db2); + QDropbox2Folder db_folder("/QtDropbox2Folder", db2); QCOMPARE(db_folder.remove(), true); } @@ -172,29 +176,33 @@ void QtDropbox2Test::getContents() QVERIFY(db2 != nullptr); // Retrieves the contents of the root folder - QDropbox2Folder db_folder("/", db2); - QDropbox2Folder::ContentsList contents; + QDropbox2Folder db_folder("", db2); + FoldersModel *contents = new FoldersModel(); QCOMPARE(db_folder.contents(contents), true); - - //QTextStream out(stdout); - //foreach(const QDropbox2EntityInfo& entry, contents) - //{ - // out << entry.path() << ":\n"; - // if(entry.isDeleted()) - // out << "\t isDeleted: true\n"; - // else - // { - // out << "\t id: " << entry.id() << "\n"; - // out << "\tclientModified: " << entry.clientModified().toString() << "\n"; - // out << "\tserverModified: " << entry.serverModified().toString() << "\n"; - // out << "\t revisionHash: " << entry.revisionHash() << "\n"; - // out << "\t bytes: " << entry.bytes() << "\n"; - // out << "\t size: " << entry.size() << "\n"; - // out << "\t isShared: " << (entry.isShared() ? "true" : "false") << "\n"; - // out << "\t isDirectory: " << (entry.isDirectory() ? "true" : "false") << "\n"; - // } - // out.flush(); - //} +#ifdef SHOW_OUTPUT + QTextStream out(stdout); + out<<"\n\n"; +// foreach(const QDropbox2EntityInfo *entry, contents) + for (int i=0; icount();i++) + { + const QDropbox2EntityInfo *entry = contents->at(i); + out << entry->path() << ":\n"; + if(entry->isDeleted()) + out << "\t isDeleted: true\n"; + else + { + out << "\t id: " << entry->id() << "\n"; + out << "\tclientModified: " << entry->clientModified().toString() << "\n"; + out << "\tserverModified: " << entry->serverModified().toString() << "\n"; + out << "\t revisionHash: " << entry->revisionHash() << "\n"; + out << "\t bytes: " << entry->bytes() << "\n"; + out << "\t size: " << entry->size() << "\n"; + out << "\t isShared: " << (entry->isShared() ? "true" : "false") << "\n"; + out << "\t isDirectory: " << (entry->isDirectory() ? "true" : "false") << "\n"; + } + out.flush(); + } +#endif } void QtDropbox2Test::checkForChanges() @@ -204,15 +212,16 @@ void QtDropbox2Test::checkForChanges() // Check for changes in a folder (synchronous) QDropbox2Folder db_folder(QDROPBOX2_FOLDER, db2); // creation retrieves the latest cursor QThread::msleep(1000); - QDropbox2Folder::ContentsList changes; + FoldersModel *changes = new FoldersModel(); QCOMPARE(db_folder.hasChanged(changes), false); - - //QTextStream out(stdout); - //out << "Changes were "; - //QDropbox2Folder::ContentsList changes; - //if(!db_folder.hasChanged(changes)) - // out << "not "; - //out << "detected in the folder.\n"; +#ifdef SHOW_OUTPUT + QTextStream out(stdout); + out << "Changes were "; +// QDropbox2Folder::ContentsList changes; + if(!db_folder.hasChanged(changes)) + out << "not "; + out << "detected in the folder.\n"; +#endif } void QtDropbox2Test::waitForChanges() @@ -362,26 +371,27 @@ void QtDropbox2Test::getRevisions() QDropbox2File db_file(db_path, db2); QDropbox2File::RevisionsList revisions; QCOMPARE(db_file.revisions(revisions, 5), true); - - //QTextStream out(stdout); - //foreach(const QDropbox2EntityInfo& entry, revisions) - //{ - // out << db_file.filename() << ":\n"; - // if(entry.isDeleted()) - // out << "\t isDeleted: true\n"; - // else - // { - // out << "\t id: " << entry.id() << "\n"; - // out << "\tclientModified: " << entry.clientModified().toString() << "\n"; - // out << "\tserverModified: " << entry.serverModified().toString() << "\n"; - // out << "\t revisionHash: " << entry.revisionHash() << "\n"; - // out << "\t bytes: " << entry.bytes() << "\n"; - // out << "\t size: " << entry.size() << "\n"; - // out << "\t path: " << entry.path() << "\n"; - // out << "\t isShared: " << (entry.isShared() ? "true" : "false") << "\n"; - // out << "\t isDirectory: " << (entry.isDirectory() ? "true" : "false") << "\n"; - // } - //} +//#ifdef SHOW_OUTPUT +// QTextStream out(stdout); +// foreach(const QDropbox2EntityInfo& entry, revisions) +// { +// out << db_file.filename() << ":\n"; +// if(entry.isDeleted()) +// out << "\t isDeleted: true\n"; +// else +// { +// out << "\t id: " << entry.id() << "\n"; +// out << "\tclientModified: " << entry.clientModified().toString() << "\n"; +// out << "\tserverModified: " << entry.serverModified().toString() << "\n"; +// out << "\t revisionHash: " << entry.revisionHash() << "\n"; +// out << "\t bytes: " << entry.bytes() << "\n"; +// out << "\t size: " << entry.size() << "\n"; +// out << "\t path: " << entry.path() << "\n"; +// out << "\t isShared: " << (entry.isShared() ? "true" : "false") << "\n"; +// out << "\t isDirectory: " << (entry.isDirectory() ? "true" : "false") << "\n"; +// } +// } +//#endif } void QtDropbox2Test::getLink() @@ -404,28 +414,31 @@ void QtDropbox2Test::search() QString path = info.path(); QDropbox2Folder db_folder(path, db2); - QDropbox2Folder::ContentsList contents; + FoldersModel *contents = new FoldersModel(); QCOMPARE(db_folder.search(contents, QString(".%1").arg(suffix)), true); - - //QTextStream out(stdout); - //foreach(const QDropbox2EntityInfo& entry, contents) - //{ - // if(entry.isDeleted()) - // out << "\t isDeleted: true\n"; - // else - // { - // out << "\t id: " << entry.id() << "\n"; - // out << "\tclientModified: " << entry.clientModified().toString() << "\n"; - // out << "\tserverModified: " << entry.serverModified().toString() << "\n"; - // out << "\t revisionHash: " << entry.revisionHash() << "\n"; - // out << "\t bytes: " << entry.bytes() << "\n"; - // out << "\t size: " << entry.size() << "\n"; - // out << "\t path: " << entry.path() << "\n"; - // out << "\t isShared: " << (entry.isShared() ? "true" : "false") << "\n"; - // out << "\t isDirectory: " << (entry.isDirectory() ? "true" : "false") << "\n"; - // } - // out.flush(); - //} +#ifdef SHOW_OUTPUT + QTextStream out(stdout); + for (int i=0;icount();i++){ +// foreach(const QDropbox2EntityInfo *entry, contents) +// { +const QDropbox2EntityInfo *entry = contents->at(i); + if(entry->isDeleted()) + out << "\t isDeleted: true\n"; + else + { + out << "\t id: " << entry->id() << "\n"; + out << "\tclientModified: " << entry->clientModified().toString() << "\n"; + out << "\tserverModified: " << entry->serverModified().toString() << "\n"; + out << "\t revisionHash: " << entry->revisionHash() << "\n"; + out << "\t bytes: " << entry->bytes() << "\n"; + out << "\t size: " << entry->size() << "\n"; + out << "\t path: " << entry->path() << "\n"; + out << "\t isShared: " << (entry->isShared() ? "true" : "false") << "\n"; + out << "\t isDirectory: " << (entry->isDirectory() ? "true" : "false") << "\n"; + } + out.flush(); + } +#endif } void QtDropbox2Test::downloadFile() @@ -434,13 +447,14 @@ void QtDropbox2Test::downloadFile() // Download a file without signals QDropbox2File db_file(db_path, db2); - //connect(&db_file, &QDropbox2File::signal_downloadProgress, [](qint64 bytesReceived, qint64 bytesTotal) - // { - // QString percent = QString::number((qint32)((bytesReceived / (bytesTotal * 1.0)) * 100.0)); - // std::cout << "Download: " << percent.toUtf8().constData() << "%" << "\r"; - // std::cout.flush(); - // }); - +#ifdef SHOW_OUTPUT + connect(&db_file, &QDropbox2File::signal_downloadProgress, [](qint64 bytesReceived, qint64 bytesTotal) + { + QString percent = QString::number((qint32)((bytesReceived / (bytesTotal * 1.0)) * 100.0)); + std::cout << "Download: " << percent.toUtf8().constData() << "%" << "\r"; + std::cout.flush(); + }); +#endif // opening the file causes it to be downloaded and cached locally QCOMPARE(db_file.open(QIODevice::ReadOnly), true); QDropbox2EntityInfo info(db_file.metadata()); @@ -450,24 +464,25 @@ void QtDropbox2Test::downloadFile() QByteArray data = db_file.readAll(); QByteArray local_md5 = QCryptographicHash::hash(data, QCryptographicHash::Md5); QCOMPARE(md5, local_md5); - - //QTextStream out(stdout); - //out << db_file.filename() << ":\n"; - //if(entry.isDeleted()) - // out << "\t isDeleted: true\n"; - //else - //{ - // out << "\t id: " << info.id() << "\n"; - // out << "\tclientModified: " << info.clientModified().toString() << "\n"; - // out << "\tserverModified: " << info.serverModified().toString() << "\n"; - // out << "\t revisionHash: " << info.revisionHash() << "\n"; - // out << "\t bytes: " << info.bytes() << "\n"; - // out << "\t size: " << info.size() << "\n"; - // out << "\t path: " << info.path() << "\n"; - // out << "\t isShared: " << (info.isShared() ? "true" : "false") << "\n"; - // out << "\t isDirectory: " << (info.isDirectory() ? "true" : "false") << "\n"; - //} - //out.flush(); +#ifdef SHOW_OUTPUT + QTextStream out(stdout); + out << db_file.filename() << ":\n"; + if(info.isDeleted()) + out << "\t isDeleted: true\n"; + else + { + out << "\t id: " << info.id() << "\n"; + out << "\tclientModified: " << info.clientModified().toString() << "\n"; + out << "\tserverModified: " << info.serverModified().toString() << "\n"; + out << "\t revisionHash: " << info.revisionHash() << "\n"; + out << "\t bytes: " << info.bytes() << "\n"; + out << "\t size: " << info.size() << "\n"; + out << "\t path: " << info.path() << "\n"; + out << "\t isShared: " << (info.isShared() ? "true" : "false") << "\n"; + out << "\t isDirectory: " << (info.isDirectory() ? "true" : "false") << "\n"; + } + out.flush(); +#endif } void QtDropbox2Test::removeFile() diff --git a/tests/qtdropbox2test.pro b/tests/qtdropbox2test.pro index 567fee6..afadc6c 100644 --- a/tests/qtdropbox2test.pro +++ b/tests/qtdropbox2test.pro @@ -1,4 +1,4 @@ -QT += core network testlib xml widgets +QT += core network testlib xml widgets qml quick TARGET = qtdropbox2test CONFIG += console @@ -7,12 +7,14 @@ CONFIG -= app_bundle TEMPLATE = app DEFINES += SRCDIR=\\\"$$PWD/\\\" +DEFINES += SHOW_OUTPUT SOURCES += qtdropbox2test.cpp HEADERS += qtdropbox2test.h \ config.h INCLUDEPATH += ../src +DISTFILES += config.h.in QTVER=5_6_2 BUILDTYPE=Release CONFIG(debug, debug|release) { @@ -37,12 +39,14 @@ unix { COMPILER=clang LIBS += -stdlib=libc++ CONFIG += x86_64 - QMAKE_MAC_SDK = macosx10.11 - QMAKE_MACOSX_DEPLOYMENT_TARGET=10.7 +# QMAKE_MAC_SDK = macosx10.11 +# QMAKE_MACOSX_DEPLOYMENT_TARGET=10.7 QMAKE_CXXFLAGS+=-std=c++11 -stdlib=libc++ } } +include(../qtdropbox2.pri) +#QMAKE_SUBSTITUTES += $$PWD/config.h.in # I don't understand QtCreator's logic of putting the shadow build folder # outside the project folder, but that's the default. -LIBS += -lQtDropbox2 -L../../build-qtdropbox2-Desktop_Qt_$${QTVER}_$${COMPILER}_64bit-$${BUILDTYPE}$${OUTPUT} +#LIBS += -lQtDropbox2 -L../../build-qtdropbox2-Desktop_Qt_$${QTVER}_$${COMPILER}_64bit-$${BUILDTYPE}$${OUTPUT} From 4f612a7dc5d1b9a38b4f7781122be612b460dbb6 Mon Sep 17 00:00:00 2001 From: Calugar George Date: Fri, 10 May 2019 16:29:31 +0300 Subject: [PATCH 2/7] Inital test case --- src/qdropbox2file.h | 9 +++++---- src/qdropbox2folder.h | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/qdropbox2file.h b/src/qdropbox2file.h index 9519839..a229bb9 100755 --- a/src/qdropbox2file.h +++ b/src/qdropbox2file.h @@ -22,7 +22,7 @@ class QDROPBOXSHARED_EXPORT QDropbox2File : public QIODevice, public IQDropbox2Entity { Q_OBJECT - + Q_PROPERTY(QDropbox2 api READ api WRITE setApi) public: // typedefs and enums typedef QList RevisionsList; @@ -32,7 +32,7 @@ class QDROPBOXSHARED_EXPORT QDropbox2File : public QIODevice, public IQDropbox2E \param parent Parent QObject */ - QDropbox2File(QObject* parent = 0); + QDropbox2File(QObject* parent = nullptr); /*! Copy constructor. @@ -90,6 +90,7 @@ class QDROPBOXSHARED_EXPORT QDropbox2File : public QIODevice, public IQDropbox2E */ bool open(OpenMode mode); + /*! Closes the file buffer. If the file was opened with QIODevice::WriteOnly (or QIODevice::ReadWrite) the file content buffer will be flushed and written to @@ -102,12 +103,12 @@ class QDROPBOXSHARED_EXPORT QDropbox2File : public QIODevice, public IQDropbox2E \param dropbox Pointer to the QDropbox2 object */ - void setApi(QDropbox2* dropbox); + Q_INVOKABLE void setApi(QDropbox2* dropbox); /*! Returns a pointer to the QDropbox2 instance that is used to connect to Dropbox. */ - QDropbox2* api() const { return _api; } + Q_INVOKABLE QDropbox2* api() const { return _api; } /*! Set the name of the file you want to access. Remember to use correct Dropbox path diff --git a/src/qdropbox2folder.h b/src/qdropbox2folder.h index 6aae336..4ac41ea 100755 --- a/src/qdropbox2folder.h +++ b/src/qdropbox2folder.h @@ -14,7 +14,7 @@ class QDROPBOXSHARED_EXPORT QDropbox2Folder : public QObject, public IQDropbox2Entity { Q_OBJECT - + Q_PROPERTY(QDropbox2 api READ api WRITE setApi) public: // typedefs and enums // typedef QList ContentsList; // typedef QList ContentsList; From 74ad03c867c22c87f509440f5247be11525bd741 Mon Sep 17 00:00:00 2001 From: Calugar George Date: Fri, 10 May 2019 16:31:39 +0300 Subject: [PATCH 3/7] Update QML Support --- qtdropbox2.pri | 2 + src/FoldersModel.cpp | 19 +++++++--- src/FoldersModel.h | 2 + src/qdropbox2.cpp | 3 ++ src/qdropbox2.h | 24 +++++++++++- src/qdropbox2file.cpp | 80 ++++++++++++++++++++++++++++++++-------- src/qdropbox2file.h | 42 +++++++++++++++++---- src/qdropbox2folder.cpp | 19 +++++++--- src/qdropbox2folder.h | 24 ++++++++++-- tests/qtdropbox2test.cpp | 26 +++++++++---- tests/qtdropbox2test.h | 6 ++- 11 files changed, 198 insertions(+), 49 deletions(-) diff --git a/qtdropbox2.pri b/qtdropbox2.pri index 5a7a05f..164ba5a 100644 --- a/qtdropbox2.pri +++ b/qtdropbox2.pri @@ -1,3 +1,5 @@ +INCLUDEPATH += $$PWD/src + SOURCES += \ $$PWD/src/FoldersModel.cpp \ $$PWD/src/qdropbox2.cpp \ diff --git a/src/FoldersModel.cpp b/src/FoldersModel.cpp index 74de7f8..c8da540 100644 --- a/src/FoldersModel.cpp +++ b/src/FoldersModel.cpp @@ -12,12 +12,15 @@ FoldersModel::~FoldersModel() QVariant FoldersModel::data(const QModelIndex &index, int role) const { - qDebug()<<" Data asked for "<filename(); - + // return m_contentList.at(index.row(); + if (index.row()filename(); + case DirectoryRole: return m_contentList.at(index.row())->isDirectory(); + case PathRole:return m_contentList.at(index.row())->path(); + } } return QVariant(); } @@ -42,15 +45,21 @@ QHash FoldersModel::roleNames() const QHash roles; roles[IdRole] = "fileId"; roles[NameRole] = "name"; + roles[DirectoryRole] = "isDirectory"; + roles[PathRole] = "path"; return roles; } void FoldersModel::append(QDropbox2EntityInfo *item) { + beginInsertRows(QModelIndex(), count(),count()); m_contentList.append(item); + endInsertRows(); } void FoldersModel::clear() { + beginResetModel(); m_contentList.clear(); + endResetModel(); } diff --git a/src/FoldersModel.h b/src/FoldersModel.h index ed69119..6e6a215 100644 --- a/src/FoldersModel.h +++ b/src/FoldersModel.h @@ -14,6 +14,8 @@ class FoldersModel : public QAbstractListModel enum FolderListRole { IdRole = Qt::UserRole, // 256 NameRole, + DirectoryRole, + PathRole }; //TODO: Change to no QDropbox2EntityInfo pointer as soon as a qml test exists typedef QList ContentsList; diff --git a/src/qdropbox2.cpp b/src/qdropbox2.cpp index 15a6f46..53ceaba 100755 --- a/src/qdropbox2.cpp +++ b/src/qdropbox2.cpp @@ -1,4 +1,5 @@ #include "qdropbox2.h" +#include QDropbox2::QDropbox2(QObject *parent) : QObject(parent), @@ -605,3 +606,5 @@ void QDropbox2::stopEventLoop() #endif eventLoop->exit(); } + +Q_COREAPP_STARTUP_FUNCTION(registerQDropbox2Types); diff --git a/src/qdropbox2.h b/src/qdropbox2.h index 842b2de..e8909b7 100755 --- a/src/qdropbox2.h +++ b/src/qdropbox2.h @@ -12,6 +12,10 @@ #include "qdropbox2account.h" #include "qdropbox2entityinfo.h" +#include "FoldersModel.h" + +#include + /*! The main entry point of QDropbox2, a heavily re-factored version of Daniel Eder's QtDropbox to support the new Dropbox APIv2 interface. */ @@ -175,7 +179,7 @@ class QDROPBOXSHARED_EXPORT QDropbox2 : public QObject \param t token string */ - void setAccessToken(const QString& token); + Q_INVOKABLE void setAccessToken(const QString& token); /*! Returns the current access token in use. @@ -372,3 +376,21 @@ private slots: }; Q_DECLARE_METATYPE(QDropbox2::Error); + +//Q_DECLARE_METATYPE(QDropbox2); +static void registerQDropbox2Types() { + // qmlRegisterSingletonType("QtDropBox2", + // 1,0, + // "DropBoxCPP", + // DropBoxCPP::registerComponent); + qmlRegisterType("QtDropBox2", + 1,0, + "QDropbox2"); + qmlRegisterType("QtDropBox2", + 1,0, + "FoldersModel"); +// qmlRegisterType("QtDropBox2", +// 1,0, +// "QDropbox2EntityInfo"); +} + diff --git a/src/qdropbox2file.cpp b/src/qdropbox2file.cpp index 9a22ae8..634ee54 100755 --- a/src/qdropbox2file.cpp +++ b/src/qdropbox2file.cpp @@ -1,4 +1,5 @@ #include "qdropbox2file.h" +#include QDropbox2File::QDropbox2File(QObject *parent) : QIODevice(parent), @@ -39,8 +40,11 @@ QDropbox2File::~QDropbox2File() delete eventLoop; } -void QDropbox2File::init(QDropbox2 *api, const QString& filename, qint64 threshold) +void QDropbox2File::init(QDropbox2 *api, + const QString& filename, + qint64 threshold) { + qDebug()<<"Init Called "<size(); + return true; +//#endif +} + void QDropbox2File::close() { if(isMode(QIODevice::WriteOnly) && _buffer->length()) @@ -294,6 +337,7 @@ QNetworkReply* QDropbox2File::sendGET(QNetworkRequest& rq) QNetworkReply *reply = QNAM.get(rq); connect(this, &QDropbox2File::signal_operationAborted, reply, &QNetworkReply::abort); connect(reply, &QNetworkReply::downloadProgress, this, &QDropbox2File::signal_downloadProgress); + connect(reply, &QNetworkReply::finished,this,&QDropbox2File::signal_downloadFinished); return reply; } @@ -309,8 +353,10 @@ bool QDropbox2File::getFile(const QString& filename) url.setPath("/2/files/download"); QNetworkRequest req; - if(!_api->createAPIv2Reqeust(url, req)) + if(!_api->createAPIv2Reqeust(url, req)){ + qDebug()<<"Can't create the request"; return result; + } req.setRawHeader("Dropbox-API-arg", QString("{ \"path\": \"%1\" }") .arg((filename.compare("/") == 0) ? "" : filename).toUtf8()); @@ -326,13 +372,14 @@ bool QDropbox2File::getFile(const QString& filename) replyMap[reply] = reply_data; startEventLoop(); - + qDebug()<<"Event loop ended "<readAll(); QString resp_str; -//#ifdef QTDROPBOX_DEBUG -// resp_str = QString(response.toHex()); -// qDebug() << "QDropbox2File::replyFileContent response = " << resp_str << endl; -// -//#endif +#ifdef QTDROPBOX_DEBUG + resp_str = QString(response.toHex()); + qDebug() << "QDropbox2File::replyFileContent response = " << resp_str << endl; + +#endif if(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() == QDROPBOX_V2_ERROR) { @@ -623,6 +670,7 @@ void QDropbox2File::stopEventLoop() if(!eventLoop) return; eventLoop->exit(); + eventLoop = nullptr; } QDropbox2EntityInfo QDropbox2File::metadata() @@ -1153,3 +1201,5 @@ QUrl QDropbox2File::requestStreamingLink() return result; } + +Q_COREAPP_STARTUP_FUNCTION(registerQDropbox2FileTypes); diff --git a/src/qdropbox2file.h b/src/qdropbox2file.h index 9519839..0101315 100755 --- a/src/qdropbox2file.h +++ b/src/qdropbox2file.h @@ -22,17 +22,19 @@ class QDROPBOXSHARED_EXPORT QDropbox2File : public QIODevice, public IQDropbox2Entity { Q_OBJECT - + Q_PROPERTY(QDropbox2 *api READ api WRITE setApi) + Q_PROPERTY(QString filename READ filename WRITE setFilename) public: // typedefs and enums typedef QList RevisionsList; public: + Q_ENUM(OpenMode) /*! Default constructor. Use setApi() and setFilename() to access Dropbox. \param parent Parent QObject */ - QDropbox2File(QObject* parent = 0); + QDropbox2File(QObject* parent = nullptr); /*! Copy constructor. @@ -49,7 +51,7 @@ class QDROPBOXSHARED_EXPORT QDropbox2File : public QIODevice, public IQDropbox2E \param api Pointer to a QDropbox2 that is connected to an account. \param parent Parent QObject */ - QDropbox2File(QDropbox2* api, QObject* parent = 0); + QDropbox2File(QDropbox2* api, QObject* parent = nullptr); /*! Creates an instance of QDropbox2File that may access a file on Dropbox. @@ -88,8 +90,9 @@ class QDROPBOXSHARED_EXPORT QDropbox2File : public QIODevice, public IQDropbox2E \param mode The access mode of the file. Equivalent to QIODevice. */ - bool open(OpenMode mode); - + bool open(OpenMode mode); +// Q_INVOKABLE bool openReadOnly() { return open(QIODevice::ReadOnly);}inline + Q_INVOKABLE bool downloadFile(); /*! Closes the file buffer. If the file was opened with QIODevice::WriteOnly (or QIODevice::ReadWrite) the file content buffer will be flushed and written to @@ -102,12 +105,12 @@ class QDROPBOXSHARED_EXPORT QDropbox2File : public QIODevice, public IQDropbox2E \param dropbox Pointer to the QDropbox2 object */ - void setApi(QDropbox2* dropbox); + Q_INVOKABLE void setApi(QDropbox2* dropbox); /*! Returns a pointer to the QDropbox2 instance that is used to connect to Dropbox. */ - QDropbox2* api() const { return _api; } + Q_INVOKABLE QDropbox2* api() const { return _api; } /*! Set the name of the file you want to access. Remember to use correct Dropbox path @@ -193,7 +196,7 @@ class QDROPBOXSHARED_EXPORT QDropbox2File : public QIODevice, public IQDropbox2E \returns A valid QUrl suitable for use with QDesktopServices::openUrl(), or an invalid QUrl on failure. */ - QUrl temporaryLink(); + Q_INVOKABLE QUrl temporaryLink(); /*! Remove the file from Dropbox. @@ -305,6 +308,7 @@ public slots: */ void signal_errorOccurred(int errorcode, const QString& errormessage = QString()); + /*! Emitted as file contents are downloaded from Dropbox. @@ -312,6 +316,7 @@ public slots: \param bytesTotal Total expected size of the payload. */ void signal_downloadProgress(qint64 bytesReceived, qint64 bytesTotal); + void signal_downloadFinished(); /*! Emitted as file contents are uploaded to Dropbox. @@ -454,3 +459,24 @@ private slots: }; Q_DECLARE_METATYPE(QDropbox2File); +static void registerQDropbox2FileTypes() { + + qmlRegisterType("QtDropBox2", + 1,0, + "QDropbox2File"); +// qmlRegisterSingletonType("QtDropBox2", +// 1,0, +// "QDropbox2FileSignleton", +// [](QQmlEngine *engine, +// QJSEngine *scriptEngine) -> QObject*{ +// Q_UNUSED(engine) +// Q_UNUSED(scriptEngine) +// return new QDropbox2File(); +// }); + +// qRegisterMetaType("OpenMode"); +// qmlRegisterUncreatableType("QtDropBox2", +// 1, 0, +// "OpenMode", +// "Cannot create WarningLevel in QML"); +} diff --git a/src/qdropbox2folder.cpp b/src/qdropbox2folder.cpp index 3f7a14e..6587643 100755 --- a/src/qdropbox2folder.cpp +++ b/src/qdropbox2folder.cpp @@ -1,4 +1,5 @@ #include +#include #include "qdropbox2folder.h" @@ -7,7 +8,8 @@ QDropbox2Folder::QDropbox2Folder(QObject *parent) IQDropbox2Entity(), QNAM(this) { - init(nullptr, ""); + init(nullptr, + ""); } QDropbox2Folder::QDropbox2Folder(QDropbox2 *api, QObject *parent) @@ -49,13 +51,15 @@ void QDropbox2Folder::init(QDropbox2 *api, const QString& foldername) lastErrorCode = 0; lastErrorMessage = ""; - if(api) + if(api){ accessToken = api->accessToken(); - + } connect(&QNAM, &QNetworkAccessManager::finished, this, &QDropbox2Folder::slot_networkRequestFinished); - getLatestCursor(latestCursor); -} + if (api){ + getLatestCursor(latestCursor); + + }} int QDropbox2Folder::error() { @@ -164,7 +168,8 @@ bool QDropbox2Folder::getLatestCursor(QString& cursor, bool include_deleted) #endif QUrl url; - url.setUrl(QDROPBOX2_API_URL, QUrl::StrictMode); + url.setUrl(QDROPBOX2_API_URL, + QUrl::StrictMode); url.setPath("/2/files/list_folder/get_latest_cursor"); Q_ASSERT(url.isValid()); @@ -959,3 +964,5 @@ bool QDropbox2Folder::getSearch(QNetworkReply*& reply, const QString& query, qui result = (lastErrorCode == 0); return result; } + +Q_COREAPP_STARTUP_FUNCTION(registerQDropbox2FolderTypes); diff --git a/src/qdropbox2folder.h b/src/qdropbox2folder.h index 6aae336..e22cae9 100755 --- a/src/qdropbox2folder.h +++ b/src/qdropbox2folder.h @@ -14,7 +14,8 @@ class QDROPBOXSHARED_EXPORT QDropbox2Folder : public QObject, public IQDropbox2Entity { Q_OBJECT - + Q_PROPERTY(QDropbox2 *api READ api WRITE setApi) + Q_PROPERTY(QString foldername READ foldername WRITE setFoldername) public: // typedefs and enums // typedef QList ContentsList; // typedef QList ContentsList; @@ -25,7 +26,7 @@ class QDROPBOXSHARED_EXPORT QDropbox2Folder : public QObject, public IQDropbox2E \param parent Parent QObject */ - QDropbox2Folder(QObject* parent = 0); + QDropbox2Folder(QObject* parent = nullptr); /*! Copy constructor. @@ -79,7 +80,9 @@ class QDROPBOXSHARED_EXPORT QDropbox2Folder : public QObject, public IQDropbox2E /*! Returns a pointer to the QDropbox2 instance that is used to connect to Dropbox. */ - QDropbox2* api() const { return _api; } + QDropbox2* api() const { + return _api; + } /*! Set the name of the file you want to access. Remember to use correct Dropbox path @@ -204,7 +207,7 @@ class QDROPBOXSHARED_EXPORT QDropbox2Folder : public QObject, public IQDropbox2E \param include_deleted Include deleted files in the result. \returns true if the retreival was successful or false if it was not. */ - bool contents(FoldersModel *contents, bool include_folders = true, bool include_deleted = false); + Q_INVOKABLE bool contents(FoldersModel *contents, bool include_folders = true, bool include_deleted = false); /*! Gets and returns all the contents of the folder. @@ -358,3 +361,16 @@ private slots: Q_DECLARE_METATYPE(QDropbox2Folder); //Q_DECLARE_METATYPE(FoldersModel); Q_DECLARE_METATYPE(FoldersModel::ContentsList); + +static void registerQDropbox2FolderTypes() { + + qmlRegisterType("QtDropBox2", + 1,0, + "QDropbox2Folder"); + // qmlRegisterType("QtDropBox2", + // 1,0, + // "FoldersModel"); + // qmlRegisterType("QtDropBox2", + // 1,0, + // "QDropbox2EntityInfo"); +} diff --git a/tests/qtdropbox2test.cpp b/tests/qtdropbox2test.cpp index 9537595..95b09e3 100644 --- a/tests/qtdropbox2test.cpp +++ b/tests/qtdropbox2test.cpp @@ -141,6 +141,7 @@ void QtDropbox2Test::createFolder() // Create a new folder QDropbox2Folder db_folder(QString("%1/%2").arg(QDROPBOX2_FOLDER).arg(QDROPBOX2_FOLDER_NEW), db2); + qInfo()<<"Create Folder: "< Date: Fri, 10 May 2019 16:50:44 +0300 Subject: [PATCH 4/7] Using QML, the init is not called. Added init call on downloadFile to make sure all initialisations are done --- src/qdropbox2file.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/qdropbox2file.cpp b/src/qdropbox2file.cpp index 634ee54..6fc98a3 100755 --- a/src/qdropbox2file.cpp +++ b/src/qdropbox2file.cpp @@ -148,8 +148,9 @@ bool QDropbox2File::open(QIODevice::OpenMode mode) bool QDropbox2File::downloadFile() { + init(_api,_filename); QDropbox2File::open(QIODevice::ReadOnly); - return true; +// return true; QDropbox2EntityInfo info(metadata()); // qDebug()<<"MetaID Empty? "<callback = &QDropbox2File::resultGetFile; replyMap[reply] = reply_data; + startEventLoop(); qDebug()<<"Event loop ended "< Date: Fri, 10 May 2019 16:50:44 +0300 Subject: [PATCH 5/7] Return filename --- src/qdropbox2file.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/qdropbox2file.cpp b/src/qdropbox2file.cpp index 634ee54..6fc98a3 100755 --- a/src/qdropbox2file.cpp +++ b/src/qdropbox2file.cpp @@ -148,8 +148,9 @@ bool QDropbox2File::open(QIODevice::OpenMode mode) bool QDropbox2File::downloadFile() { + init(_api,_filename); QDropbox2File::open(QIODevice::ReadOnly); - return true; +// return true; QDropbox2EntityInfo info(metadata()); // qDebug()<<"MetaID Empty? "<callback = &QDropbox2File::resultGetFile; replyMap[reply] = reply_data; + startEventLoop(); qDebug()<<"Event loop ended "< Date: Fri, 10 May 2019 23:22:09 +0300 Subject: [PATCH 6/7] Update README.md --- README.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 276f2fa..dcb7e60 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,17 @@ -# QtDropbox2 +# QtDropbox2 - QML Implementation A C++ Qt-based framework for accessing Dropbox using APIv2 +## Fork Information (CMGeorge repo) +The role of this fork is to extend the library to QML + +For more informations see [QMLDropBox](https://github.com/CMGeorge/QMLDropBox) + +**Supported features:** +1. List directoryes +2. Rename File / Directory +3. Download file + + ## Summary QtDropbox2 is a Qt-based framework for accessing the cloud storage service [Dropbox](http://www.dropbox.com) using its new APIv2 protocols. From 613b6568d102a18bfe0564a0c9c8a7bc0a70599a Mon Sep 17 00:00:00 2001 From: "CMG-LAPTOP\\CMGeorge" Date: Fri, 10 May 2019 23:23:14 +0300 Subject: [PATCH 7/7] Support for rename --- src/qdropbox2file.cpp | 3 ++- src/qdropbox2file.h | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/qdropbox2file.cpp b/src/qdropbox2file.cpp index 20f2ea4..ea4f408 100755 --- a/src/qdropbox2file.cpp +++ b/src/qdropbox2file.cpp @@ -66,7 +66,7 @@ void QDropbox2File::init(QDropbox2 *api, position = 0; currentThreshold = 0; fileExists = false; - + initialized = true; if(api) accessToken = api->accessToken(); @@ -1053,6 +1053,7 @@ bool QDropbox2File::requestRemoval(bool permanently) bool QDropbox2File::move(const QString& to_path) { + if (!initialized) init(_api,_filename); return requestMove(to_path); } diff --git a/src/qdropbox2file.h b/src/qdropbox2file.h index 3636538..844f018 100755 --- a/src/qdropbox2file.h +++ b/src/qdropbox2file.h @@ -217,7 +217,7 @@ class QDROPBOXSHARED_EXPORT QDropbox2File : public QIODevice, public IQDropbox2E \returns true if the file was successfully moved or false if there was an error. */ - bool move(const QString& to_path); + Q_INVOKABLE bool move(const QString& to_path); /*! Copy the contents of a file to a new location in the @@ -456,6 +456,8 @@ private slots: SessionMap upload_sessions; QDropbox2EntityInfo *_metadata; + + bool initialized = false; }; Q_DECLARE_METATYPE(QDropbox2File);