Skip to content
Snippets Groups Projects
PowerlevelsEditModels.h 7.04 KiB
Newer Older
  • Learn to ignore specific revisions
  • // SPDX-FileCopyrightText: Nheko Contributors
    
    //
    // SPDX-License-Identifier: GPL-3.0-or-later
    
    #pragma once
    
    #include <QAbstractListModel>
    #include <QSortFilterProxyModel>
    
    #include <mtx/events/power_levels.hpp>
    
    #include "CacheStructs.h"
    
    
    class PowerlevelsTypeListModel final : public QAbstractListModel
    
    signals:
        void adminLevelChanged();
        void moderatorLevelChanged();
    
    
    public:
        enum Roles
        {
            DisplayName,
            Powerlevel,
            IsType,
            Moveable,
            Removeable,
        };
    
        explicit PowerlevelsTypeListModel(const std::string &room_id_,
                                          const mtx::events::state::PowerLevels &pl,
                                          QObject *parent = nullptr);
    
        QHash<int, QByteArray> roleNames() const override;
        int rowCount(const QModelIndex &) const override { return static_cast<int>(types.size()); }
        QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    
        Q_INVOKABLE bool remove(int row);
        Q_INVOKABLE bool move(int from, int to);
        Q_INVOKABLE void add(int index, QString type);
    
        void addRole(int64_t role);
    
    
        bool moveRows(const QModelIndex &sourceParent,
                      int sourceRow,
                      int count,
                      const QModelIndex &destinationParent,
                      int destinationChild) override;
    
    
        std::map<std::string, mtx::events::state::power_level_t, std::less<>> toEvents() const;
        mtx::events::state::power_level_t kick() const;
        mtx::events::state::power_level_t invite() const;
        mtx::events::state::power_level_t ban() const;
        mtx::events::state::power_level_t eventsDefault() const;
        mtx::events::state::power_level_t stateDefault() const;
    
    
        struct Entry
        {
    
    Nicolas Werner's avatar
    Nicolas Werner committed
            ~Entry() = default;
    
            std::string type;
            mtx::events::state::power_level_t pl;
        };
    
        std::string room_id;
        QVector<Entry> types;
        mtx::events::state::PowerLevels powerLevels_;
    };
    
    
    class PowerlevelsUserListModel final : public QAbstractListModel
    
    signals:
        void defaultUserLevelChanged();
    
    
    public:
        enum Roles
        {
            Mxid,
            DisplayName,
            AvatarUrl,
            Powerlevel,
            IsUser,
            Moveable,
            Removeable,
        };
    
        explicit PowerlevelsUserListModel(const std::string &room_id_,
                                          const mtx::events::state::PowerLevels &pl,
                                          QObject *parent = nullptr);
    
        QHash<int, QByteArray> roleNames() const override;
        int rowCount(const QModelIndex &) const override { return static_cast<int>(users.size()); }
        QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    
        Q_INVOKABLE bool remove(int row);
        Q_INVOKABLE bool move(int from, int to);
        Q_INVOKABLE void add(int index, QString user);
    
        void addRole(int64_t role);
    
    
        bool moveRows(const QModelIndex &sourceParent,
                      int sourceRow,
                      int count,
                      const QModelIndex &destinationParent,
                      int destinationChild) override;
    
    
        std::map<std::string, mtx::events::state::power_level_t, std::less<>> toUsers() const;
        mtx::events::state::power_level_t usersDefault() const;
    
    Nicolas Werner's avatar
    Nicolas Werner committed
            ~Entry() = default;
    
            std::string mxid;
            mtx::events::state::power_level_t pl;
        };
    
        std::string room_id;
        QVector<Entry> users;
        mtx::events::state::PowerLevels powerLevels_;
    };
    
    
    class PowerlevelsSpacesListModel final : public QAbstractListModel
    
    {
        Q_OBJECT
        Q_PROPERTY(bool applyToChildren READ applyToChildren WRITE setApplyToChildren NOTIFY
                     applyToChildrenChanged)
        Q_PROPERTY(bool overwriteDiverged READ overwriteDiverged WRITE setOverwriteDiverged NOTIFY
                     overwriteDivergedChanged)
    
    signals:
        void applyToChildrenChanged();
        void overwriteDivergedChanged();
    
    public:
        enum Roles
        {
            DisplayName,
            AvatarUrl,
            IsSpace,
            IsEditable,
            IsDifferentFromBase,
            IsAlreadyUpToDate,
            ApplyPermissions,
        };
    
        explicit PowerlevelsSpacesListModel(const std::string &room_id_,
                                            const mtx::events::state::PowerLevels &pl,
                                            QObject *parent = nullptr);
    
        QHash<int, QByteArray> roleNames() const override;
        int rowCount(const QModelIndex &) const override { return static_cast<int>(spaces.size()); }
        QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
        bool
        setData(const QModelIndex &index, const QVariant &value, int role = Qt::DisplayRole) override;
    
        bool applyToChildren() const { return applyToChildren_; }
        bool overwriteDiverged() const { return overwriteDiverged_; }
    
        void setApplyToChildren(bool val)
        {
            applyToChildren_ = val;
            emit applyToChildrenChanged();
            updateToDefaults();
        }
        void setOverwriteDiverged(bool val)
        {
            overwriteDiverged_ = val;
            emit overwriteDivergedChanged();
            updateToDefaults();
        }
    
        void updateToDefaults();
    
        Q_INVOKABLE void commit();
    
        struct Entry
        {
            ~Entry() = default;
    
            std::string roomid;
            mtx::events::state::PowerLevels pl;
            bool apply = false;
        };
    
        std::string room_id;
        QVector<Entry> spaces;
        mtx::events::state::PowerLevels oldPowerLevels_, newPowerlevels_;
    
        bool applyToChildren_ = true, overwriteDiverged_ = false;
    };
    
    
    class PowerlevelEditingModels final : public QObject
    
    {
        Q_OBJECT
    
        Q_PROPERTY(PowerlevelsUserListModel *users READ users CONSTANT)
        Q_PROPERTY(PowerlevelsTypeListModel *types READ types CONSTANT)
    
        Q_PROPERTY(PowerlevelsSpacesListModel *spaces READ spaces CONSTANT)
    
        Q_PROPERTY(qlonglong adminLevel READ adminLevel NOTIFY adminLevelChanged)
        Q_PROPERTY(qlonglong moderatorLevel READ moderatorLevel NOTIFY moderatorLevelChanged)
        Q_PROPERTY(qlonglong defaultUserLevel READ defaultUserLevel NOTIFY defaultUserLevelChanged)
    
        Q_PROPERTY(bool isSpace READ isSpace CONSTANT)
    
    
    signals:
        void adminLevelChanged();
        void moderatorLevelChanged();
        void defaultUserLevelChanged();
    
    private:
        mtx::events::state::PowerLevels calculateNewPowerlevel() const;
    
    
    public:
        explicit PowerlevelEditingModels(QString room_id, QObject *parent = nullptr);
    
        PowerlevelsUserListModel *users() { return &users_; }
        PowerlevelsTypeListModel *types() { return &types_; }
    
        PowerlevelsSpacesListModel *spaces() { return &spaces_; }
    
        qlonglong adminLevel() const
        {
            return powerLevels_.state_level(to_string(mtx::events::EventType::RoomPowerLevels));
        }
        qlonglong moderatorLevel() const { return powerLevels_.redact; }
    
        qlonglong defaultUserLevel() const { return powerLevels_.users_default; }
    
        bool isSpace() const;
    
    
        Q_INVOKABLE void commit();
    
        Q_INVOKABLE void updateSpacesModel();
    
        Q_INVOKABLE void addRole(int pl);
    
    
        mtx::events::state::PowerLevels powerLevels_;
        PowerlevelsTypeListModel types_;
        PowerlevelsUserListModel users_;
    
        PowerlevelsSpacesListModel spaces_;
    
        std::string room_id_;
    };