File indexing completed on 2024-06-02 06:03:19

0001 /*
0002     This file is part of the Kasten Framework, made within the KDE community.
0003 
0004     SPDX-FileCopyrightText: 2007-2009, 2012 Friedrich W. H. Kossebau <kossebau@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0007 */
0008 
0009 #ifndef KASTEN_ABSTRACTMODELSYNCHRONIZER_HPP
0010 #define KASTEN_ABSTRACTMODELSYNCHRONIZER_HPP
0011 
0012 // lib
0013 #include "kastencore_export.hpp"
0014 #include "kastencore.hpp"
0015 // Qt
0016 #include <QObject>
0017 // Std
0018 #include <memory>
0019 
0020 class QUrl;
0021 
0022 namespace Kasten {
0023 
0024 class AbstractLoadJob;
0025 class AbstractConnectJob;
0026 class AbstractSyncToRemoteJob;
0027 class AbstractSyncFromRemoteJob;
0028 class AbstractSyncWithRemoteJob;
0029 class AbstractDocument;
0030 
0031 class AbstractModelSynchronizerPrivate;
0032 
0033 // TODO: better names? Active Translator?
0034 // synchronizers are created by factory functions (like plugins)
0035 
0036 // TODO: should synchronizers set the document to readonly if remote is readonly? or who?
0037 // TODO: should synchronizers offer to change writeflag at remote?
0038 // TODO: allow synchronizers which can read-only, perhaps also write-only (usecase?)
0039 
0040 /**
0041    possible actions:
0042    1. synchronizer loads document and synchronizes until closing
0043    -> done by factory functions
0044    2. synchronizer gets attached to a document new created or with other synchronizer
0045    3. synchronizer used to export a model
0046  */
0047 class KASTENCORE_EXPORT AbstractModelSynchronizer : public QObject
0048 {
0049     Q_OBJECT
0050 
0051 public:
0052     enum ConnectOption // TODO: better names
0053     {
0054         SyncLocalAndRemote = 0,
0055         ReplaceRemote = 1,
0056         ReplaceLocal = 2
0057     };
0058 
0059 protected:
0060     KASTENCORE_NO_EXPORT explicit AbstractModelSynchronizer(AbstractModelSynchronizerPrivate* d);
0061 
0062 public:
0063     AbstractModelSynchronizer();
0064 
0065     ~AbstractModelSynchronizer() override;
0066 
0067 public:
0068     QUrl url() const;
0069 
0070 public: // API to be implemented
0071     // TODO: makes this a job, too
0072     // TODO: filesystem synchronizer (or: to-passive-storage) does not need this: subclass or interface?
0073 //     virtual void startOffering( AbstractDocument* document ) = 0;
0074     // TODO: once the synchronizer is attached to a document, this function should not be called
0075     // is there a way to ensure this?
0076     virtual AbstractLoadJob* startLoad(const QUrl& url) = 0;
0077     /** */
0078     // TODO: not in constructor? cannot be called twice, each synchronizer is attached to its document
0079 //     virtual AbstractDocument* createWorkingCopy( const QUrl& originUrl, int* success ) const = 0;
0080 
0081     /** */
0082     // TODO: static? or by function? or another class? but
0083 //     virtual void copyTo( const QUrl& url, AbstractDocument* document, int* success ) const = 0;
0084 
0085     /** overwrite remote with local (save) */
0086     virtual AbstractSyncToRemoteJob* startSyncToRemote() = 0;
0087     /** overwrite local with remote (reload) */
0088     virtual AbstractSyncFromRemoteJob* startSyncFromRemote() = 0;
0089 
0090     /** changes the  */ // TODO: better name for replace: overwrite?
0091     virtual AbstractSyncWithRemoteJob* startSyncWithRemote(const QUrl& url, AbstractModelSynchronizer::ConnectOption option) = 0;
0092 
0093     virtual AbstractConnectJob* startConnect(AbstractDocument* document,
0094                                              const QUrl& url, AbstractModelSynchronizer::ConnectOption option) = 0;
0095 //     virtual bool syncBiDirectly() = 0;
0096 //     virtual bool canSyncBiDirectly() const = 0;
0097 //     virtual bool deleteDocument();
0098 
0099     virtual AbstractDocument* document() const = 0;
0100     virtual LocalSyncState localSyncState() const = 0;
0101     virtual RemoteSyncState remoteSyncState() const = 0;
0102 
0103 Q_SIGNALS:
0104     void urlChanged(const QUrl& url);
0105     // TODO: next two could be part of an interface? parameter quite specific
0106     void dataPulled(int) const;
0107     void dataPushed(int) const;
0108 
0109     // TODO: should be signal the diff? how to say then remote is in synch again?
0110     // could be done by pairs of flags instead of notset = isnot
0111     // TODO: this signal should be part of AbstractModel?
0112     void localSyncStateChanged(Kasten::LocalSyncState newState);
0113     void remoteSyncStateChanged(Kasten::RemoteSyncState newState);
0114 
0115 protected: // get
0116     void setUrl(const QUrl& url);
0117 
0118 protected:
0119     const std::unique_ptr<AbstractModelSynchronizerPrivate> d_ptr;
0120 
0121 private:
0122     Q_DECLARE_PRIVATE(AbstractModelSynchronizer)
0123 };
0124 
0125 }
0126 
0127 #endif