24 changed files with 1286 additions and 50 deletions
@ -0,0 +1,244 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<!DOCTYPE TS> |
||||
|
<TS version="2.1" language="de_DE"> |
||||
|
<context> |
||||
|
<name>DrawerViewModel</name> |
||||
|
<message> |
||||
|
<location filename="drawerviewmodel.cpp" line="+11"/> |
||||
|
<source>Main Sample</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+1"/> |
||||
|
<source>Tab Sample</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+1"/> |
||||
|
<source>Settings</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
</context> |
||||
|
<context> |
||||
|
<name>SampleViewModel</name> |
||||
|
<message> |
||||
|
<location filename="sampleviewmodel.cpp" line="+81"/> |
||||
|
<source>Random input</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+1"/> |
||||
|
<source>Enter a number:</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+12"/> |
||||
|
<source>Open Files:</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+12"/> |
||||
|
<source>Clear Eventlist</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+1"/> |
||||
|
<source>Do you really want to clear the eventlist?</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+9"/> |
||||
|
<source>QtMvvm sample application</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+2"/> |
||||
|
<source>BSD 3 Clause</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
</context> |
||||
|
<context> |
||||
|
<name>TabItemViewModel</name> |
||||
|
<message> |
||||
|
<location filename="tabviewmodel.cpp" line="+28"/> |
||||
|
<source>No Title</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
</context> |
||||
|
<context> |
||||
|
<name>TabViewModel</name> |
||||
|
<message> |
||||
|
<location line="-13"/> |
||||
|
<source>New Tab</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+0"/> |
||||
|
<source>Enter a tab title:</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
</context> |
||||
|
<context> |
||||
|
<name>qtmvvm_settings_xml</name> |
||||
|
<message> |
||||
|
<location filename=".ts-dummy/settings.tsdummy.cpp" line="+4"/> |
||||
|
<source>property</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+1"/> |
||||
|
<source>Text 1</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+1"/> |
||||
|
<source>Value C</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+1"/> |
||||
|
<source>Value A</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+1"/> |
||||
|
<source>Another Section</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+1"/> |
||||
|
<source>Value B</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+1"/> |
||||
|
<source>Enter a nice name</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+1"/> |
||||
|
<source>Value B+C</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+1"/> |
||||
|
<source>Variant A</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+1"/> |
||||
|
<source>This is a tooltip</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+1"/> |
||||
|
<source>Variant C</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+1"/> |
||||
|
<source>Value A+B</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+1"/> |
||||
|
<source>Sub-Group</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+1"/> |
||||
|
<source>&Check me</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+1"/> |
||||
|
<source>Enter a &value</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+1"/> |
||||
|
<source>The value must be between 0 and 1</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+1"/> |
||||
|
<source>Open &system settings</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+1"/> |
||||
|
<source>Another main category</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+1"/> |
||||
|
<source>Value A+C</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+1"/> |
||||
|
<source>Variant B</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+1"/> |
||||
|
<source>Choose a &font</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+1"/> |
||||
|
<source>This is another section</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+1"/> |
||||
|
<source>bool</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+1"/> |
||||
|
<source>Select a &mode</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+1"/> |
||||
|
<source>I am a checkbox!</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+1"/> |
||||
|
<source>Value A+B+C</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+1"/> |
||||
|
<source>Enter a &number</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+1"/> |
||||
|
<source>You can use this to trigger whatever kind of action you need</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+1"/> |
||||
|
<source>Text 2</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+1"/> |
||||
|
<source>Enter a &website</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+1"/> |
||||
|
<source>Enter a &name</source> |
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
<message> |
||||
|
<location line="+1"/> |
||||
|
<source>https://example.org/test</source>
|
||||
|
<translation type="unfinished"></translation> |
||||
|
</message> |
||||
|
</context> |
||||
|
</TS> |
@ -0,0 +1,131 @@ |
|||||
|
#include "accountmodel.h" |
||||
|
#include "accountmodel_p.h" |
||||
|
|
||||
|
#include <QRemoteObjectReplica> |
||||
|
|
||||
|
using namespace QtMvvm; |
||||
|
using namespace QtDataSync; |
||||
|
|
||||
|
AccountModel::AccountModel(QObject *parent) : |
||||
|
QAbstractListModel(parent), |
||||
|
d(new AccountModelPrivate()) |
||||
|
{} |
||||
|
|
||||
|
AccountModel::~AccountModel() {} |
||||
|
|
||||
|
void AccountModel::setup(AccountManager *manager) |
||||
|
{ |
||||
|
beginResetModel(); |
||||
|
d->devices.clear(); |
||||
|
if(d->manager) |
||||
|
d->manager->disconnect(this); |
||||
|
d->manager = manager; |
||||
|
endResetModel(); |
||||
|
|
||||
|
connect(d->manager, &AccountManager::accountDevices, |
||||
|
this, &AccountModel::accountDevices); |
||||
|
connect(d->manager, &AccountManager::importAccepted, |
||||
|
this, &AccountModel::reload); |
||||
|
connect(d->manager, &AccountManager::accountAccessGranted, |
||||
|
this, &AccountModel::reload); |
||||
|
|
||||
|
if(d->manager->replica()->isInitialized()) |
||||
|
d->manager->listDevices(); |
||||
|
else { |
||||
|
connect(d->manager->replica(), &QRemoteObjectReplica::initialized, |
||||
|
d->manager, &AccountManager::listDevices); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
QVariant AccountModel::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 FingerPrintRole: |
||||
|
return tr("Fingerprint"); |
||||
|
default: |
||||
|
break; |
||||
|
} |
||||
|
break; |
||||
|
case 1: |
||||
|
if(role == Qt::DisplayRole) |
||||
|
return tr("Fingerprint"); |
||||
|
break; |
||||
|
default: |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
return {}; |
||||
|
} |
||||
|
|
||||
|
int AccountModel::rowCount(const QModelIndex &parent) const |
||||
|
{ |
||||
|
if (parent.isValid()) |
||||
|
return 0; |
||||
|
else |
||||
|
return d->devices.size(); |
||||
|
} |
||||
|
|
||||
|
QVariant AccountModel::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 FingerPrintRole: |
||||
|
return d->devices.value(index.row()).fingerprint(); |
||||
|
default: |
||||
|
break; |
||||
|
} |
||||
|
break; |
||||
|
case 1: |
||||
|
if(role == Qt::DisplayRole) |
||||
|
return d->devices.value(index.row()).fingerprint(); |
||||
|
break; |
||||
|
default: |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
return {}; |
||||
|
} |
||||
|
|
||||
|
bool AccountModel::removeDevice(const QModelIndex &index) |
||||
|
{ |
||||
|
if (!index.isValid()) |
||||
|
return false; |
||||
|
else { |
||||
|
d->manager->removeDevice(d->devices.value(index.row())); |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void AccountModel::reload() |
||||
|
{ |
||||
|
if(d->manager) |
||||
|
d->manager->listDevices(); |
||||
|
} |
||||
|
|
||||
|
void AccountModel::accountDevices(const QList<DeviceInfo> &devices) |
||||
|
{ |
||||
|
beginResetModel(); |
||||
|
d->devices = devices; |
||||
|
endResetModel(); |
||||
|
} |
||||
|
|
||||
|
// ------------- Private Implementation -------------
|
||||
|
|
||||
|
AccountModelPrivate::AccountModelPrivate() : |
||||
|
manager(nullptr), |
||||
|
devices() |
||||
|
{} |
@ -0,0 +1,51 @@ |
|||||
|
#ifndef QTMVVM_ACCOUNTMODEL_H |
||||
|
#define QTMVVM_ACCOUNTMODEL_H |
||||
|
|
||||
|
#include <QtCore/qabstractitemmodel.h> |
||||
|
#include <QtCore/qscopedpointer.h> |
||||
|
|
||||
|
#include <QtDataSync/accountmanager.h> |
||||
|
|
||||
|
#include "QtMvvmDataSyncCore/qtmvvmdatasynccore_global.h" |
||||
|
|
||||
|
namespace QtMvvm { |
||||
|
|
||||
|
class AccountModelPrivate; |
||||
|
class Q_MVVMDATASYNCCORE_EXPORT AccountModel : public QAbstractListModel |
||||
|
{ |
||||
|
Q_OBJECT |
||||
|
|
||||
|
public: |
||||
|
enum Roles { |
||||
|
NameRole = Qt::DisplayRole, |
||||
|
FingerPrintRole = Qt::UserRole + 1 |
||||
|
}; |
||||
|
Q_ENUM(Roles) |
||||
|
|
||||
|
explicit AccountModel(QObject *parent = nullptr); |
||||
|
~AccountModel(); |
||||
|
|
||||
|
Q_INVOKABLE void setup(QtDataSync::AccountManager *manager); |
||||
|
|
||||
|
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; |
||||
|
int rowCount(const QModelIndex &parent = QModelIndex()) const override; |
||||
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; |
||||
|
|
||||
|
Q_INVOKABLE bool removeDevice(const QModelIndex &index); |
||||
|
Q_INVOKABLE inline bool removeDevice(int row) { |
||||
|
return removeDevice(index(row)); |
||||
|
} |
||||
|
|
||||
|
public Q_SLOTS: |
||||
|
void reload(); |
||||
|
|
||||
|
private Q_SLOTS: |
||||
|
void accountDevices(const QList<QtDataSync::DeviceInfo> &devices); |
||||
|
|
||||
|
private: |
||||
|
QScopedPointer<AccountModelPrivate> d; |
||||
|
}; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
#endif // QTMVVM_ACCOUNTMODEL_H
|
@ -0,0 +1,20 @@ |
|||||
|
#ifndef QTMVVM_ACCOUNTMODEL_P_H |
||||
|
#define QTMVVM_ACCOUNTMODEL_P_H |
||||
|
|
||||
|
#include "qtmvvmdatasynccore_global.h" |
||||
|
#include "accountmodel.h" |
||||
|
|
||||
|
namespace QtMvvm { |
||||
|
|
||||
|
class AccountModelPrivate |
||||
|
{ |
||||
|
public: |
||||
|
AccountModelPrivate(); |
||||
|
|
||||
|
QtDataSync::AccountManager *manager; |
||||
|
QList<QtDataSync::DeviceInfo> devices; |
||||
|
}; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
#endif // QTMVVM_ACCOUNTMODEL_P_H
|
@ -0,0 +1,11 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info"> |
||||
|
<mime-type type="application/x-datasync-account-data"> |
||||
|
<comment>Account data of a datasync account as file export</comment> |
||||
|
<comment xml:lang="en">Account data of a datasync account as file export</comment> |
||||
|
<comment xml:lang="de">Account-Daten eines Datasync-Accounts als Dateiexport</comment> |
||||
|
<icon name="x-datasync-account-data"/> |
||||
|
<glob-deleteall/> |
||||
|
<glob pattern="*.dsad"/> |
||||
|
</mime-type> |
||||
|
</mime-info> |
@ -0,0 +1,422 @@ |
|||||
|
#include "datasyncviewmodel.h" |
||||
|
#include "datasyncviewmodel_p.h" |
||||
|
#include "exportsetupviewmodel_p.h" |
||||
|
|
||||
|
#include <QtCore/QStandardPaths> |
||||
|
#include <QtCore/QFile> |
||||
|
|
||||
|
#include <QtRemoteObjects/QRemoteObjectNode> |
||||
|
|
||||
|
#include <QtMvvmCore/CoreApp> |
||||
|
#include <QtMvvmCore/Messages> |
||||
|
|
||||
|
#include <QtDataSync/SetupDoesNotExistException> |
||||
|
|
||||
|
#undef logDebug |
||||
|
#undef logInfo |
||||
|
#undef logWarning |
||||
|
#undef logCritical |
||||
|
#include <QtMvvmCore/private/qtmvvm_logging_p.h> |
||||
|
|
||||
|
using namespace QtMvvm; |
||||
|
using namespace QtDataSync; |
||||
|
|
||||
|
const QString DataSyncViewModel::paramSetup(QStringLiteral("setup")); |
||||
|
const QString DataSyncViewModel::paramReplicaNode(QStringLiteral("node")); |
||||
|
|
||||
|
QVariantHash DataSyncViewModel::showParams(const QString &setup) |
||||
|
{ |
||||
|
return { |
||||
|
{paramSetup, setup} |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
QVariantHash DataSyncViewModel::showParams(QRemoteObjectNode *node) |
||||
|
{ |
||||
|
return { |
||||
|
{paramReplicaNode, QVariant::fromValue(node)} |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
DataSyncViewModel::DataSyncViewModel(QObject *parent) : |
||||
|
ViewModel(parent), |
||||
|
d(new DataSyncViewModelPrivate(this)) |
||||
|
{ |
||||
|
resetColorMap(); |
||||
|
} |
||||
|
|
||||
|
DataSyncViewModel::~DataSyncViewModel() {} |
||||
|
|
||||
|
SyncManager *DataSyncViewModel::syncManager() const |
||||
|
{ |
||||
|
return d->syncManager; |
||||
|
} |
||||
|
|
||||
|
AccountManager *DataSyncViewModel::accountManager() const |
||||
|
{ |
||||
|
return d->accountManager; |
||||
|
} |
||||
|
|
||||
|
DataSyncViewModel::ColorMap DataSyncViewModel::colorMap() const |
||||
|
{ |
||||
|
return d->colorMap; |
||||
|
} |
||||
|
|
||||
|
QString DataSyncViewModel::statusString() const |
||||
|
{ |
||||
|
if(!d->syncManager) |
||||
|
return {}; |
||||
|
auto state = d->syncManager->syncState(); |
||||
|
|
||||
|
QString baseText = QStringLiteral("<font color=\"%1\">%2</font>") |
||||
|
.arg(d->colorMap.value(state).name()); |
||||
|
switch (state) { |
||||
|
case SyncManager::Initializing: |
||||
|
return baseText.arg(tr("Connecting…")); |
||||
|
case SyncManager::Downloading: |
||||
|
return baseText.arg(tr("Downloading…")); |
||||
|
case SyncManager::Uploading: |
||||
|
return baseText.arg(tr("Uploading…")); |
||||
|
case SyncManager::Synchronized: |
||||
|
return baseText.arg(tr("Synchronized")); |
||||
|
case SyncManager::Error: |
||||
|
return baseText.arg(tr("Error!")); |
||||
|
case SyncManager::Disconnected: |
||||
|
return baseText.arg(tr("Disconnected")); |
||||
|
default: |
||||
|
Q_UNREACHABLE(); |
||||
|
return QString(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
AccountModel *DataSyncViewModel::accountModel() const |
||||
|
{ |
||||
|
return d->accountModel; |
||||
|
} |
||||
|
|
||||
|
QString DataSyncViewModel::formatFingerPrint(const QByteArray &fingerPrint) |
||||
|
{ |
||||
|
QByteArrayList res; |
||||
|
for(char c : fingerPrint) |
||||
|
res.append(QByteArray(1, c).toHex().toUpper()); |
||||
|
return QString::fromUtf8(res.join(':')); |
||||
|
} |
||||
|
|
||||
|
void DataSyncViewModel::showDeviceInfo() |
||||
|
{ |
||||
|
Q_UNIMPLEMENTED(); |
||||
|
} |
||||
|
|
||||
|
void DataSyncViewModel::startExport() |
||||
|
{ |
||||
|
showForResult<ExportSetupViewModel>(DataSyncViewModelPrivate::ExportRequestCode); |
||||
|
} |
||||
|
|
||||
|
void DataSyncViewModel::startImport() |
||||
|
{ |
||||
|
auto home = QStandardPaths::writableLocation(QStandardPaths::HomeLocation); |
||||
|
getOpenFile(this, [this](QUrl url) { |
||||
|
if(url.isValid()) { |
||||
|
QSharedPointer<QIODevice> device; |
||||
|
//TODO add support for android content device
|
||||
|
if(url.isLocalFile()) |
||||
|
device.reset(new QFile(url.toLocalFile())); |
||||
|
else { |
||||
|
critical(tr("Import failed"), tr("Unsupported URL Scheme: %1").arg(url.scheme())); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if(!device->open(QIODevice::ReadOnly | QIODevice::Text)) { |
||||
|
critical(tr("Import failed"), |
||||
|
tr("Failed to open URL \"%1\" with error: %1") |
||||
|
.arg(url.toString()) |
||||
|
.arg(device->errorString())); |
||||
|
return; |
||||
|
} |
||||
|
auto data = device->readAll(); |
||||
|
device->close(); |
||||
|
|
||||
|
if(AccountManager::isTrustedImport(data)) { |
||||
|
MessageConfig config{MessageConfig::TypeInputDialog, QMetaType::typeName(QMetaType::QString)}; |
||||
|
config.setTitle(tr("Import account data")) |
||||
|
.setText(tr("Enter the password to decrypt the account data. " |
||||
|
"Then choose whether you want to keep you local data or not:")) |
||||
|
.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, data](MessageConfig::StandardButton btn) { |
||||
|
switch (btn) { |
||||
|
case MessageConfig::YesToAll: |
||||
|
d->performImport(true, res->result().toString(), data, false); |
||||
|
break; |
||||
|
case MessageConfig::Yes: |
||||
|
d->performImport(true, res->result().toString(), data, true); |
||||
|
break; |
||||
|
default: |
||||
|
break; |
||||
|
} |
||||
|
}); |
||||
|
} else { |
||||
|
MessageConfig config{MessageConfig::TypeMessageBox, MessageConfig::SubTypeQuestion}; |
||||
|
config.setTitle(tr("Import account data")) |
||||
|
.setText(tr("Keep the local data after changing the account?")) |
||||
|
.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, res, data](MessageConfig::StandardButton btn) { |
||||
|
switch (btn) { |
||||
|
case MessageConfig::YesToAll: |
||||
|
d->performImport(false, {}, data, false); |
||||
|
break; |
||||
|
case MessageConfig::Yes: |
||||
|
d->performImport(false, {}, data, true); |
||||
|
break; |
||||
|
default: |
||||
|
break; |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
}, tr("Import account data"), |
||||
|
{QStringLiteral("application/x-datasync-account-data"), QStringLiteral("application/octet-stream")}, |
||||
|
QUrl::fromLocalFile(home)); |
||||
|
} |
||||
|
|
||||
|
void DataSyncViewModel::performReset() |
||||
|
{ |
||||
|
MessageConfig config {MessageConfig::TypeMessageBox, MessageConfig::SubTypeQuestion}; |
||||
|
config.setTitle(tr("Reset Account?")) |
||||
|
.setText(tr("Do you want to reset your account? " |
||||
|
"You will loose the connection to all other devices and get a new identity." |
||||
|
"You can either keep your data or reset it as well." |
||||
|
"This cannot be undone!")) |
||||
|
.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](MessageConfig::StandardButton btn) { |
||||
|
switch (btn) { |
||||
|
case MessageConfig::YesToAll: |
||||
|
d->accountManager->resetAccount(false); |
||||
|
break; |
||||
|
case MessageConfig::Yes: |
||||
|
d->accountManager->resetAccount(true); |
||||
|
break; |
||||
|
default: |
||||
|
break; |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
void DataSyncViewModel::changeRemote() |
||||
|
{ |
||||
|
Q_UNIMPLEMENTED(); |
||||
|
} |
||||
|
|
||||
|
void DataSyncViewModel::startNetworkExchange() |
||||
|
{ |
||||
|
Q_UNIMPLEMENTED(); |
||||
|
} |
||||
|
|
||||
|
void DataSyncViewModel::setColorMap(DataSyncViewModel::ColorMap colorMap) |
||||
|
{ |
||||
|
if (d->colorMap == colorMap) |
||||
|
return; |
||||
|
|
||||
|
d->colorMap = colorMap; |
||||
|
emit colorMapChanged(d->colorMap); |
||||
|
} |
||||
|
|
||||
|
void DataSyncViewModel::resetColorMap() |
||||
|
{ |
||||
|
d->colorMap.clear(); |
||||
|
d->colorMap.insert(SyncManager::Initializing, Qt::darkCyan); |
||||
|
d->colorMap.insert(SyncManager::Downloading, Qt::darkCyan); |
||||
|
d->colorMap.insert(SyncManager::Uploading, Qt::darkCyan); |
||||
|
d->colorMap.insert(SyncManager::Synchronized, Qt::darkGreen); |
||||
|
d->colorMap.insert(SyncManager::Error, Qt::darkRed); |
||||
|
d->colorMap.insert(SyncManager::Disconnected, Qt::darkYellow); |
||||
|
emit colorMapChanged(d->colorMap); |
||||
|
} |
||||
|
|
||||
|
void DataSyncViewModel::showImportDialog(LoginRequest request) |
||||
|
{ |
||||
|
if(request.handled()) |
||||
|
return; |
||||
|
question(tr("Login requested!"), |
||||
|
tr("<p>A device wants to log into your account:</p>" |
||||
|
"<p>Name: %1<br/>" |
||||
|
"Fingerprint: %2</p>" |
||||
|
"<p>Do you want accept the request?</p>") |
||||
|
.arg(request.device().name()) |
||||
|
.arg(formatFingerPrint(request.device().fingerprint())), |
||||
|
this, [this, request](bool ok) { |
||||
|
auto req = request; |
||||
|
if(!req.handled()) { |
||||
|
if(ok) |
||||
|
req.accept(); |
||||
|
else |
||||
|
req.reject(); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
void DataSyncViewModel::showImportAccepted() |
||||
|
{ |
||||
|
information(tr("Import accepted"), |
||||
|
tr("The partner has accepted the import. You are now logged in.")); |
||||
|
} |
||||
|
|
||||
|
void DataSyncViewModel::showAccessGranted(const QUuid &id) |
||||
|
{ |
||||
|
d->pendingGrants.insert(id); |
||||
|
//no need to call list devices, is done by the model
|
||||
|
} |
||||
|
|
||||
|
void DataSyncViewModel::triggerGranted(const QList<DeviceInfo> &devices) |
||||
|
{ |
||||
|
for(auto device : devices) { |
||||
|
if(d->pendingGrants.remove(device.deviceId())) { |
||||
|
information(tr("Account access granted"), |
||||
|
tr("<p>Account access has been granted to device:</p>" |
||||
|
"<p>Name: %1<br/>" |
||||
|
"Fingerprint: %2</p>") |
||||
|
.arg(device.name()) |
||||
|
.arg(formatFingerPrint(device.fingerprint()))); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void DataSyncViewModel::onInit(const QVariantHash ¶ms) |
||||
|
{ |
||||
|
try { |
||||
|
if(params.contains(paramReplicaNode)) { |
||||
|
auto node = params.value(paramReplicaNode).value<QRemoteObjectNode*>(); |
||||
|
d->syncManager = new SyncManager(node, this); |
||||
|
d->accountManager = new AccountManager(node, this); |
||||
|
} else { |
||||
|
auto setup = params.value(paramSetup, QtDataSync::DefaultSetup).toString(); |
||||
|
d->syncManager = new SyncManager(setup, this); |
||||
|
d->accountManager = new AccountManager(setup, this); |
||||
|
} |
||||
|
|
||||
|
//sync manager
|
||||
|
connect(d->syncManager, &SyncManager::syncStateChanged, |
||||
|
this, &DataSyncViewModel::statusStringChanged); |
||||
|
connect(d->syncManager, &SyncManager::lastErrorChanged, |
||||
|
this, &DataSyncViewModel::statusStringChanged); |
||||
|
|
||||
|
//account manager
|
||||
|
connect(d->accountManager, &AccountManager::loginRequested, |
||||
|
this, &DataSyncViewModel::showImportDialog); |
||||
|
connect(d->accountManager, &AccountManager::importAccepted, |
||||
|
this, &DataSyncViewModel::showImportAccepted); |
||||
|
connect(d->accountManager, &AccountManager::accountAccessGranted, |
||||
|
this, &DataSyncViewModel::showAccessGranted); |
||||
|
connect(d->accountManager, &AccountManager::accountDevices, |
||||
|
this, &DataSyncViewModel::triggerGranted); |
||||
|
d->accountModel->setup(d->accountManager); |
||||
|
|
||||
|
emit syncManagerChanged(d->syncManager); |
||||
|
emit accountManagerChanged(d->accountManager); |
||||
|
} catch(SetupDoesNotExistException &e) { |
||||
|
logCritical() << "Failed to init DataSyncViewModel with error:" |
||||
|
<< e.what(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void DataSyncViewModel::onResult(quint32 requestCode, const QVariant &result) |
||||
|
{ |
||||
|
switch (requestCode) { |
||||
|
case DataSyncViewModelPrivate::ExportRequestCode: |
||||
|
if(result.isValid()) { |
||||
|
auto res = ExportSetupViewModel::result(result); |
||||
|
d->performExport(std::get<0>(res), std::get<1>(res), std::get<2>(res)); |
||||
|
} |
||||
|
break; |
||||
|
default: |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// ------------- Private Implementation -------------
|
||||
|
|
||||
|
QtMvvm::DataSyncViewModelPrivate::DataSyncViewModelPrivate(DataSyncViewModel *q_ptr) : |
||||
|
q(q_ptr), |
||||
|
syncManager(nullptr), |
||||
|
accountManager(nullptr), |
||||
|
colorMap(), |
||||
|
accountModel(new AccountModel(q_ptr)) |
||||
|
{} |
||||
|
|
||||
|
void DataSyncViewModelPrivate::performExport(bool trusted, bool includeServer, const QString &password) |
||||
|
{ |
||||
|
auto home = QStandardPaths::writableLocation(QStandardPaths::HomeLocation); |
||||
|
getSaveFile(q, [this, trusted, includeServer, password](QUrl url) { |
||||
|
if(url.isValid()) { |
||||
|
QSharedPointer<QIODevice> device; |
||||
|
//TODO add support for android content device
|
||||
|
if(url.isLocalFile()) |
||||
|
device.reset(new QFile(url.toLocalFile())); |
||||
|
else { |
||||
|
critical(DataSyncViewModel::tr("Export failed"), |
||||
|
DataSyncViewModel::tr("Unsupported URL Scheme: %1").arg(url.scheme())); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if(!device->open(QIODevice::WriteOnly | QIODevice::Text)) { |
||||
|
critical(DataSyncViewModel::tr("Export failed"), |
||||
|
DataSyncViewModel::tr("Failed to open URL \"%1\" with error: %1") |
||||
|
.arg(url.toString()) |
||||
|
.arg(device->errorString())); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
QPointer<DataSyncViewModel> qPtr(q); |
||||
|
auto resFn = [this, qPtr, device](QByteArray data) { |
||||
|
if(!qPtr) |
||||
|
return; |
||||
|
device->write(data); |
||||
|
device->close(); |
||||
|
information(DataSyncViewModel::tr("Export completed"), |
||||
|
DataSyncViewModel::tr("Data was successfully exported.")); |
||||
|
}; |
||||
|
auto errFn = [this, qPtr, device](QString error){ |
||||
|
if(!qPtr) |
||||
|
return; |
||||
|
critical(DataSyncViewModel::tr("Export failed"), error); |
||||
|
}; |
||||
|
|
||||
|
if(trusted) |
||||
|
accountManager->exportAccountTrusted(includeServer, password, resFn, errFn); |
||||
|
else |
||||
|
accountManager->exportAccount(includeServer, resFn, errFn); |
||||
|
} |
||||
|
}, DataSyncViewModel::tr("Export account data"), |
||||
|
{QStringLiteral("application/x-datasync-account-data"), QStringLiteral("application/octet-stream")}, |
||||
|
QUrl::fromLocalFile(home)); |
||||
|
} |
||||
|
|
||||
|
void DataSyncViewModelPrivate::performImport(bool trusted, const QString &password, const QByteArray &data, bool keepData) |
||||
|
{ |
||||
|
QPointer<DataSyncViewModel> qPtr(q); |
||||
|
auto resFn = [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) |
||||
|
accountManager->importAccountTrusted(data, password, resFn, keepData); |
||||
|
else |
||||
|
accountManager->importAccount(data, resFn, keepData); |
||||
|
} |
@ -0,0 +1,86 @@ |
|||||
|
#ifndef QTMVVM_DATASYNCVIEWMODEL_H |
||||
|
#define QTMVVM_DATASYNCVIEWMODEL_H |
||||
|
|
||||
|
#include <QtCore/qmap.h> |
||||
|
#include <QtCore/qscopedpointer.h> |
||||
|
|
||||
|
#include <QtGui/qcolor.h> |
||||
|
|
||||
|
#include <QtMvvmCore/viewmodel.h> |
||||
|
|
||||
|
#include <QtDataSync/syncmanager.h> |
||||
|
#include <QtDataSync/accountmanager.h> |
||||
|
|
||||
|
#include "QtMvvmDataSyncCore/qtmvvmdatasynccore_global.h" |
||||
|
#include "QtMvvmDataSyncCore/accountmodel.h" |
||||
|
|
||||
|
namespace QtMvvm { |
||||
|
|
||||
|
class DataSyncViewModelPrivate; |
||||
|
class Q_MVVMDATASYNCCORE_EXPORT DataSyncViewModel : public ViewModel |
||||
|
{ |
||||
|
Q_OBJECT |
||||
|
|
||||
|
Q_PROPERTY(QtDataSync::SyncManager* syncManager READ syncManager NOTIFY syncManagerChanged) |
||||
|
Q_PROPERTY(QtDataSync::AccountManager* accountManager READ accountManager NOTIFY accountManagerChanged) |
||||
|
|
||||
|
Q_PROPERTY(ColorMap colorMap READ colorMap WRITE setColorMap RESET resetColorMap NOTIFY colorMapChanged) |
||||
|
Q_PROPERTY(QString statusString READ statusString NOTIFY statusStringChanged) |
||||
|
|
||||
|
Q_PROPERTY(QtMvvm::AccountModel* accountModel READ accountModel CONSTANT) |
||||
|
|
||||
|
public: |
||||
|
typedef QMap<QtDataSync::SyncManager::SyncState, QColor> ColorMap; |
||||
|
|
||||
|
static const QString paramSetup; |
||||
|
static const QString paramReplicaNode; |
||||
|
|
||||
|
static QVariantHash showParams(const QString &setup); |
||||
|
static QVariantHash showParams(QRemoteObjectNode *node); |
||||
|
|
||||
|
Q_INVOKABLE explicit DataSyncViewModel(QObject *parent = nullptr); |
||||
|
~DataSyncViewModel(); |
||||
|
|
||||
|
QtDataSync::SyncManager* syncManager() const; |
||||
|
QtDataSync::AccountManager* accountManager() const; |
||||
|
ColorMap colorMap() const; |
||||
|
QString statusString() const; |
||||
|
|
||||
|
AccountModel *accountModel() const; |
||||
|
|
||||
|
Q_INVOKABLE static QString formatFingerPrint(const QByteArray &fingerPrint); |
||||
|
|
||||
|
public Q_SLOTS: |
||||
|
void showDeviceInfo(); |
||||
|
void startExport(); |
||||
|
void startImport(); |
||||
|
void performReset(); |
||||
|
void changeRemote(); |
||||
|
void startNetworkExchange(); |
||||
|
|
||||
|
void setColorMap(ColorMap colorMap); |
||||
|
void resetColorMap(); |
||||
|
|
||||
|
private Q_SLOTS: |
||||
|
void showImportDialog(QtDataSync::LoginRequest request); |
||||
|
void showImportAccepted(); |
||||
|
void showAccessGranted(const QUuid &id); |
||||
|
void triggerGranted(const QList<QtDataSync::DeviceInfo> &devices); |
||||
|
|
||||
|
Q_SIGNALS: |
||||
|
void syncManagerChanged(QtDataSync::SyncManager* syncManager); |
||||
|
void accountManagerChanged(QtDataSync::AccountManager* accountManager); |
||||
|
void colorMapChanged(ColorMap colorMap); |
||||
|
void statusStringChanged(); |
||||
|
|
||||
|
protected: |
||||
|
void onInit(const QVariantHash ¶ms) override; |
||||
|
void onResult(quint32 requestCode, const QVariant &result) override; |
||||
|
|
||||
|
private: |
||||
|
QScopedPointer<DataSyncViewModelPrivate> d; |
||||
|
}; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
#endif // QTMVVM_DATASYNCVIEWMODEL_H
|
@ -0,0 +1,32 @@ |
|||||
|
#ifndef QTMVVM_DATASYNCVIEWMODEL_P_H |
||||
|
#define QTMVVM_DATASYNCVIEWMODEL_P_H |
||||
|
|
||||
|
#include <QtCore/QSet> |
||||
|
|
||||
|
#include "qtmvvmdatasynccore_global.h" |
||||
|
#include "datasyncviewmodel.h" |
||||
|
|
||||
|
namespace QtMvvm { |
||||
|
|
||||
|
class DataSyncViewModelPrivate |
||||
|
{ |
||||
|
public: |
||||
|
static const quint32 ExportRequestCode = 0xb201; |
||||
|
|
||||
|
DataSyncViewModelPrivate(DataSyncViewModel *q_ptr); |
||||
|
|
||||
|
DataSyncViewModel *q; |
||||
|
QtDataSync::SyncManager *syncManager; |
||||
|
QtDataSync::AccountManager *accountManager; |
||||
|
DataSyncViewModel::ColorMap colorMap; |
||||
|
AccountModel *accountModel; |
||||
|
|
||||
|
QSet<QUuid> pendingGrants; |
||||
|
|
||||
|
void performExport(bool trusted, bool includeServer, const QString &password); |
||||
|
void performImport(bool trusted, const QString &password, const QByteArray &data, bool keepData); |
||||
|
}; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
#endif // QTMVVM_DATASYNCVIEWMODEL_P_H
|
@ -0,0 +1,82 @@ |
|||||
|
#include "exportsetupviewmodel_p.h" |
||||
|
using namespace QtMvvm; |
||||
|
|
||||
|
std::tuple<bool, bool, QString> ExportSetupViewModel::result(const QVariant &data) |
||||
|
{ |
||||
|
auto map = data.toHash(); |
||||
|
return std::make_tuple(map.value(QStringLiteral("trusted")).toBool(), |
||||
|
map.value(QStringLiteral("includeServer")).toBool(), |
||||
|
map.value(QStringLiteral("password")).toString()); |
||||
|
} |
||||
|
|
||||
|
ExportSetupViewModel::ExportSetupViewModel(QObject *parent) : |
||||
|
ViewModel(parent), |
||||
|
_trusted(false), |
||||
|
_includeServer(false), |
||||
|
_password() |
||||
|
{ |
||||
|
connect(this, &ExportSetupViewModel::trustedChanged, |
||||
|
this, &ExportSetupViewModel::validChanged); |
||||
|
connect(this, &ExportSetupViewModel::passwordChanged, |
||||
|
this, &ExportSetupViewModel::validChanged); |
||||
|
} |
||||
|
|
||||
|
bool ExportSetupViewModel::trusted() const |
||||
|
{ |
||||
|
return _trusted; |
||||
|
} |
||||
|
|
||||
|
bool ExportSetupViewModel::includeServer() const |
||||
|
{ |
||||
|
return _includeServer; |
||||
|
} |
||||
|
|
||||
|
QString ExportSetupViewModel::password() const |
||||
|
{ |
||||
|
return _password; |
||||
|
} |
||||
|
|
||||
|
bool ExportSetupViewModel::isValid() const |
||||
|
{ |
||||
|
return !_trusted || !_password.isEmpty(); |
||||
|
} |
||||
|
|
||||
|
bool ExportSetupViewModel::completeSetup() |
||||
|
{ |
||||
|
if(!isValid()) |
||||
|
return false; |
||||
|
|
||||
|
QVariantHash hash; |
||||
|
hash[QStringLiteral("trusted")] = _trusted; |
||||
|
hash[QStringLiteral("includeServer")] = _includeServer; |
||||
|
hash[QStringLiteral("password")] = _trusted ? _password : QString(); |
||||
|
emit resultReady(hash); |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
void ExportSetupViewModel::setTrusted(bool trusted) |
||||
|
{ |
||||
|
if (_trusted == trusted) |
||||
|
return; |
||||
|
|
||||
|
_trusted = trusted; |
||||
|
emit trustedChanged(_trusted); |
||||
|
} |
||||
|
|
||||
|
void ExportSetupViewModel::setIncludeServer(bool includeServer) |
||||
|
{ |
||||
|
if (_includeServer == includeServer) |
||||
|
return; |
||||
|
|
||||
|
_includeServer = includeServer; |
||||
|
emit includeServerChanged(_includeServer); |
||||
|
} |
||||
|
|
||||
|
void ExportSetupViewModel::setPassword(QString password) |
||||
|
{ |
||||
|
if (_password == password) |
||||
|
return; |
||||
|
|
||||
|
_password = password; |
||||
|
emit passwordChanged(_password); |
||||
|
} |
@ -0,0 +1,53 @@ |
|||||
|
#ifndef QTMVVM_EXPORTSETUPVIEWMODEL_P_H |
||||
|
#define QTMVVM_EXPORTSETUPVIEWMODEL_P_H |
||||
|
|
||||
|
#include <tuple> |
||||
|
|
||||
|
#include <QtMvvmCore/ViewModel> |
||||
|
|
||||
|
#include "qtmvvmdatasynccore_global.h" |
||||
|
|
||||
|
namespace QtMvvm { |
||||
|
|
||||
|
class Q_MVVMDATASYNCCORE_EXPORT ExportSetupViewModel : public ViewModel |
||||
|
{ |
||||
|
Q_OBJECT |
||||
|
|
||||
|
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) |
||||
|
|
||||
|
Q_PROPERTY(bool valid READ isValid NOTIFY validChanged) |
||||
|
|
||||
|
public: |
||||
|
static std::tuple<bool, bool, QString> result(const QVariant &data); |
||||
|
|
||||
|
Q_INVOKABLE explicit ExportSetupViewModel(QObject *parent = nullptr); |
||||
|
|
||||
|
bool trusted() const; |
||||
|
bool includeServer() const; |
||||
|
QString password() const; |
||||
|
bool isValid() const; |
||||
|
|
||||
|
public Q_SLOTS: |
||||
|
bool completeSetup(); |
||||
|
|
||||
|
void setTrusted(bool trusted); |
||||
|
void setIncludeServer(bool includeServer); |
||||
|
void setPassword(QString password); |
||||
|
|
||||
|
Q_SIGNALS: |
||||
|
void trustedChanged(bool trusted); |
||||
|
void includeServerChanged(bool includeServer); |
||||
|
void passwordChanged(QString password); |
||||
|
void validChanged(); |
||||
|
|
||||
|
private: |
||||
|
bool _trusted; |
||||
|
QString _password; |
||||
|
bool _includeServer; |
||||
|
}; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
#endif // QTMVVM_EXPORTSETUPVIEWMODEL_P_H
|
@ -0,0 +1,43 @@ |
|||||
|
TARGET = QtMvvmDataSyncCore |
||||
|
|
||||
|
QT = core gui mvvmcore datasync mvvmcore-private |
||||
|
|
||||
|
HEADERS += \ |
||||
|
qtmvvmdatasynccore_global.h \ |
||||
|
datasyncviewmodel.h \ |
||||
|
datasyncviewmodel_p.h \ |
||||
|
accountmodel.h \ |
||||
|
accountmodel_p.h \ |
||||
|
exportsetupviewmodel_p.h |
||||
|
|
||||
|
SOURCES += \ |
||||
|
datasyncviewmodel.cpp \ |
||||
|
accountmodel.cpp \ |
||||
|
exportsetupviewmodel.cpp |
||||
|
|
||||
|
TRANSLATIONS += \ |
||||
|
translations/qtmvvmdatasynccore_de.ts \ |
||||
|
translations/qtmvvmdatasynccore_template.ts |
||||
|
|
||||
|
DISTFILES += $$TRANSLATIONS \ |
||||
|
application-x-datasync-account-data.xml |
||||
|
|
||||
|
qpmx_ts_target.path = $$[QT_INSTALL_TRANSLATIONS] |
||||
|
qpmx_ts_target.depends += lrelease |
||||
|
|
||||
|
load(qt_module) |
||||
|
|
||||
|
win32 { |
||||
|
QMAKE_TARGET_PRODUCT = "$$TARGET" |
||||
|
QMAKE_TARGET_COMPANY = "Skycoder42" |
||||
|
QMAKE_TARGET_COPYRIGHT = "Felix Barz" |
||||
|
} else:mac { |
||||
|
QMAKE_TARGET_BUNDLE_PREFIX = "com.skycoder42." |
||||
|
} |
||||
|
|
||||
|
!ReleaseBuild:!DebugBuild:!system(qpmx -d $$shell_quote($$_PRO_FILE_PWD_) --qmake-run init $$QPMX_EXTRA_OPTIONS $$shell_quote($$QMAKE_QMAKE) $$shell_quote($$OUT_PWD)): error(qpmx initialization failed. Check the compilation log for details.) |
||||
|
else: include($$OUT_PWD/qpmx_generated.pri) |
||||
|
|
||||
|
qpmx_ts_target.files -= $$OUT_PWD/$$QPMX_WORKINGDIR/qtmvvmdatasynccore_template.qm |
||||
|
qpmx_ts_target.files += translations/qtmvvmdatasynccore_template.ts |
||||
|
|
@ -0,0 +1,14 @@ |
|||||
|
{ |
||||
|
"dependencies": [], |
||||
|
"license": { |
||||
|
"file": "", |
||||
|
"name": "" |
||||
|
}, |
||||
|
"prcFile": "", |
||||
|
"priFile": "", |
||||
|
"priIncludes": [ |
||||
|
], |
||||
|
"publishers": { |
||||
|
}, |
||||
|
"source": false |
||||
|
} |
@ -0,0 +1,12 @@ |
|||||
|
#ifndef QTMVVMDATASYNCCORE_GLOBAL_H |
||||
|
#define QTMVVMDATASYNCCORE_GLOBAL_H |
||||
|
|
||||
|
#include <QtCore/qglobal.h> |
||||
|
|
||||
|
#if defined(QT_BUILD_MVVMDATASYNCCORE_LIB) |
||||
|
# define Q_MVVMDATASYNCCORE_EXPORT Q_DECL_EXPORT |
||||
|
#else |
||||
|
# define Q_MVVMDATASYNCCORE_EXPORT Q_DECL_IMPORT |
||||
|
#endif |
||||
|
|
||||
|
#endif // QTMVVMDATASYNCCORE_GLOBAL_H
|
@ -0,0 +1,4 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<!DOCTYPE TS> |
||||
|
<TS version="2.1" language="de_DE"> |
||||
|
</TS> |
@ -0,0 +1,4 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<!DOCTYPE TS> |
||||
|
<TS version="2.1"> |
||||
|
</TS> |
Loading…
Reference in new issue