Skip to content
This repository was archived by the owner on Mar 4, 2023. It is now read-only.

Commit 3b9afd2

Browse files
committed
completed doc
1 parent f19a40e commit 3b9afd2

File tree

14 files changed

+186
-48
lines changed

14 files changed

+186
-48
lines changed

doc/Doxyfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1928,7 +1928,7 @@ RTF_SOURCE_CODE = NO
19281928
# classes and files.
19291929
# The default value is: NO.
19301930

1931-
GENERATE_MAN = NO
1931+
GENERATE_MAN = YES
19321932

19331933
# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
19341934
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of

doc/datastoremodel.dox

Lines changed: 66 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,25 @@ auto model = new QtDataSync::DataStoreModel(this);
4949
model->setTypeId<Person>();
5050
@endcode
5151

52-
To properly use it with widgets, you can use
53-
[QObjectListModel's](https://github.com/Skycoder42/QObjectListModel) `QObjectProxyModel`. The code
54-
below creates a model with 2 columns, where column 0 shows the "name" role and column 1 shows the
55-
"age" role:
52+
One additional feature of the model is, that it can also serve as model for table/tree views by
53+
delegating properties to multiple columns. This way you can use the model from QML by using the
54+
property names, and from widgets by delegating the properties to extra columns. For the above
55+
sample, the following code will result in a model with 2 columns, presenting the name and age
56+
properties as the Qt::DisplayRole of each column:
57+
5658
@code{.cpp}
57-
auto proxy = new QObjectProxyModel({"name", "age"}, this);
58-
proxy->setSourceModel(model);
59-
proxy->addMapping(0, Qt::DisplayRole, "name");
60-
proxy->addMapping(1, Qt::DisplayRole, "age");
59+
// setup first
60+
auto model = new QtDataSync::DataStoreModel(this);
61+
model->setTypeId<Person>();
62+
63+
// add the column config:
64+
auto col0 = model->addColumn("Name");
65+
model->addRole(col0, Qt::DisplayRole, "name");
66+
// or as shortcut for the above:
67+
model->addColumn("Age", "age");
6168
@endcode
6269

63-
@sa DataStore, [QObjectListModel](https://github.com/Skycoder42/QObjectListModel)
70+
@sa DataStore
6471
*/
6572

6673
/*!
@@ -79,9 +86,11 @@ properly.
7986
@accessors{
8087
@readAc{typeId()}
8188
@writeAc{setTypeId()}
89+
@notifyAc{typeIdChanged()}
8290
}
8391

84-
@sa DataStoreModel::storeError, DataStoreModel::reload
92+
@sa DataStoreModel::storeError, DataStoreModel::reload, DataStoreModel::addColumn,
93+
DataStoreModel::addRole
8594
*/
8695

8796
/*!
@@ -165,3 +174,50 @@ DataStore::load.
165174
@sa DataStoreModel::object, DataStore::load
166175
*/
167176

177+
/*!
178+
@fn QVariant QtDataSync::DataStoreModel::addColumn(const QString &)
179+
180+
@param text The display name of the column header
181+
@returns The index of the newly created column
182+
183+
The method add a column to the model that can be used to present propeties from the underlying
184+
data as specific roles.
185+
186+
@attention If no custom columns have been added yet, the model with have a single column with
187+
the typeId class name as title. By calling this method the first time, this default column will
188+
be **replaced** by whatever column you specify. All subsequent columns are simply added as new
189+
columns.
190+
191+
@sa DataStoreModel, DataStoreModel::typeId, DataStore::addRole, DataStore::clearColumns
192+
*/
193+
194+
/*!
195+
@fn QVariant QtDataSync::DataStoreModel::addColumn(const QString &, const char *)
196+
197+
@param text The display name of the column header
198+
@param propertyName The name of the property to presented as the display role of that column
199+
@returns The index of the newly created column
200+
201+
This method is basically a shortcut for:
202+
203+
@code{.cpp}
204+
auto column = model->addColumn(text);
205+
model->addRole(column, Qt::DisplayRole, propertyName
206+
@endcode
207+
208+
@sa DataStoreModel, DataStoreModel::typeId, DataStore::addRole, DataStore::clearColumns
209+
*/
210+
211+
/*!
212+
@fn QVariant QtDataSync::DataStoreModel::addRole
213+
214+
@param column The existing column to add the role to
215+
@param role The role that should be added to the column
216+
@param propertyName The name of the property to presented as the give role of that column
217+
218+
This method adds a new role to an existing column. The new role will simply the the value of the
219+
given property of the object in each row. It's basically a delegate to the properties role.
220+
221+
@sa DataStoreModel, DataStoreModel::typeId, DataStore::addColumn, DataStore::clearColumns
222+
*/
223+

doc/setup.dox

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,32 @@ This may take a moment to complete, depending on the keystore beeing used.
461461
@sa Setup::keystoreProviders, Setup::availableKeystores
462462
*/
463463

464+
/*!
465+
@fn QtDataSync::Setup::loadKeystore(QObject *, const QString &)
466+
467+
@param parent The parent object to set as the keystores parent
468+
@param setupName The name of the setup to create the keystore for
469+
@returns A newly created KeyStore instance or nullptr if the keystore does not exist
470+
@throws SetupDoesNotExistException If the setup specified by setupName does not exist (yet)
471+
@throws QException If something went wrong while loading the plugin
472+
473+
This method simply creates a keystore instance. This can be useful if you want to use a
474+
keystore outside of datasync to store your own secrets there.
475+
476+
@note The keystore still requires a valid and running datasync instance, as it is needed
477+
for logging etc. This is only due to how the keystore is designed, as external access was
478+
originally not planned, and may change in the future.
479+
480+
@sa KeyStore, Setup::keystoreProviders, Setup::defaultKeystoreProvider
481+
*/
482+
483+
/*!
484+
@fn QtDataSync::Setup::loadKeystore(const QString &, QObject *, const QString &)
485+
486+
@param provider The keystore provider to create a keystore for
487+
@copydetails Setup::loadKeystore(QObject *, const QString &)
488+
*/
489+
464490
/*!
465491
@fn QtDataSync::Setup::defaultKeystoreProvider
466492

@@ -480,6 +506,35 @@ the plain provider is returned, even if it is not available. The list is sorted
480506
@sa Setup::keystoreProviders, Setup::availableKeystores
481507
*/
482508

509+
/*!
510+
@fn QtDataSync::Setup::setAccount(const QJsonObject &, bool, bool)
511+
512+
@param importData The account data to be imported
513+
@param keepData Specify whether the stored data should be preserved
514+
@param allowFailure Specify how a failure to import the account should be treated
515+
516+
This method is basically a shortcut to import an account on creation - which is faster and
517+
much more efficient than first creating a new account and then delete it again to import an
518+
existing one. Internally, the same things will happen as with AccountManager::importAccount
519+
(or AccountManager::importAccountTrusted).
520+
521+
Whats special is that since there is no account manager to handle a failure, there are two
522+
way to handle that. If `allowFailure` is false (the default), failing to import the data
523+
will trigger a fatal error. If it is set to true, the error is only printed and a new account
524+
is created instead, so that the engine can continue running.
525+
526+
@sa Setup::setAccount, Setup::setAccountTrusted, AccountManager::importAccount,
527+
AccountManager::importAccountTrusted,
528+
*/
529+
530+
/*!
531+
@fn QtDataSync::Setup::setAccountTrusted(const QJsonObject &, const QString &, bool, bool)
532+
533+
@param password The password used to decrypt the imported data with. Must be the same as used
534+
for the export
535+
@copydetails Setup::setAccount(const QJsonObject &, bool, bool)
536+
*/
537+
483538
/*!
484539
@fn QtDataSync::Setup::create
485540

src/datasync/conflictresolver.h

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ class GenericConflictResolver : public GenericConflictResolver<Args...>
7070
}
7171

7272
protected:
73+
//! @private
7374
using NoConflictResultException = typename GenericConflictResolver<Args...>::NoConflictResultException;
7475

7576
/*!
@@ -79,12 +80,16 @@ class GenericConflictResolver : public GenericConflictResolver<Args...>
7980
* @param data2 The second dataset
8081
* @param parent A temporary qobject to use as parent for created QObjects
8182
* @returns The independent merge result of the two datasets
82-
* @throws QException In case data corruption was detected an exception can be thrown to abort the
83+
* @throws NoConflictResultException Thrown if resolving was not possible and the default JSON-based
84+
* resolving should be used instead
85+
* @throws QException In case data corruption was detected an exception can be thrown to abort the
8386
* synchronization. This will put the engine in an (unrecoverable) error state.
8487
*
8588
* Must be implemented as the main method of the resolver. The method *must* always return something.
86-
* Unlike the json variant, you cannot return a "default" result. No matter what is returned, it is
87-
* always used as it. Thus, you cannot return nullptr.
89+
* If you find that you cannot decide how to merge, simply throw the `NoConflictResultException`.
90+
* In that case, the library will ignore the result and proceed to merge as if no conflict resolver
91+
* was present. It's basically this methods equivalent of returning an empty JSON object on the
92+
* non generic variant of this method.
8893
*
8994
* @warning This method **must** be deterministic and independent of the parameter order. This means
9095
* if you assume you have 2 objects, no matter at what point in time and in which order they are
@@ -122,6 +127,7 @@ class GenericConflictResolver<T1> : public ConflictResolver
122127
}
123128

124129
protected:
130+
//! An exception to be thrown from resolveConflict() if resolving was not possible and the default JSON-based resolving should be used instead
125131
class NoConflictResultException {};
126132

127133
/*!
@@ -131,12 +137,16 @@ class GenericConflictResolver<T1> : public ConflictResolver
131137
* @param data2 The second dataset
132138
* @param parent A temporary qobject to use as parent for created QObjects
133139
* @returns The independent merge result of the two datasets
134-
* @throws QException In case data corruption was detected an exception can be thrown to abort the
140+
* @throws NoConflictResultException Thrown if resolving was not possible and the default JSON-based
141+
* resolving should be used instead
142+
* @throws QException In case data corruption was detected an exception can be thrown to abort the
135143
* synchronization. This will put the engine in an (unrecoverable) error state.
136144
*
137145
* Must be implemented as the main method of the resolver. The method *must* always return something.
138-
* Unlike the json variant, you cannot return a "default" result. No matter what is returned, it is
139-
* always used as it. Thus, you cannot return nullptr.
146+
* If you find that you cannot decide how to merge, simply throw the `NoConflictResultException`.
147+
* In that case, the library will ignore the result and proceed to merge as if no conflict resolver
148+
* was present. It's basically this methods equivalent of returning an empty JSON object on the
149+
* non generic variant of this method.
140150
*
141151
* @warning This method **must** be deterministic and independent of the parameter order. This means
142152
* if you assume you have 2 objects, no matter at what point in time and in which order they are

src/datasync/datastoremodel.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,12 @@ void DataStoreModel::addRole(int column, int role, const char *propertyName)
240240
emit dataChanged(this->index(0, column), this->index(rowCount() - 1, column), {role});
241241
}
242242

243+
void DataStoreModel::clearColumns()
244+
{
245+
d->columns.clear();
246+
d->roleMapping.clear();
247+
}
248+
243249
void DataStoreModel::setTypeId(int typeId)
244250
{
245251
setTypeId(typeId, true);
@@ -256,10 +262,8 @@ void DataStoreModel::setTypeId(int typeId, bool resetColumns)
256262
beginResetModel();
257263
d->isObject = flags.testFlag(QMetaType::PointerToQObject);
258264
d->keyList.clear();
259-
if(resetColumns) {
260-
d->columns.clear();
261-
d->roleMapping.clear();
262-
}
265+
if(resetColumns)
266+
clearColumns();
263267
d->clearHashObjects();
264268
d->createRoleNames();
265269

src/datasync/datastoremodel.h

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,18 @@ class Q_DATASYNC_EXPORT DataStoreModel : public QAbstractTableModel
4040
//! @readAcFn{DataStoreModel::editable}
4141
bool isEditable() const;
4242

43-
//! @inherit{QAbstractListModel::headerData}
43+
//! @inherit{QAbstractTableModel::headerData}
4444
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
45-
//! @inherit{QAbstractListModel::rowCount}
45+
//! @inherit{QAbstractTableModel::rowCount}
4646
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
47+
//! @inherit{QAbstractTableModel::columnCount}
4748
int columnCount(const QModelIndex &parent) const override;
48-
//! @inherit{QAbstractListModel::canFetchMore}
49+
//! @inherit{QAbstractTableModel::canFetchMore}
4950
bool canFetchMore(const QModelIndex &parent) const override;
50-
//! @inherit{QAbstractListModel::fetchMore}
51+
//! @inherit{QAbstractTableModel::fetchMore}
5152
void fetchMore(const QModelIndex &parent) override;
5253

54+
//! @inherit{QAbstractTableModel::index}
5355
QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const override;
5456
//! Returns the index of the item with the given id
5557
Q_INVOKABLE QModelIndex idIndex(const QString &id) const;
@@ -63,9 +65,9 @@ class Q_DATASYNC_EXPORT DataStoreModel : public QAbstractTableModel
6365
template <typename T>
6466
inline T key(const QModelIndex &index) const;
6567

66-
//! @inherit{QAbstractListModel::data}
68+
//! @inherit{QAbstractTableModel::data}
6769
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
68-
//! @inherit{QAbstractListModel::setData}
70+
//! @inherit{QAbstractTableModel::setData}
6971
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
7072

7173
//! Returns the object at the given index
@@ -85,18 +87,24 @@ class Q_DATASYNC_EXPORT DataStoreModel : public QAbstractTableModel
8587
template <typename T>
8688
T loadObject(const QModelIndex &index) const;
8789

88-
//! @inherit{QAbstractListModel::flags}
90+
//! @inherit{QAbstractTableModel::flags}
8991
Qt::ItemFlags flags(const QModelIndex &index) const override;
90-
//! @inherit{QAbstractListModel::roleNames}
92+
//! @inherit{QAbstractTableModel::roleNames}
9193
QHash<int, QByteArray> roleNames() const override;
9294

95+
//! Add a new column with the given title
9396
int addColumn(const QString &text);
97+
//! Add a new column and set the given property as its Qt::DisplayRole
9498
int addColumn(const QString &text, const char *propertyName);
99+
//! Adds the given property as a new role to the given column
95100
void addRole(int column, int role, const char *propertyName);
101+
//! Removes all customly added columns and roles
102+
void clearColumns();
96103

97104
public Q_SLOTS:
98105
//! @writeAcFn{DataStoreModel::typeId}
99106
void setTypeId(int typeId); //MAJOR merge methods
107+
//! @writeAcFn{DataStoreModel::typeId}
100108
void setTypeId(int typeId, bool resetColumns);
101109
//! @writeAcFn{DataStoreModel::editable}
102110
void setEditable(bool editable);
@@ -107,6 +115,7 @@ public Q_SLOTS:
107115
Q_SIGNALS:
108116
//! Emitted when the underlying DataStore throws an exception
109117
void storeError(const QException &exception, QPrivateSignal);
118+
//! @notifyAcFn{DataStoreModel::typeId}
110119
void typeIdChanged(int typeId, QPrivateSignal);
111120
//! @notifyAcFn{DataStoreModel::editable}
112121
void editableChanged(bool editable, QPrivateSignal);

src/datasync/datasync.pro

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
TARGET = QtDataSync
22

33
QT = core jsonserializer sql websockets scxml remoteobjects remoteobjects-private
4-
#android: QT += androidextras #needed to deploy the android keystore plugin
54

65
HEADERS += \
76
qtdatasync_global.h \

src/datasync/defaults.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,11 @@ class Q_DATASYNC_EXPORT Defaults
8484
Defaults(const QSharedPointer<DefaultsPrivate> &d);
8585
//! Copy constructor
8686
Defaults(const Defaults &other);
87+
//! Move constructor
8788
Defaults(Defaults &&other);
89+
//! Copy assignment operator
8890
Defaults &operator=(const Defaults &other);
91+
//! Move assignment operator
8992
Defaults &operator=(Defaults &&other);
9093
~Defaults();
9194

src/datasync/exception.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@ class Q_DATASYNC_EXPORT Exception : public QException
2828
//! Like what, but returns a QString instead of a character array
2929
virtual QString qWhat() const;
3030
//! @inherit{QException::what}
31-
const char *what() const noexcept final; //mark virtual again for doxygen
31+
virtual const char *what() const noexcept final; //mark virtual again for doxygen
3232

3333
//! @inherit{QException::raise}
34-
void raise() const override; //mark virtual again for doxygen
34+
virtual void raise() const override; //mark virtual again for doxygen
3535
//! @inherit{QException::clone}
36-
QException *clone() const override; //mark virtual again for doxygen
36+
virtual QException *clone() const override; //mark virtual again for doxygen
3737

3838
protected:
3939
//! @private

src/datasync/setup.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,9 @@ class Q_DATASYNC_EXPORT Setup
177177
static bool keystoreAvailable(const QString &provider);
178178
//! Returns the default provider to be used based on the current platform and the available providers
179179
static QString defaultKeystoreProvider();
180+
//! Create and load akeystore instance from the default provider
180181
static KeyStore *loadKeystore(QObject *parent = nullptr, const QString &setupName = DefaultSetup);
182+
//! Create and load akeystore instance from the given provider
181183
static KeyStore *loadKeystore(const QString &provider, QObject *parent = nullptr, const QString &setupName = DefaultSetup);
182184

183185
Setup();
@@ -288,9 +290,13 @@ class Q_DATASYNC_EXPORT Setup
288290
//! @resetAcFn{Setup::cipherKeySize}
289291
Setup &resetCipherKeySize();
290292

293+
//! Sets an account to be imported on creation of the instance
291294
Setup &setAccount(const QJsonObject &importData, bool keepData = false, bool allowFailure = false);
295+
//! @copydoc Setup::setAccount(const QJsonObject &, bool, bool)
292296
Setup &setAccount(const QByteArray &importData, bool keepData = false, bool allowFailure = false);
297+
//! @copybrief Setup::setAccount(const QJsonObject &, bool, bool)
293298
Setup &setAccountTrusted(const QJsonObject &importData, const QString &password, bool keepData = false, bool allowFailure = false);
299+
//! @copydoc Setup::setAccountTrusted(const QJsonObject &, const QString &, bool, bool)
294300
Setup &setAccountTrusted(const QByteArray &importData, const QString &password, bool keepData = false, bool allowFailure = false);
295301

296302
//! Creates a datasync instance from this setup with the given name

0 commit comments

Comments
 (0)