From 07d51d07c8af545927110d77053c0b096e57de5a Mon Sep 17 00:00:00 2001 From: Skycoder42 Date: Sat, 3 Mar 2018 17:24:49 +0100 Subject: [PATCH] implemented all ds core and widgets stuff --- src/mvvmdatasynccore/accountmodel.cpp | 15 +- src/mvvmdatasynccore/accountmodel.h | 1 + src/mvvmdatasynccore/datasyncviewmodel.cpp | 10 +- src/mvvmdatasynccore/exchangedevicesmodel.cpp | 148 ++++++++++++ src/mvvmdatasynccore/exchangedevicesmodel.h | 51 ++++ src/mvvmdatasynccore/exchangedevicesmodel_p.h | 20 ++ src/mvvmdatasynccore/exportsetupviewmodel.cpp | 19 ++ src/mvvmdatasynccore/exportsetupviewmodel_p.h | 10 +- .../identityeditviewmodel.cpp | 2 +- .../identityeditviewmodel_p.h | 4 +- src/mvvmdatasynccore/mvvmdatasynccore.pro | 10 +- .../networkexchangeviewmodel.cpp | 225 ++++++++++++++++++ .../networkexchangeviewmodel.h | 69 ++++++ .../networkexchangeviewmodel_p.h | 24 ++ src/mvvmdatasyncwidgets/exportsetupdialog.cpp | 3 + src/mvvmdatasyncwidgets/exportsetupdialog.ui | 19 +- .../mvvmdatasyncwidgets.pro | 10 +- .../networkexchangewindow.cpp | 42 ++++ .../networkexchangewindow.h | 32 +++ .../networkexchangewindow.ui | 129 ++++++++++ .../networkexchangewindow_p.h | 24 ++ .../qtmvvmdatasyncwidgets_global.cpp | 2 + 22 files changed, 845 insertions(+), 24 deletions(-) create mode 100644 src/mvvmdatasynccore/exchangedevicesmodel.cpp create mode 100644 src/mvvmdatasynccore/exchangedevicesmodel.h create mode 100644 src/mvvmdatasynccore/exchangedevicesmodel_p.h create mode 100644 src/mvvmdatasynccore/networkexchangeviewmodel.cpp create mode 100644 src/mvvmdatasynccore/networkexchangeviewmodel.h create mode 100644 src/mvvmdatasynccore/networkexchangeviewmodel_p.h create mode 100644 src/mvvmdatasyncwidgets/networkexchangewindow.cpp create mode 100644 src/mvvmdatasyncwidgets/networkexchangewindow.h create mode 100644 src/mvvmdatasyncwidgets/networkexchangewindow.ui create mode 100644 src/mvvmdatasyncwidgets/networkexchangewindow_p.h diff --git a/src/mvvmdatasynccore/accountmodel.cpp b/src/mvvmdatasynccore/accountmodel.cpp index 7833120..03fe89d 100644 --- a/src/mvvmdatasynccore/accountmodel.cpp +++ b/src/mvvmdatasynccore/accountmodel.cpp @@ -16,13 +16,14 @@ AccountModel::~AccountModel() {} void AccountModel::setup(AccountManager *accountManager, SyncManager *syncManager) { - beginResetModel(); - d->devices.clear(); if(d->accountManager) d->accountManager->disconnect(this); - d->accountManager = accountManager; if(d->syncManager) d->syncManager->disconnect(this); + + beginResetModel(); + d->devices.clear(); + d->accountManager = accountManager; d->syncManager = syncManager; endResetModel(); @@ -114,6 +115,14 @@ QVariant AccountModel::data(const QModelIndex &index, int role) const return {}; } +QHash AccountModel::roleNames() const +{ + return { + {NameRole, "name"}, + {FingerPrintRole, "fingerPrint"} + }; +} + bool AccountModel::removeDevice(const QModelIndex &index) { if (!index.isValid()) diff --git a/src/mvvmdatasynccore/accountmodel.h b/src/mvvmdatasynccore/accountmodel.h index 0ce73a2..aa766f8 100644 --- a/src/mvvmdatasynccore/accountmodel.h +++ b/src/mvvmdatasynccore/accountmodel.h @@ -33,6 +33,7 @@ public: int rowCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QHash roleNames() const override; Q_INVOKABLE bool removeDevice(const QModelIndex &index); Q_INVOKABLE inline bool removeDevice(int row) { diff --git a/src/mvvmdatasynccore/datasyncviewmodel.cpp b/src/mvvmdatasynccore/datasyncviewmodel.cpp index b350e58..3f6bf94 100644 --- a/src/mvvmdatasynccore/datasyncviewmodel.cpp +++ b/src/mvvmdatasynccore/datasyncviewmodel.cpp @@ -1,5 +1,6 @@ #include "datasyncviewmodel.h" #include "datasyncviewmodel_p.h" +#include "networkexchangeviewmodel.h" #include "exportsetupviewmodel_p.h" #include "changeremoteviewmodel_p.h" #include "identityeditviewmodel_p.h" @@ -117,12 +118,13 @@ void DataSyncViewModel::showDeviceInfo() { if(!d->accountManager) return; - show(IdentityEditViewModel::params(d->accountManager)); + show(IdentityEditViewModel::showParams(d->accountManager)); } void DataSyncViewModel::startExport() { - showForResult(DataSyncViewModelPrivate::ExportRequestCode); + showForResult(DataSyncViewModelPrivate::ExportRequestCode, + ExportSetupViewModel::showParams(tr("Export account data to file:"))); } void DataSyncViewModel::startImport() @@ -181,7 +183,7 @@ void DataSyncViewModel::startImport() .setButtonText(MessageConfig::YesToAll, tr("Reset data")) .setButtonText(MessageConfig::Yes, tr("Keep data")); auto res = CoreApp::showDialog(config); - connect(res, &MessageResult::dialogDone, this, [this, res, data](MessageConfig::StandardButton btn) { + connect(res, &MessageResult::dialogDone, this, [this, data](MessageConfig::StandardButton btn) { switch (btn) { case MessageConfig::YesToAll: d->performImport(false, {}, data, false); @@ -233,7 +235,7 @@ void DataSyncViewModel::changeRemote() void DataSyncViewModel::startNetworkExchange() { - Q_UNIMPLEMENTED(); + show(NetworkExchangeViewModel::showParams(d->accountManager)); } void DataSyncViewModel::setColorMap(DataSyncViewModel::ColorMap colorMap) diff --git a/src/mvvmdatasynccore/exchangedevicesmodel.cpp b/src/mvvmdatasynccore/exchangedevicesmodel.cpp new file mode 100644 index 0000000..382bc27 --- /dev/null +++ b/src/mvvmdatasynccore/exchangedevicesmodel.cpp @@ -0,0 +1,148 @@ +#include "exchangedevicesmodel.h" +#include "exchangedevicesmodel_p.h" +using namespace QtMvvm; +using namespace QtDataSync; + +ExchangeDevicesModel::ExchangeDevicesModel(QObject *parent) : + QAbstractListModel(parent), + d(new ExchangeDevicesModelPrivate()) +{} + +ExchangeDevicesModel::~ExchangeDevicesModel() {} + +void ExchangeDevicesModel::setup(QtDataSync::UserExchangeManager *exchangeManager) +{ + if(d->exchangeManager) + d->exchangeManager->disconnect(this); + + beginResetModel(); + d->exchangeManager = exchangeManager; + d->devices = d->exchangeManager->devices(); + endResetModel(); + + connect(d->exchangeManager, &UserExchangeManager::devicesChanged, + this, &ExchangeDevicesModel::updateDevices); +} + +UserInfo ExchangeDevicesModel::infoAt(int index) const +{ + return d->devices.value(index); +} + +QVariant ExchangeDevicesModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(orientation != Qt::Horizontal) + return {}; + + switch (section) { + case 0: + switch(role) { + case NameRole: + return tr("Name"); + case HostRole: + return tr("Host"); + case PortRole: + return tr("Port"); + case AddressRole: + return tr("Address"); + default: + break; + } + break; + case 1: + if(role == Qt::DisplayRole) + return tr("Address"); + break; + default: + break; + } + + return {}; +} + +int ExchangeDevicesModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + else + return d->devices.size(); +} + +int ExchangeDevicesModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + else + return 2; +} + +QVariant ExchangeDevicesModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + switch (index.column()) { + case 0: + switch(role) { + case NameRole: + return d->devices.value(index.row()).name(); + case HostRole: + return d->devices.value(index.row()).address().toString(); + case PortRole: + return d->devices.value(index.row()).port(); + case AddressRole: + return fullAddress(d->devices.value(index.row())); + default: + break; + } + break; + case 1: + if(role == Qt::DisplayRole) + return fullAddress(d->devices.value(index.row())); + break; + default: + break; + } + + return {}; +} + +QHash ExchangeDevicesModel::roleNames() const +{ + return { + {NameRole, "name"}, + {HostRole, "host"}, + {PortRole, "port"}, + {AddressRole, "address"} + }; +} + +QString ExchangeDevicesModel::fullAddress(const UserInfo &userInfo) +{ + return tr("%1:%2") + .arg(userInfo.address().toString()) + .arg(userInfo.port()); +} + +void ExchangeDevicesModel::updateDevices(const QList &devices) +{ + QList addList; + for(auto device : devices) { + auto dIndex = d->devices.indexOf(device); + if(dIndex != -1) { + if(device.name() != d->devices[dIndex].name()) { + d->devices[dIndex] = device; + emit dataChanged(index(dIndex), index(dIndex, 1)); + } + } else + addList.append(device); + } + + if(addList.isEmpty()) + return; + beginInsertRows(QModelIndex(), + d->devices.size(), + d->devices.size() + addList.size() - 1); + d->devices.append(addList); + endInsertRows(); +} diff --git a/src/mvvmdatasynccore/exchangedevicesmodel.h b/src/mvvmdatasynccore/exchangedevicesmodel.h new file mode 100644 index 0000000..ca55d46 --- /dev/null +++ b/src/mvvmdatasynccore/exchangedevicesmodel.h @@ -0,0 +1,51 @@ +#ifndef QTMVVM_EXCHANGEDEVICESMODEL_H +#define QTMVVM_EXCHANGEDEVICESMODEL_H + +#include +#include + +#include + +#include "QtMvvmDataSyncCore/qtmvvmdatasynccore_global.h" + +namespace QtMvvm { + +class ExchangeDevicesModelPrivate; +class Q_MVVMDATASYNCCORE_EXPORT ExchangeDevicesModel : public QAbstractListModel +{ + Q_OBJECT + +public: + enum Roles { + NameRole = Qt::DisplayRole, + HostRole = Qt::UserRole + 1, + PortRole, + AddressRole + }; + Q_ENUM(Roles) + + explicit ExchangeDevicesModel(QObject *parent = nullptr); + ~ExchangeDevicesModel(); + + Q_INVOKABLE void setup(QtDataSync::UserExchangeManager *exchangeManager); + + Q_INVOKABLE QtDataSync::UserInfo infoAt(int index) const; + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QHash roleNames() const override; + + static QString fullAddress(const QtDataSync::UserInfo &userInfo); + +private Q_SLOTS: + void updateDevices(const QList &devices); + +private: + QScopedPointer d; +}; + +} + +#endif // QTMVVM_EXCHANGEDEVICESMODEL_H diff --git a/src/mvvmdatasynccore/exchangedevicesmodel_p.h b/src/mvvmdatasynccore/exchangedevicesmodel_p.h new file mode 100644 index 0000000..cba6a19 --- /dev/null +++ b/src/mvvmdatasynccore/exchangedevicesmodel_p.h @@ -0,0 +1,20 @@ +#ifndef QTMVVM_EXCHANGEDEVICESMODEL_P_H +#define QTMVVM_EXCHANGEDEVICESMODEL_P_H + +#include + +#include "qtmvvmdatasynccore_global.h" +#include "exchangedevicesmodel.h" + +namespace QtMvvm { + +class ExchangeDevicesModelPrivate +{ +public: + QtDataSync::UserExchangeManager *exchangeManager = nullptr; + QList devices; +}; + +} + +#endif // QTMVVM_EXCHANGEDEVICESMODEL_P_H diff --git a/src/mvvmdatasynccore/exportsetupviewmodel.cpp b/src/mvvmdatasynccore/exportsetupviewmodel.cpp index 7e877e0..7c210a4 100644 --- a/src/mvvmdatasynccore/exportsetupviewmodel.cpp +++ b/src/mvvmdatasynccore/exportsetupviewmodel.cpp @@ -1,6 +1,13 @@ #include "exportsetupviewmodel_p.h" using namespace QtMvvm; +QVariantHash ExportSetupViewModel::showParams(const QString &label) +{ + return { + {QStringLiteral("label"), label} + }; +} + std::tuple ExportSetupViewModel::result(const QVariant &data) { auto map = data.toHash(); @@ -11,6 +18,7 @@ std::tuple ExportSetupViewModel::result(const QVariant &dat ExportSetupViewModel::ExportSetupViewModel(QObject *parent) : ViewModel(parent), + _label(), _trusted(false), _includeServer(false), _password() @@ -21,6 +29,11 @@ ExportSetupViewModel::ExportSetupViewModel(QObject *parent) : this, &ExportSetupViewModel::validChanged); } +QString ExportSetupViewModel::label() const +{ + return _label; +} + bool ExportSetupViewModel::trusted() const { return _trusted; @@ -80,3 +93,9 @@ void ExportSetupViewModel::setPassword(QString password) _password = password; emit passwordChanged(_password); } + +void ExportSetupViewModel::onInit(const QVariantHash ¶ms) +{ + _label = params.value(QStringLiteral("label")).toString(); + emit labelChanged(_label); +} diff --git a/src/mvvmdatasynccore/exportsetupviewmodel_p.h b/src/mvvmdatasynccore/exportsetupviewmodel_p.h index 500753e..1f9ad49 100644 --- a/src/mvvmdatasynccore/exportsetupviewmodel_p.h +++ b/src/mvvmdatasynccore/exportsetupviewmodel_p.h @@ -13,6 +13,7 @@ class Q_MVVMDATASYNCCORE_EXPORT ExportSetupViewModel : public ViewModel { Q_OBJECT + Q_PROPERTY(QString label READ label NOTIFY labelChanged) Q_PROPERTY(bool trusted READ trusted WRITE setTrusted NOTIFY trustedChanged) Q_PROPERTY(bool includeServer READ includeServer WRITE setIncludeServer NOTIFY includeServerChanged) Q_PROPERTY(QString password READ password WRITE setPassword NOTIFY passwordChanged) @@ -20,10 +21,12 @@ class Q_MVVMDATASYNCCORE_EXPORT ExportSetupViewModel : public ViewModel Q_PROPERTY(bool valid READ isValid NOTIFY validChanged) public: - static std::tuple result(const QVariant &data); + static QVariantHash showParams(const QString &label); + static std::tuple result(const QVariant &data); //(trusted, includeServer, password) Q_INVOKABLE explicit ExportSetupViewModel(QObject *parent = nullptr); + QString label() const; bool trusted() const; bool includeServer() const; QString password() const; @@ -37,12 +40,17 @@ public Q_SLOTS: void setPassword(QString password); Q_SIGNALS: + void labelChanged(QString label); void trustedChanged(bool trusted); void includeServerChanged(bool includeServer); void passwordChanged(QString password); void validChanged(); +protected: + void onInit(const QVariantHash ¶ms) override; + private: + QString _label; bool _trusted; QString _password; bool _includeServer; diff --git a/src/mvvmdatasynccore/identityeditviewmodel.cpp b/src/mvvmdatasynccore/identityeditviewmodel.cpp index 77abd08..ad1e98e 100644 --- a/src/mvvmdatasynccore/identityeditviewmodel.cpp +++ b/src/mvvmdatasynccore/identityeditviewmodel.cpp @@ -8,7 +8,7 @@ IdentityEditViewModel::IdentityEditViewModel(QObject *parent) : _manager(nullptr) {} -QVariantHash IdentityEditViewModel::params(AccountManager *manager) +QVariantHash IdentityEditViewModel::showParams(AccountManager *manager) { return { {QStringLiteral("manager"), QVariant::fromValue(manager)} diff --git a/src/mvvmdatasynccore/identityeditviewmodel_p.h b/src/mvvmdatasynccore/identityeditviewmodel_p.h index 036f399..72cd6ac 100644 --- a/src/mvvmdatasynccore/identityeditviewmodel_p.h +++ b/src/mvvmdatasynccore/identityeditviewmodel_p.h @@ -19,7 +19,7 @@ class Q_MVVMDATASYNCCORE_EXPORT IdentityEditViewModel : public ViewModel public: Q_INVOKABLE explicit IdentityEditViewModel(QObject *parent = nullptr); - static QVariantHash params(QtDataSync::AccountManager *manager); + static QVariantHash showParams(QtDataSync::AccountManager *manager); QString name() const; QString fingerPrint() const; @@ -34,7 +34,7 @@ Q_SIGNALS: void fingerPrintChanged(); protected: - void onInit(const QVariantHash ¶ms) override; + void onInit(const QVariantHash &showParams) override; private: QtDataSync::AccountManager *_manager; diff --git a/src/mvvmdatasynccore/mvvmdatasynccore.pro b/src/mvvmdatasynccore/mvvmdatasynccore.pro index a86fc1c..da26f21 100644 --- a/src/mvvmdatasynccore/mvvmdatasynccore.pro +++ b/src/mvvmdatasynccore/mvvmdatasynccore.pro @@ -10,14 +10,20 @@ HEADERS += \ accountmodel_p.h \ exportsetupviewmodel_p.h \ changeremoteviewmodel_p.h \ - identityeditviewmodel_p.h + identityeditviewmodel_p.h \ + networkexchangeviewmodel.h \ + networkexchangeviewmodel_p.h \ + exchangedevicesmodel.h \ + exchangedevicesmodel_p.h SOURCES += \ datasyncviewmodel.cpp \ accountmodel.cpp \ exportsetupviewmodel.cpp \ changeremoteviewmodel.cpp \ - identityeditviewmodel.cpp + identityeditviewmodel.cpp \ + networkexchangeviewmodel.cpp \ + exchangedevicesmodel.cpp TRANSLATIONS += \ translations/qtmvvmdatasynccore_de.ts \ diff --git a/src/mvvmdatasynccore/networkexchangeviewmodel.cpp b/src/mvvmdatasynccore/networkexchangeviewmodel.cpp new file mode 100644 index 0000000..2456db7 --- /dev/null +++ b/src/mvvmdatasynccore/networkexchangeviewmodel.cpp @@ -0,0 +1,225 @@ +#include "networkexchangeviewmodel.h" +#include "networkexchangeviewmodel_p.h" +#include "datasyncviewmodel.h" +#include "exportsetupviewmodel_p.h" + +#include +#include + +#undef logDebug +#undef logInfo +#undef logWarning +#undef logCritical +#include + +using namespace QtMvvm; +using namespace QtDataSync; + +const QString NetworkExchangeViewModel::paramSetup(QStringLiteral("setup")); +const QString NetworkExchangeViewModel::paramAccountManager(QStringLiteral("accountManager")); + +QVariantHash NetworkExchangeViewModel::showParams(const QString &setup) +{ + return { + {paramSetup, setup} + }; +} + +QVariantHash NetworkExchangeViewModel::showParams(AccountManager *accountManager) +{ + return { + {paramAccountManager, QVariant::fromValue(accountManager)} + }; +} + +NetworkExchangeViewModel::NetworkExchangeViewModel(QObject *parent) : + ViewModel(parent), + d(new NetworkExchangeViewModelPrivate(this)) +{} + +NetworkExchangeViewModel::~NetworkExchangeViewModel() {} + +quint16 NetworkExchangeViewModel::port() const +{ + return d->port; +} + +QString NetworkExchangeViewModel::deviceName() const +{ + return d->exchangeManager ? + d->exchangeManager->accountManager()->deviceName() : + QString(); +} + +bool NetworkExchangeViewModel::active() const +{ + return d->exchangeManager && d->exchangeManager->isActive(); +} + +ExchangeDevicesModel *NetworkExchangeViewModel::deviceModel() const +{ + return d->deviceModel; +} + +void NetworkExchangeViewModel::exportTo(int index) +{ + auto exCode = NetworkExchangeViewModelPrivate::ExportRequestCode; + while(d->activeExports.contains(exCode)) + exCode++; + auto info = d->deviceModel->infoAt(index); + d->activeExports.insert(exCode, info); + showForResult(exCode, + ExportSetupViewModel::showParams(tr("Export accont data to device \"%1\" with address \"%1\":") + .arg(info.name()) + .arg(ExchangeDevicesModel::fullAddress(info)))); +} + +void NetworkExchangeViewModel::setPort(quint16 port) +{ + if (d->port == port) + return; + + d->port = port; + emit portChanged(d->port); +} + +void NetworkExchangeViewModel::setDeviceName(QString deviceName) +{ + if (!d->exchangeManager || + this->deviceName() == deviceName) + return; + + d->exchangeManager->accountManager()->setDeviceName(deviceName); +} + +void NetworkExchangeViewModel::setActive(bool active) +{ + if(active != this->active()) { + if(active) + d->exchangeManager->startExchange(d->port); + else + d->exchangeManager->stopExchange(); + } +} + +void NetworkExchangeViewModel::onInit(const QVariantHash ¶ms) +{ + try { + if(params.contains(paramAccountManager)) { + auto accountManager = params.value(paramAccountManager).value(); + d->exchangeManager = new UserExchangeManager(accountManager, this); + } else { + auto setup = params.value(paramSetup, QtDataSync::DefaultSetup).toString(); + d->exchangeManager = new UserExchangeManager(setup, this); + } + + connect(d->exchangeManager->accountManager(), &AccountManager::deviceNameChanged, + this, &NetworkExchangeViewModel::deviceNameChanged); + connect(d->exchangeManager, &UserExchangeManager::userDataReceived, + this, &NetworkExchangeViewModel::newUserData); + connect(d->exchangeManager, &UserExchangeManager::exchangeError, + this, &NetworkExchangeViewModel::exchangeError); + connect(d->exchangeManager, &UserExchangeManager::activeChanged, + this, &NetworkExchangeViewModel::activeChanged); + + emit deviceNameChanged(deviceName()); + + d->deviceModel->setup(d->exchangeManager); + emit ready(); + } catch(SetupDoesNotExistException &e) { + logCritical() << "Failed to init DataSyncViewModel with error:" + << e.what(); + } +} + +void NetworkExchangeViewModel::onResult(quint32 requestCode, const QVariant &result) +{ + if(d->activeExports.contains(requestCode)) { + auto info = d->activeExports.take(requestCode); + if(result.isValid()) { + auto res = ExportSetupViewModel::result(result); + if(std::get<0>(res)) + d->exchangeManager->exportTrustedTo(info, std::get<1>(res), std::get<2>(res)); + else + d->exchangeManager->exportTo(info, std::get<1>(res)); + } + } +} + +void NetworkExchangeViewModel::exchangeError(const QString &errorString) +{ + critical(tr("Network exchange error"), errorString); +} + +void NetworkExchangeViewModel::newUserData(const UserInfo &userInfo, bool trusted) +{ + QPointer qPtr(this); + auto importDoneHandler = [this, qPtr](bool ok, QString error) { + if(!qPtr) + return; + if(ok) { + information(DataSyncViewModel::tr("Import completed"), + DataSyncViewModel::tr("Data was successfully imported.")); + } else + critical(DataSyncViewModel::tr("Import failed"), error); + }; + + if(trusted) { + MessageConfig config{MessageConfig::TypeInputDialog, QMetaType::typeName(QMetaType::QString)}; + config.setTitle(tr("Import account data")) + .setText(tr("Enter the password to decrypt the account data received from \"%1\" with address \"%2\". " + "Then choose whether you want to keep you local data or not:") + .arg(userInfo.name()) + .arg(ExchangeDevicesModel::fullAddress(userInfo))) + .setButtons(MessageConfig::YesToAll | MessageConfig::Yes | MessageConfig::Cancel) //TODO adjust to get ideal placement + .setButtonText(MessageConfig::YesToAll, tr("Reset data")) + .setButtonText(MessageConfig::Yes, tr("Keep data")) + .setViewProperties({ + {QStringLiteral("echoMode"), 2} //QLineEdit::Password + }); + auto res = CoreApp::showDialog(config); + connect(res, &MessageResult::dialogDone, this, [this, res, userInfo, importDoneHandler](MessageConfig::StandardButton btn) { + switch (btn) { + case MessageConfig::YesToAll: + d->exchangeManager->importTrustedFrom(userInfo, res->result().toString(), importDoneHandler, false); + break; + case MessageConfig::Yes: + d->exchangeManager->importTrustedFrom(userInfo, res->result().toString(), importDoneHandler, true); + break; + default: + break; + } + }); + } else { + MessageConfig config{MessageConfig::TypeMessageBox, MessageConfig::SubTypeQuestion}; + config.setTitle(tr("Import account data")) + .setText(tr("Do you want to import data received from \"%1\" with address \"%2\"? " + "Keep the local data after changing the account?") + .arg(userInfo.name()) + .arg(ExchangeDevicesModel::fullAddress(userInfo))) + .setButtons(MessageConfig::YesToAll | MessageConfig::Yes | MessageConfig::Cancel) //TODO adjust to get ideal placement + .setButtonText(MessageConfig::YesToAll, tr("Reset data")) + .setButtonText(MessageConfig::Yes, tr("Keep data")); + auto res = CoreApp::showDialog(config); + connect(res, &MessageResult::dialogDone, this, [this, userInfo, importDoneHandler](MessageConfig::StandardButton btn) { + switch (btn) { + case MessageConfig::YesToAll: + d->exchangeManager->importFrom(userInfo, importDoneHandler, false); + break; + case MessageConfig::Yes: + d->exchangeManager->importFrom(userInfo, importDoneHandler, true); + break; + default: + break; + } + }); + } +} + +// ------------- Private Implementation ------------- + +NetworkExchangeViewModelPrivate::NetworkExchangeViewModelPrivate(NetworkExchangeViewModel *q_ptr) : + exchangeManager(nullptr), + deviceModel(new ExchangeDevicesModel(q_ptr)), + port(UserExchangeManager::DataExchangePort) +{} diff --git a/src/mvvmdatasynccore/networkexchangeviewmodel.h b/src/mvvmdatasynccore/networkexchangeviewmodel.h new file mode 100644 index 0000000..880efba --- /dev/null +++ b/src/mvvmdatasynccore/networkexchangeviewmodel.h @@ -0,0 +1,69 @@ +#ifndef QTMVVM_NETWORKEXCHANGEVIEWMODEL_H +#define QTMVVM_NETWORKEXCHANGEVIEWMODEL_H + +#include + +#include + +#include + +#include "QtMvvmDataSyncCore/qtmvvmdatasynccore_global.h" +#include "QtMvvmDataSyncCore/exchangedevicesmodel.h" + +namespace QtMvvm { + +class NetworkExchangeViewModelPrivate; +class Q_MVVMDATASYNCCORE_EXPORT NetworkExchangeViewModel : public ViewModel +{ + Q_OBJECT + + Q_PROPERTY(quint16 port READ port WRITE setPort NOTIFY portChanged) + Q_PROPERTY(QString deviceName READ deviceName WRITE setDeviceName NOTIFY deviceNameChanged) + Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged) + + Q_PROPERTY(ExchangeDevicesModel* deviceModel READ deviceModel CONSTANT) + +public: + static const QString paramSetup; + static const QString paramAccountManager; + + static QVariantHash showParams(const QString &setup); + static QVariantHash showParams(QtDataSync::AccountManager *accountManager); + + Q_INVOKABLE explicit NetworkExchangeViewModel(QObject *parent = nullptr); + ~NetworkExchangeViewModel(); + + quint16 port() const; + QString deviceName() const; + bool active() const; + ExchangeDevicesModel* deviceModel() const; + +public Q_SLOTS: + void exportTo(int index); + + void setPort(quint16 port); + void setDeviceName(QString deviceName); + void setActive(bool active); + +Q_SIGNALS: + void ready(); + + void portChanged(quint16 port); + void deviceNameChanged(QString deviceName); + void activeChanged(bool active); + +protected: + void onInit(const QVariantHash ¶ms) override; + void onResult(quint32 requestCode, const QVariant &result) override; + +private Q_SLOTS: + void exchangeError(const QString &errorString); + void newUserData(const QtDataSync::UserInfo &userInfo, bool trusted); + +private: + QScopedPointer d; +}; + +} + +#endif // QTMVVM_NETWORKEXCHANGEVIEWMODEL_H diff --git a/src/mvvmdatasynccore/networkexchangeviewmodel_p.h b/src/mvvmdatasynccore/networkexchangeviewmodel_p.h new file mode 100644 index 0000000..1933d91 --- /dev/null +++ b/src/mvvmdatasynccore/networkexchangeviewmodel_p.h @@ -0,0 +1,24 @@ +#ifndef QTMVVM_NETWORKEXCHANGEVIEWMODEL_P_H +#define QTMVVM_NETWORKEXCHANGEVIEWMODEL_P_H + +#include "qtmvvmdatasynccore_global.h" +#include "networkexchangeviewmodel.h" + +namespace QtMvvm { + +class NetworkExchangeViewModelPrivate +{ +public: + static const quint32 ExportRequestCode = 0xb300; + + NetworkExchangeViewModelPrivate(NetworkExchangeViewModel *q_ptr); + + QtDataSync::UserExchangeManager *exchangeManager; + ExchangeDevicesModel *deviceModel; + quint16 port; + QHash activeExports; +}; + +} + +#endif // QTMVVM_NETWORKEXCHANGEVIEWMODEL_P_H diff --git a/src/mvvmdatasyncwidgets/exportsetupdialog.cpp b/src/mvvmdatasyncwidgets/exportsetupdialog.cpp index 52daaa9..9c9210c 100644 --- a/src/mvvmdatasyncwidgets/exportsetupdialog.cpp +++ b/src/mvvmdatasyncwidgets/exportsetupdialog.cpp @@ -17,6 +17,9 @@ ExportSetupDialog::ExportSetupDialog(ViewModel *viewModel, QWidget *parent) : setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint | Qt::WindowMinimizeButtonHint); } + bind(_viewModel, "label", + ui->titleLabel, "text", + Binding::OneWayToView); bind(_viewModel, "trusted", ui->trustedCheckBox, "checked"); bind(_viewModel, "includeServer", diff --git a/src/mvvmdatasyncwidgets/exportsetupdialog.ui b/src/mvvmdatasyncwidgets/exportsetupdialog.ui index 61ff306..d2952bb 100644 --- a/src/mvvmdatasyncwidgets/exportsetupdialog.ui +++ b/src/mvvmdatasyncwidgets/exportsetupdialog.ui @@ -7,7 +7,7 @@ 0 0 296 - 124 + 148 @@ -20,7 +20,7 @@ true - + &Trusted: @@ -30,10 +30,10 @@ - + - + Include &Server: @@ -43,10 +43,10 @@ - + - + false @@ -59,7 +59,7 @@ - + false @@ -72,7 +72,7 @@ - + Qt::Horizontal @@ -82,6 +82,9 @@ + + + diff --git a/src/mvvmdatasyncwidgets/mvvmdatasyncwidgets.pro b/src/mvvmdatasyncwidgets/mvvmdatasyncwidgets.pro index c5df4c8..5f1facd 100644 --- a/src/mvvmdatasyncwidgets/mvvmdatasyncwidgets.pro +++ b/src/mvvmdatasyncwidgets/mvvmdatasyncwidgets.pro @@ -8,14 +8,17 @@ HEADERS += \ datasyncwindow_p.h \ exportsetupdialog_p.h \ changeremotedialog_p.h \ - identityeditdialog_p.h + identityeditdialog_p.h \ + networkexchangewindow.h \ + networkexchangewindow_p.h SOURCES += \ datasyncwindow.cpp \ qtmvvmdatasyncwidgets_global.cpp \ exportsetupdialog.cpp \ changeremotedialog.cpp \ - identityeditdialog.cpp + identityeditdialog.cpp \ + networkexchangewindow.cpp TRANSLATIONS += \ translations/qtmvvmdatasyncwidgets_de.ts \ @@ -46,5 +49,6 @@ FORMS += \ datasyncwindow.ui \ exportsetupdialog.ui \ changeremotedialog.ui \ - identityeditdialog.ui + identityeditdialog.ui \ + networkexchangewindow.ui diff --git a/src/mvvmdatasyncwidgets/networkexchangewindow.cpp b/src/mvvmdatasyncwidgets/networkexchangewindow.cpp new file mode 100644 index 0000000..1b62140 --- /dev/null +++ b/src/mvvmdatasyncwidgets/networkexchangewindow.cpp @@ -0,0 +1,42 @@ +#include "networkexchangewindow.h" +#include "networkexchangewindow_p.h" +#include "ui_networkexchangewindow.h" +#include +using namespace QtMvvm; + +NetworkExchangeWindow::NetworkExchangeWindow(ViewModel *viewModel, QWidget *parent) : + QWidget(parent, Qt::Window), + d(new NetworkExchangeWindowPrivate(viewModel)) +{ + d->ui->setupUi(this); + + connect(d->ui->treeView, &QTreeView::activated, + this, &NetworkExchangeWindow::activated); + + bind(d->viewModel, "port", + d->ui->exchangePortSpinBox, "value"); + bind(d->viewModel, "deviceName", + d->ui->deviceNameLineEdit, "text", + Binding::TwoWay, + nullptr, "editingFinished()"); + bind(d->viewModel, "active", + d->ui->exchangeCheckBox, "checked", + Binding::OneWayToViewModel);//NOTE workaround because of buggy active property in datasync + + d->ui->treeView->setModel(d->viewModel->deviceModel()); +} + +NetworkExchangeWindow::~NetworkExchangeWindow() {} + +void NetworkExchangeWindow::activated(const QModelIndex &index) +{ + if(index.isValid()) + d->viewModel->exportTo(index.row()); +} + +// ------------- Private Implementation ------------- + +NetworkExchangeWindowPrivate::NetworkExchangeWindowPrivate(ViewModel *viewModel) : + viewModel(static_cast(viewModel)), + ui(new Ui::NetworkExchangeWindow()) +{} diff --git a/src/mvvmdatasyncwidgets/networkexchangewindow.h b/src/mvvmdatasyncwidgets/networkexchangewindow.h new file mode 100644 index 0000000..e369d81 --- /dev/null +++ b/src/mvvmdatasyncwidgets/networkexchangewindow.h @@ -0,0 +1,32 @@ +#ifndef QTMVVM_NETWORKEXCHANGEWINDOW_H +#define QTMVVM_NETWORKEXCHANGEWINDOW_H + +#include + +#include + +#include + +#include "QtMvvmDataSyncWidgets/qtmvvmdatasyncwidgets_global.h" + +namespace QtMvvm { + +class NetworkExchangeWindowPrivate; +class Q_MVVMDATASYNCWIDGETS_EXPORT NetworkExchangeWindow : public QWidget +{ + Q_OBJECT + +public: + Q_INVOKABLE explicit NetworkExchangeWindow(QtMvvm::ViewModel *viewModel, QWidget *parent = nullptr); + ~NetworkExchangeWindow(); + +private Q_SLOTS: + void activated(const QModelIndex &index); + +private: + QScopedPointer d; +}; + +} + +#endif // QTMVVM_NETWORKEXCHANGEWINDOW_H diff --git a/src/mvvmdatasyncwidgets/networkexchangewindow.ui b/src/mvvmdatasyncwidgets/networkexchangewindow.ui new file mode 100644 index 0000000..340a06e --- /dev/null +++ b/src/mvvmdatasyncwidgets/networkexchangewindow.ui @@ -0,0 +1,129 @@ + + + NetworkExchangeWindow + + + + 0 + 0 + 433 + 303 + + + + Form + + + + + + Exchange &Port: + + + exchangePortSpinBox + + + + + + + Random + + + true + + + QAbstractSpinBox::CorrectToNearestValue + + + true + + + 65535 + + + + + + + Device &Name: + + + deviceNameLineEdit + + + + + + + Name shown to other devices + + + + + + + Qt::Horizontal + + + + + + + &Exchange active: + + + + + + + false + + + QAbstractItemView::NoEditTriggers + + + false + + + true + + + false + + + false + + + true + + + true + + + false + + + + + + + + + exchangeCheckBox + toggled(bool) + treeView + setEnabled(bool) + + + 93 + 151 + + + 118 + 229 + + + + + diff --git a/src/mvvmdatasyncwidgets/networkexchangewindow_p.h b/src/mvvmdatasyncwidgets/networkexchangewindow_p.h new file mode 100644 index 0000000..d51842e --- /dev/null +++ b/src/mvvmdatasyncwidgets/networkexchangewindow_p.h @@ -0,0 +1,24 @@ +#ifndef QTMVVM_NETWORKEXCHANGEWINDOW_P_H +#define QTMVVM_NETWORKEXCHANGEWINDOW_P_H + +#include "qtmvvmdatasyncwidgets_global.h" +#include "networkexchangewindow.h" + +namespace Ui { +class NetworkExchangeWindow; +} + +namespace QtMvvm { + +class NetworkExchangeWindowPrivate +{ +public: + NetworkExchangeWindowPrivate(ViewModel *viewModel); + + NetworkExchangeViewModel *viewModel; + QScopedPointer ui; +}; + +} + +#endif // QTMVVM_NETWORKEXCHANGEWINDOW_P_H diff --git a/src/mvvmdatasyncwidgets/qtmvvmdatasyncwidgets_global.cpp b/src/mvvmdatasyncwidgets/qtmvvmdatasyncwidgets_global.cpp index 978d3b2..9c06291 100644 --- a/src/mvvmdatasyncwidgets/qtmvvmdatasyncwidgets_global.cpp +++ b/src/mvvmdatasyncwidgets/qtmvvmdatasyncwidgets_global.cpp @@ -2,6 +2,7 @@ #include #include "datasyncwindow.h" +#include "networkexchangewindow.h" #include "exportsetupdialog_p.h" #include "changeremotedialog_p.h" #include "identityeditdialog_p.h" @@ -9,6 +10,7 @@ void QtMvvm::registerDataSyncWidgets() { QtMvvm::WidgetsPresenter::registerView(); + QtMvvm::WidgetsPresenter::registerView(); QtMvvm::WidgetsPresenter::registerView(); QtMvvm::WidgetsPresenter::registerView(); QtMvvm::WidgetsPresenter::registerView();