1 /*
2  * SPDX-FileCopyrightText: 2013 Christian Mollekopf <mollekopf@kolabsys.com>
3  *
4  * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
5  *
6  */
7 
8 #pragma once
9 
10 #include "migratorbase.h"
11 #include <QAbstractItemModel>
12 class QObject;
13 #include <QPointer>
14 #include <QSharedPointer>
15 #include <QStandardItemModel>
16 
17 class MigrationExecutor;
18 class KJobTrackerInterface;
19 class MigratorModel;
20 
21 class LogModel : public QStandardItemModel
22 {
23     Q_OBJECT
24 public Q_SLOTS:
25     void message(MigratorBase::MessageType type, const QString &msg);
26 };
27 
28 class Row : public QObject
29 {
30     Q_OBJECT
31 public:
32     QSharedPointer<MigratorBase> mMigrator;
33     MigratorModel &mModel;
34 
35     explicit Row(const QSharedPointer<MigratorBase> &migrator, MigratorModel &model);
36 
37     bool operator==(const Row &other) const;
38 
39 private Q_SLOTS:
40     void stateChanged(MigratorBase::MigrationState);
41     void progress(int);
42 };
43 
44 /**
45  * The model serves as container for the migrators and exposes the status of each migrator.
46  *
47  * It can be plugged into a Listview to inform about the migration progress.
48  */
49 class MigratorModel : public QAbstractItemModel
50 {
51     Q_OBJECT
52 public:
53     enum Roles {
54         IdentifierRole = Qt::UserRole + 1,
55         LogfileRole,
56     };
57     bool addMigrator(const QSharedPointer<MigratorBase> &migrator);
58 
59     int rowCount(const QModelIndex &parent = QModelIndex()) const override;
60     int columnCount(const QModelIndex &parent = QModelIndex()) const override;
61     QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
62     QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
63     QModelIndex parent(const QModelIndex &child) const override;
64     QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
65 
66     QSharedPointer<MigratorBase> migrator(const QString &identifier) const;
67     QList<QSharedPointer<MigratorBase>> migrators() const;
68 
69 private:
70     enum Columns {
71         Name = 0,
72         Progress = 1,
73         State = 2,
74         ColumnCount,
75     };
76     friend class Row;
77     int positionOf(const Row &);
78     void columnChanged(const Row &, int column);
79     QList<QSharedPointer<Row>> mMigrators;
80 };
81 
82 /**
83  * Scheduler for migration jobs.
84  *
85  * Status information is exposed via getModel, which returns a list model containing all migrators with basic information.
86  * Additionally a logmodel is available via getLogModel for each migrator. The logmodel is continuously filled with information, and can be requested and
87  * displayed at any time.
88  *
89  * Migrators which return true on shouldAutostart() automatically enter a queue to be processed one after the other.
90  * When manually triggered it is possible though to run multiple jobs in parallel.
91  */
92 class MigrationScheduler : public QObject
93 {
94     Q_OBJECT
95 public:
96     explicit MigrationScheduler(KJobTrackerInterface *jobTracker = nullptr, QObject *parent = nullptr);
97     ~MigrationScheduler() override;
98 
99     void addMigrator(const QSharedPointer<MigratorBase> &migrator);
100 
101     // A model for the view
102     QAbstractItemModel &model();
103     QStandardItemModel &logModel(const QString &identifier);
104 
105     // Control
106     void start(const QString &identifier);
107     void pause(const QString &identifier);
108     void abort(const QString &identifier);
109 
110 private:
111     void checkForAutostart(const QSharedPointer<MigratorBase> &migrator);
112 
113     QScopedPointer<MigratorModel> mModel;
114     QHash<QString, QSharedPointer<LogModel>> mLogModel;
115     QPointer<MigrationExecutor> mAutostartExecutor;
116     KJobTrackerInterface *mJobTracker = nullptr;
117 };
118 
119