File indexing completed on 2024-11-10 04:56:49

0001 /*
0002     SPDX-FileCopyrightText: 2018 Eike Hein <hein@kde.org>
0003     SPDX-FileCopyrightText: 2018 Marco Martin <mart@kde.org>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #pragma once
0009 
0010 #include <QAbstractListModel>
0011 
0012 #include "virtualdesktopsdbustypes.h"
0013 
0014 class QDBusArgument;
0015 class QDBusMessage;
0016 class QDBusServiceWatcher;
0017 
0018 namespace KWin
0019 {
0020 
0021 /**
0022  * @short An item model around KWin's D-Bus API for virtual desktops.
0023  *
0024  * The model initially gets the state from KWin and populates.
0025  *
0026  * As long as the user makes no changes, KWin-side changes are directly
0027  * exposed in the model.
0028  *
0029  * If the user makes changes (see the `userModified` property), it stops
0030  * exposing KWin-side changes live, but it keeps track of the KWin-side
0031  * changes, so it can figure out and apply the delta when `syncWithServer`
0032  * is called.
0033  *
0034  * When KWin-side changes happen while the model is user-modified, the
0035  * model signals this via the `serverModified` property. A call to
0036  * `syncWithServer` will overwrite the KWin-side changes.
0037  *
0038  * After synchronization, the model tracks Kwin-side changes again,
0039  * until the user makes further changes.
0040  *
0041  * @author Eike Hein <hein@kde.org>
0042  */
0043 
0044 class DesktopsModel : public QAbstractListModel
0045 {
0046     Q_OBJECT
0047     Q_PROPERTY(bool ready READ ready NOTIFY readyChanged)
0048     Q_PROPERTY(QString error READ error NOTIFY errorChanged)
0049     Q_PROPERTY(bool userModified READ userModified NOTIFY userModifiedChanged)
0050     Q_PROPERTY(bool serverModified READ serverModified NOTIFY serverModifiedChanged)
0051     Q_PROPERTY(int rows READ rows WRITE setRows NOTIFY rowsChanged)
0052     Q_PROPERTY(int desktopCount READ desktopCount NOTIFY desktopCountChanged)
0053 
0054 public:
0055     enum AdditionalRoles {
0056         Id = Qt::UserRole + 1,
0057         DesktopRow,
0058         IsDefault,
0059     };
0060     Q_ENUM(AdditionalRoles)
0061 
0062     explicit DesktopsModel(QObject *parent = nullptr);
0063     ~DesktopsModel() override;
0064 
0065     QHash<int, QByteArray> roleNames() const override;
0066 
0067     QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
0068     int rowCount(const QModelIndex &parent = {}) const override;
0069 
0070     bool ready() const;
0071     QString error() const;
0072 
0073     bool userModified() const;
0074     bool serverModified() const;
0075 
0076     int rows() const;
0077     void setRows(int rows);
0078 
0079     int desktopCount() const;
0080 
0081     QString createDesktopName() const;
0082     Q_INVOKABLE void createDesktop();
0083     Q_INVOKABLE void removeDesktop(const QString &id);
0084     Q_INVOKABLE void setDesktopName(const QString &id, const QString &name);
0085 
0086     Q_INVOKABLE void syncWithServer();
0087 
0088     bool needsSave() const;
0089     void load();
0090     void defaults();
0091     bool isDefaults() const;
0092 
0093 Q_SIGNALS:
0094     void readyChanged() const;
0095     void errorChanged() const;
0096     void userModifiedChanged() const;
0097     void serverModifiedChanged() const;
0098     void rowsChanged() const;
0099     void desktopCountChanged();
0100 
0101 protected Q_SLOTS:
0102     void reset();
0103     void getAllAndConnect(const QDBusMessage &msg);
0104     void desktopCreated(const QString &id, const KWin::DBusDesktopDataStruct &data);
0105     void desktopRemoved(const QString &id);
0106     void desktopDataChanged(const QString &id, const KWin::DBusDesktopDataStruct &data);
0107     void desktopRowsChanged(uint rows);
0108     void updateModifiedState(bool server = false);
0109     void handleCallError();
0110 
0111 private:
0112     QDBusServiceWatcher *m_serviceWatcher;
0113     QString m_error;
0114     bool m_userModified;
0115     bool m_serverModified;
0116     QStringList m_serverSideDesktops;
0117     QHash<QString, QString> m_serverSideNames;
0118     int m_serverSideRows;
0119     QStringList m_desktops;
0120     QHash<QString, QString> m_names;
0121     int m_rows;
0122     int m_pendingCalls = 0;
0123 };
0124 
0125 }