File indexing completed on 2024-04-14 05:24:31

0001 /*
0002     SPDX-FileCopyrightText: 2021 Michail Vourlakos <mvourlakos@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "screensmodel.h"
0008 
0009 // Qt
0010 #include <QFont>
0011 #include <QIcon>
0012 
0013 // KDE
0014 #include <KLocalizedString>
0015 
0016 namespace Latte {
0017 namespace Settings {
0018 namespace Model {
0019 
0020 Screens::Screens(QObject *parent)
0021     : QAbstractTableModel(parent)
0022 {
0023 }
0024 
0025 Screens::~Screens()
0026 {
0027 }
0028 
0029 bool Screens::hasChangedData() const
0030 {
0031     return c_screens != o_screens;
0032 }
0033 
0034 bool Screens::hasChecked() const
0035 {
0036     for(int i=0; i<c_screens.rowCount(); ++i) {
0037         if (c_screens[i].isSelected) {
0038             return true;
0039         }
0040     }
0041 
0042     return false;
0043 }
0044 
0045 int Screens::rowCount() const
0046 {
0047     return c_screens.rowCount();
0048 }
0049 
0050 int Screens::rowCount(const QModelIndex &parent) const
0051 {
0052     Q_UNUSED(parent);
0053 
0054     return c_screens.rowCount();
0055 }
0056 
0057 int Screens::columnCount(const QModelIndex &parent) const
0058 {
0059     Q_UNUSED(parent);
0060 
0061     return 1;
0062 }
0063 
0064 int Screens::row(const QString &id)
0065 {
0066     for (int i=0; i<c_screens.rowCount(); ++i){
0067         if (c_screens[i].id == id) {
0068             return i;
0069         }
0070     }
0071 
0072     return -1;
0073 }
0074 
0075 bool Screens::inDefaultValues() const
0076 {
0077     return c_screens == o_screens;
0078 }
0079 
0080 void Screens::initDefaults()
0081 {
0082     for(int i=0; i<c_screens.rowCount(); ++i) {
0083         c_screens[i].isSelected = false;
0084     }
0085 }
0086 
0087 void Screens::clear()
0088 {
0089     if (c_screens.rowCount() > 0) {
0090         beginRemoveRows(QModelIndex(), 0, c_screens.rowCount() - 1);
0091         c_screens.clear();
0092         endRemoveRows();
0093 
0094         emit screenDataChanged();
0095     }
0096 }
0097 
0098 void Screens::deselectAll()
0099 {
0100     QVector<int> roles;
0101     roles << Qt::CheckStateRole;
0102 
0103     for(int i=0; i<c_screens.rowCount(); ++i) {
0104         c_screens[i].isSelected = false;
0105     }
0106 
0107     emit dataChanged(index(0, SCREENCOLUMN), index(c_screens.rowCount()-1, SCREENCOLUMN), roles);
0108     emit screenDataChanged();
0109 }
0110 
0111 void Screens::reset()
0112 {
0113     c_screens = o_screens;
0114 
0115     QVector<int> roles;
0116     roles << Qt::CheckStateRole;
0117 
0118     emit dataChanged(index(0, SCREENCOLUMN), index(c_screens.rowCount()-1, SCREENCOLUMN), roles);
0119     emit screenDataChanged();
0120 }
0121 
0122 QString Screens::sortableId(const QString &id) const
0123 {
0124     int sid = id.toInt();
0125 
0126     //! reverse id priority, smaller id has higher priority
0127     if (sid < 10) {
0128         return QString::number(99999 - sid);
0129     } else if (sid < 100) {
0130         return QString::number(9999 - sid);
0131     } else if (sid < 1000) {
0132         return QString::number(999 - sid);
0133     }
0134 
0135     return QString::number(999 - sid);
0136 }
0137 
0138 QString Screens::sortableText(const int &priority, const QString &text) const
0139 {
0140     QString numberPart;
0141 
0142     if (priority < 10) {
0143         numberPart = "00000" + QString::number(priority);
0144     } else if (priority < 100) {
0145         numberPart = "0000" + QString::number(priority);
0146     } else if (priority < 1000) {
0147         numberPart = "000" + QString::number(priority);
0148     } else if (priority < 10000) {
0149         numberPart = "00" + QString::number(priority);
0150     } else if (priority < 100000) {
0151         numberPart = "0" + QString::number(priority);
0152     }
0153 
0154     return (numberPart + text);
0155 }
0156 
0157 void Screens::setData(const Latte::Data::ScreensTable &screens)
0158 {
0159     clear();
0160 
0161     if (screens.rowCount() > 0) {
0162         beginInsertRows(QModelIndex(), 0, screens.rowCount()-1);
0163         c_screens = screens;
0164         initDefaults();
0165         o_screens = c_screens;
0166         endInsertRows();
0167 
0168         emit screenDataChanged();
0169     }
0170 }
0171 
0172 void Screens::setSelected(const Latte::Data::ScreensTable &screens)
0173 {
0174     bool changed{false};
0175 
0176     for(int i=0; i<screens.rowCount(); ++i) {
0177         int pos = c_screens.indexOf(screens[i].id);
0178 
0179         if (pos>=0 && screens[i].isSelected != c_screens[pos].isSelected) {
0180             QVector<int> roles;
0181             roles << Qt::CheckStateRole;
0182 
0183             c_screens[pos].isSelected = screens[i].isSelected;
0184             emit dataChanged(index(pos, SCREENCOLUMN), index(pos, SCREENCOLUMN), roles);
0185             changed = true;
0186         }
0187     }
0188 
0189     if (changed) {
0190         emit screenDataChanged();
0191     }
0192 }
0193 
0194 Latte::Data::ScreensTable Screens::checkedScreens()
0195 {
0196     Data::ScreensTable checked;
0197 
0198     for(int i=0; i<c_screens.rowCount(); ++i) {
0199         if (!c_screens[i].isActive && c_screens[i].isSelected) {
0200             checked << c_screens[i];
0201         }
0202     }
0203     return checked;
0204 }
0205 
0206 Qt::ItemFlags Screens::flags(const QModelIndex &index) const
0207 {
0208     const int column = index.column();
0209     const int row = index.row();
0210 
0211     auto flags = QAbstractTableModel::flags(index);
0212 
0213     if (c_screens[row].isRemovable) {
0214         flags |= Qt::ItemIsUserCheckable;
0215     } else {
0216         flags &= ~Qt::ItemIsSelectable;
0217         flags &= ~Qt::ItemIsEditable;
0218     }
0219 
0220     return flags;
0221 }
0222 
0223 QVariant Screens::headerData(int section, Qt::Orientation orientation, int role) const
0224 {
0225     if (orientation != Qt::Horizontal) {
0226         return QAbstractTableModel::headerData(section, orientation, role);
0227     }
0228 
0229     if (role == Qt::FontRole) {
0230         QFont font = qvariant_cast<QFont>(QAbstractTableModel::headerData(section, orientation, role));
0231         font.setBold(true);
0232         return font;
0233     }
0234 
0235     switch(section) {
0236     case SCREENCOLUMN:
0237         if (role == Qt::DisplayRole) {
0238             return QString(i18nc("column for screens", "Screens"));
0239         }
0240         break;
0241     default:
0242         break;
0243     };
0244 
0245     return QAbstractTableModel::headerData(section, orientation, role);
0246 }
0247 
0248 bool Screens::setData(const QModelIndex &index, const QVariant &value, int role)
0249 {
0250     const int row = index.row();
0251     const int column = index.column();
0252 
0253     if (!c_screens.rowExists(row) || column<0 || column > SCREENCOLUMN) {
0254         return false;
0255     }
0256 
0257     //! specific roles to each independent cell
0258     switch (column) {
0259     case SCREENCOLUMN:
0260         if (role == Qt::CheckStateRole) {
0261             c_screens[row].isSelected = (value.toInt() > 0 ? true : false);
0262             emit screenDataChanged();
0263             return true;
0264         }
0265         break;
0266     };
0267 
0268     return false;
0269 }
0270 
0271 QVariant Screens::data(const QModelIndex &index, int role) const
0272 {
0273     const int row = index.row();
0274     int column = index.column();
0275 
0276     if (row >= rowCount()) {
0277         return QVariant{};
0278     }
0279 
0280     if (role == IDROLE) {
0281         return c_screens[row].id;
0282     } else if (role == Qt::DisplayRole) {
0283         QString display = "{" + c_screens[row].id + "} " + c_screens[row].name;
0284         return display;
0285     } else if (role == Qt::CheckStateRole) {
0286         return (c_screens[row].isSelected ? Qt::Checked : Qt::Unchecked);
0287     } else if (role == ISSCREENACTIVEROLE) {
0288         return c_screens[row].isActive;
0289     } else if (role == ISSELECTEDROLE) {
0290         return c_screens[row].isSelected;
0291     } else if (role == SCREENDATAROLE) {
0292         QVariant scrVariant;
0293         Latte::Data::Screen scrdata = c_screens[row];
0294         scrVariant.setValue<Latte::Data::Screen>(scrdata);
0295         return scrVariant;
0296     } else if (role == SORTINGROLE) {
0297         //! reverse id priority, smaller id has higher priority
0298         QString idstr = sortableId(c_screens[row].id);
0299 
0300         if (c_screens[row].isActive) {
0301             return sortableText(HIGHESTPRIORITY, idstr);
0302         } else if (!c_screens[row].isRemovable) {
0303             return sortableText(HIGHPRIORITY, idstr);
0304         }
0305 
0306         return sortableText(NORMALPRIORITY, idstr);
0307     }
0308 
0309     return QVariant{};
0310 }
0311 
0312 }
0313 }
0314 }