File indexing completed on 2026-08-09 12:02:24

0001 /*
0002     SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005 */
0006 #include "buttonsmodel.h"
0007 
0008 #include <KLocalizedString>
0009 
0010 #include <QFontDatabase>
0011 
0012 namespace KDecoration2
0013 {
0014 
0015 namespace Preview
0016 {
0017 
0018 ButtonsModel::ButtonsModel(const QVector<DecorationButtonType> &buttons, QObject *parent)
0019     : QAbstractListModel(parent)
0020     , m_buttons(buttons)
0021 {
0022 }
0023 
0024 ButtonsModel::ButtonsModel(QObject *parent)
0025     : ButtonsModel(QVector<DecorationButtonType>({DecorationButtonType::Menu,
0026                                                   DecorationButtonType::ApplicationMenu,
0027                                                   DecorationButtonType::OnAllDesktops,
0028                                                   DecorationButtonType::Minimize,
0029                                                   DecorationButtonType::Maximize,
0030                                                   DecorationButtonType::Close,
0031                                                   DecorationButtonType::ContextHelp,
0032                                                   DecorationButtonType::Shade,
0033                                                   DecorationButtonType::KeepBelow,
0034                                                   DecorationButtonType::KeepAbove}),
0035                    parent)
0036 {
0037 }
0038 
0039 ButtonsModel::~ButtonsModel() = default;
0040 
0041 int ButtonsModel::rowCount(const QModelIndex &parent) const
0042 {
0043     if (parent.isValid()) {
0044         return 0;
0045     }
0046     return m_buttons.count();
0047 }
0048 
0049 static QString buttonToName(DecorationButtonType type)
0050 {
0051     switch (type) {
0052     case DecorationButtonType::Menu:
0053         return i18n("More actions for this window");
0054     case DecorationButtonType::ApplicationMenu:
0055         return i18n("Application menu");
0056     case DecorationButtonType::OnAllDesktops:
0057         return i18n("On all desktops");
0058     case DecorationButtonType::Minimize:
0059         return i18n("Minimize");
0060     case DecorationButtonType::Maximize:
0061         return i18n("Maximize");
0062     case DecorationButtonType::Close:
0063         return i18n("Close");
0064     case DecorationButtonType::ContextHelp:
0065         return i18n("Context help");
0066     case DecorationButtonType::Shade:
0067         return i18n("Shade");
0068     case DecorationButtonType::KeepBelow:
0069         return i18n("Keep below other windows");
0070     case DecorationButtonType::KeepAbove:
0071         return i18n("Keep above other windows");
0072     default:
0073         return QString();
0074     }
0075 }
0076 
0077 QVariant ButtonsModel::data(const QModelIndex &index, int role) const
0078 {
0079     if (!index.isValid() || index.row() < 0 || index.row() >= m_buttons.count() || index.column() != 0) {
0080         return QVariant();
0081     }
0082     switch (role) {
0083     case Qt::DisplayRole:
0084         return buttonToName(m_buttons.at(index.row()));
0085     case Qt::UserRole:
0086         return QVariant::fromValue(int(m_buttons.at(index.row())));
0087     }
0088     return QVariant();
0089 }
0090 
0091 QHash<int, QByteArray> ButtonsModel::roleNames() const
0092 {
0093     QHash<int, QByteArray> roles;
0094     roles.insert(Qt::DisplayRole, QByteArrayLiteral("display"));
0095     roles.insert(Qt::UserRole, QByteArrayLiteral("button"));
0096     return roles;
0097 }
0098 
0099 void ButtonsModel::remove(int row)
0100 {
0101     if (row < 0 || row >= m_buttons.count()) {
0102         return;
0103     }
0104     beginRemoveRows(QModelIndex(), row, row);
0105     m_buttons.removeAt(row);
0106     endRemoveRows();
0107 }
0108 
0109 void ButtonsModel::down(int index)
0110 {
0111     if (m_buttons.count() < 2 || index == m_buttons.count() - 1) {
0112         return;
0113     }
0114     beginMoveRows(QModelIndex(), index, index, QModelIndex(), index + 2);
0115     m_buttons.insert(index + 1, m_buttons.takeAt(index));
0116     endMoveRows();
0117 }
0118 
0119 void ButtonsModel::up(int index)
0120 {
0121     if (m_buttons.count() < 2 || index == 0) {
0122         return;
0123     }
0124     beginMoveRows(QModelIndex(), index, index, QModelIndex(), index - 1);
0125     m_buttons.insert(index - 1, m_buttons.takeAt(index));
0126     endMoveRows();
0127 }
0128 
0129 void ButtonsModel::add(DecorationButtonType type)
0130 {
0131     beginInsertRows(QModelIndex(), m_buttons.count(), m_buttons.count());
0132     m_buttons.append(type);
0133     endInsertRows();
0134 }
0135 
0136 void ButtonsModel::add(int index, int type)
0137 {
0138     beginInsertRows(QModelIndex(), index, index);
0139     m_buttons.insert(index, KDecoration2::DecorationButtonType(type));
0140     endInsertRows();
0141 }
0142 
0143 void ButtonsModel::move(int sourceIndex, int targetIndex)
0144 {
0145     if (sourceIndex == std::max(0, targetIndex)) {
0146         return;
0147     }
0148 
0149     /* When moving an item down, the destination index needs to be incremented
0150        by one, as explained in the documentation:
0151        https://doc.qt.io/qt-5/qabstractitemmodel.html#beginMoveRows */
0152     if (targetIndex > sourceIndex) {
0153         // Row will be moved down
0154         beginMoveRows(QModelIndex(), sourceIndex, sourceIndex, QModelIndex(), targetIndex + 1);
0155     } else {
0156         beginMoveRows(QModelIndex(), sourceIndex, sourceIndex, QModelIndex(), std::max(0, targetIndex));
0157     }
0158 
0159     m_buttons.move(sourceIndex, std::max(0, targetIndex));
0160     endMoveRows();
0161 }
0162 
0163 void ButtonsModel::clear()
0164 {
0165     beginResetModel();
0166     m_buttons.clear();
0167     endResetModel();
0168 }
0169 
0170 void ButtonsModel::replace(const QVector<DecorationButtonType> &buttons)
0171 {
0172     if (buttons.isEmpty()) {
0173         return;
0174     }
0175 
0176     beginResetModel();
0177     m_buttons = buttons;
0178     endResetModel();
0179 }
0180 
0181 }
0182 }