File indexing completed on 2024-04-28 09:25:44

0001 /*
0002     SPDX-FileCopyrightText: 2021 Michail Vourlakos <mvourlakos@gmail.com>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 #include "viewsmodel.h"
0007 
0008 // local
0009 #include <coretypes.h>
0010 #include "../../screenpool.h"
0011 #include "../../data/genericdata.h"
0012 #include "../../data/screendata.h"
0013 
0014 // KDE
0015 #include <KLocalizedString>
0016 
0017 #define TEMPIDDISPLAY "#"
0018 
0019 namespace Latte {
0020 namespace Settings {
0021 namespace Model {
0022 
0023 Views::Views(QObject *parent, Latte::Corona *corona)
0024     : QAbstractTableModel(parent),
0025       m_corona(corona)
0026 {
0027     initEdges();
0028     initAlignments();
0029     populateScreens();
0030 }
0031 
0032 Views::~Views()
0033 {
0034 }
0035 
0036 bool Views::hasChangedData() const
0037 {
0038     return o_viewsTable != m_viewsTable;
0039 }
0040 
0041 int Views::rowCount() const
0042 {
0043     return m_viewsTable.rowCount();
0044 }
0045 
0046 int Views::columnCount()
0047 {
0048     return LASTCOLUMN;
0049 }
0050 
0051 int Views::rowCount(const QModelIndex &parent) const
0052 {
0053     Q_UNUSED(parent);
0054     return m_viewsTable.rowCount();
0055 }
0056 
0057 int Views::columnCount(const QModelIndex &parent) const
0058 {
0059     Q_UNUSED(parent);
0060     return columnCount();
0061 }
0062 
0063 int Views::rowForId(const QString &id) const
0064 {
0065     return m_viewsTable.indexOf(id);
0066 }
0067 
0068 const Latte::Data::View &Views::at(const int &row)
0069 {
0070     return m_viewsTable[row];
0071 }
0072 
0073 const Latte::Data::View Views::currentData(const QString &id)
0074 {
0075     if (!m_viewsTable.containsId(id)) {
0076         return Latte::Data::View();
0077     }
0078 
0079     return m_viewsTable[id];
0080 }
0081 
0082 
0083 const Latte::Data::View Views::originalData(const QString &id)
0084 {
0085     if (o_viewsTable.containsId(id)){
0086         return o_viewsTable[id];
0087     }
0088 
0089     return Latte::Data::View();
0090 }
0091 
0092 const Latte::Data::ViewsTable &Views::currentViewsData()
0093 {
0094     return m_viewsTable;
0095 }
0096 
0097 const Latte::Data::ViewsTable &Views::originalViewsData()
0098 {
0099     return o_viewsTable;
0100 }
0101 
0102 int Views::sortingFactorForState(const Data::View &view) const
0103 {
0104     if (view.isActive) {
0105         return 1;
0106     } else if (view.state() == Data::View::IsCreated) {
0107         return 2;
0108     }
0109 
0110     //! temp case
0111     return 3;
0112 }
0113 
0114 int Views::sortingFactorForScreen(const Data::View &view) const
0115 {
0116     if (view.onPrimary) {
0117         return 1;
0118     }
0119 
0120     //! explicit screen
0121     return 2;
0122 }
0123 
0124 int Views::sortingFactorForEdge(const Data::View &view) const
0125 {
0126     if (view.edge == Plasma::Types::TopEdge) {
0127         return 1;
0128     } else if (view.edge == Plasma::Types::LeftEdge) {
0129         return 2;
0130     } else if (view.edge == Plasma::Types::BottomEdge) {
0131         return 3;
0132     }
0133 
0134     //! Right edge
0135     return 4;
0136 }
0137 
0138 int Views::sortingFactorForAlignment(const Data::View &view) const
0139 {
0140     if (view.alignment == Latte::Types::Top || view.alignment == Latte::Types::Left) {
0141         return 1;
0142     } else if (view.alignment == Latte::Types::Center) {
0143         return 2;
0144     } else if (view.alignment == Latte::Types::Bottom || view.alignment == Latte::Types::Right) {
0145         return 3;
0146     }
0147 
0148     //! Justify alignment
0149     return 4;
0150 }
0151 
0152 int Views::sortingFactorForSubContainments(const Data::View &view) const
0153 {
0154     return view.subcontainments.rowCount()+1;
0155 }
0156 
0157 QString Views::sortableText(const int &priority, const QString &text) const
0158 {
0159     QString numberPart;
0160 
0161     if (priority < 10) {
0162         numberPart = "00000" + QString::number(priority);
0163     } else if (priority < 100) {
0164         numberPart = "0000" + QString::number(priority);
0165     } else if (priority < 1000) {
0166         numberPart = "000" + QString::number(priority);
0167     } else if (priority < 10000) {
0168         numberPart = "00" + QString::number(priority);
0169     } else if (priority < 100000) {
0170         numberPart = "0" + QString::number(priority);
0171     }
0172 
0173     return (numberPart + text);
0174 }
0175 
0176 void Views::clear()
0177 {
0178     if (m_viewsTable.rowCount() > 0) {
0179         beginRemoveRows(QModelIndex(), 0, m_viewsTable.rowCount() - 1);
0180         m_viewsTable.clear();
0181         endRemoveRows();
0182     }
0183 }
0184 
0185 void Views::initEdges()
0186 {
0187     s_edges.clear();
0188 
0189     int i=0;
0190     s_edges << Data::View(QString::number(Plasma::Types::TopEdge), i18nc("top edge", "Top"));
0191     s_edges[i].edge = Plasma::Types::TopEdge; s_edges[i].alignment = Latte::Types::Center;
0192     s_edges[i].setState(Data::View::IsCreated);
0193 
0194     i++;
0195     s_edges << Data::View(QString::number(Plasma::Types::LeftEdge), i18nc("left edge", "Left"));
0196     s_edges[i].edge = Plasma::Types::LeftEdge; s_edges[i].alignment = Latte::Types::Center;
0197     s_edges[i].setState(Data::View::IsCreated);
0198 
0199     i++;
0200     s_edges << Data::View(QString::number(Plasma::Types::BottomEdge), i18nc("bottom edge", "Bottom"));
0201     s_edges[i].edge = Plasma::Types::BottomEdge; s_edges[i].alignment = Latte::Types::Center;
0202     s_edges[i].setState(Data::View::IsCreated);
0203 
0204     i++;
0205     s_edges << Data::View(QString::number(Plasma::Types::RightEdge), i18nc("right edge", "Right"));
0206     s_edges[i].edge = Plasma::Types::RightEdge; s_edges[i].alignment = Latte::Types::Center;
0207     s_edges[i].setState(Data::View::IsCreated);
0208 }
0209 
0210 void Views::initAlignments()
0211 {
0212     s_horizontalAlignments.clear();
0213     s_verticalAlignments.clear();
0214 
0215     int i=0; // Left / Top
0216     s_horizontalAlignments << Data::View(QString::number(Latte::Types::Left), i18nc("left alignment", "Left"));
0217     s_horizontalAlignments[i].edge = Plasma::Types::BottomEdge; s_horizontalAlignments[i].alignment = Latte::Types::Left;
0218     s_horizontalAlignments[i].setState(Data::View::IsCreated);
0219 
0220     s_verticalAlignments << Data::View(QString::number(Latte::Types::Top), i18nc("top alignment", "Top"));
0221     s_verticalAlignments[i].edge = Plasma::Types::LeftEdge; s_verticalAlignments[i].alignment = Latte::Types::Top;
0222     s_verticalAlignments[i].setState(Data::View::IsCreated);
0223 
0224     i++; // Center
0225     s_horizontalAlignments << Data::View(QString::number(Latte::Types::Center), i18nc("center alignment", "Center"));
0226     s_horizontalAlignments[i].edge = Plasma::Types::BottomEdge; s_horizontalAlignments[i].alignment = Latte::Types::Center;
0227     s_horizontalAlignments[i].setState(Data::View::IsCreated);
0228 
0229     s_verticalAlignments << s_horizontalAlignments[1];
0230     s_verticalAlignments[i].edge = Plasma::Types::LeftEdge;
0231     s_verticalAlignments[i].setState(Data::View::IsCreated);
0232 
0233     i++; // Right / Bottom
0234     s_horizontalAlignments << Data::View(QString::number(Latte::Types::Right), i18nc("right alignment", "Right"));
0235     s_horizontalAlignments[i].edge = Plasma::Types::BottomEdge; s_horizontalAlignments[i].alignment = Latte::Types::Right;
0236     s_horizontalAlignments[i].setState(Data::View::IsCreated);
0237 
0238     s_verticalAlignments << Data::View(QString::number(Latte::Types::Bottom), i18nc("bottom alignment", "Bottom"));
0239     s_verticalAlignments[i].edge = Plasma::Types::LeftEdge; s_verticalAlignments[i].alignment = Latte::Types::Bottom;
0240     s_verticalAlignments[i].setState(Data::View::IsCreated);
0241 
0242     i++; // Justify
0243     s_horizontalAlignments << Data::View(QString::number(Latte::Types::Justify), i18nc("justify alignment", "Justify"));
0244     s_horizontalAlignments[i].edge = Plasma::Types::BottomEdge; s_horizontalAlignments[i].alignment = Latte::Types::Justify;
0245     s_horizontalAlignments[i].setState(Data::View::IsCreated);
0246 
0247     s_verticalAlignments << s_horizontalAlignments[3];
0248     s_verticalAlignments[i].edge = Plasma::Types::LeftEdge;
0249     s_verticalAlignments[i].setState(Data::View::IsCreated);
0250 }
0251 
0252 Data::ViewsTable Views::edgesChoices(const Data::View &view) const
0253 {
0254     Data::ViewsTable t_edges = s_edges;
0255 
0256     if (view.alignment == Latte::Types::Left) {
0257         t_edges[0].alignment = view.alignment;
0258         t_edges[1].alignment = Latte::Types::Top;
0259         t_edges[2].alignment = view.alignment;
0260         t_edges[3].alignment = Latte::Types::Top;
0261     } else if (view.alignment == Latte::Types::Top) {
0262         t_edges[0].alignment = Latte::Types::Left;
0263         t_edges[1].alignment = view.alignment;
0264         t_edges[2].alignment = Latte::Types::Left;
0265         t_edges[3].alignment = view.alignment;
0266     } else if (view.alignment == Latte::Types::Center
0267                || view.alignment == Latte::Types::Justify) {
0268         t_edges[0].alignment = view.alignment;
0269         t_edges[1].alignment = view.alignment;
0270         t_edges[2].alignment = view.alignment;
0271         t_edges[3].alignment = view.alignment;
0272     } else if (view.alignment == Latte::Types::Right) {
0273         t_edges[0].alignment = view.alignment;
0274         t_edges[1].alignment = Latte::Types::Bottom;
0275         t_edges[2].alignment = view.alignment;
0276         t_edges[3].alignment = Latte::Types::Bottom;
0277     } else if (view.alignment == Latte::Types::Bottom) {
0278         t_edges[0].alignment = Latte::Types::Right;
0279         t_edges[1].alignment = view.alignment;
0280         t_edges[2].alignment = Latte::Types::Right;
0281         t_edges[3].alignment = view.alignment;
0282     }
0283 
0284     t_edges[0].screenEdgeMargin = view.screenEdgeMargin;
0285     t_edges[1].screenEdgeMargin = view.screenEdgeMargin;
0286     t_edges[2].screenEdgeMargin = view.screenEdgeMargin;
0287     t_edges[3].screenEdgeMargin = view.screenEdgeMargin;
0288 
0289     return t_edges;
0290 }
0291 
0292 Data::ViewsTable Views::horizontalAlignmentChoices(const Data::View &view) const
0293 {
0294     Data::ViewsTable t_horizontalAlignments = s_horizontalAlignments;
0295 
0296     t_horizontalAlignments[0].edge = view.edge;
0297     t_horizontalAlignments[1].edge = view.edge;
0298     t_horizontalAlignments[2].edge = view.edge;
0299     t_horizontalAlignments[3].edge = view.edge;
0300 
0301     t_horizontalAlignments[0].screenEdgeMargin = view.screenEdgeMargin;
0302     t_horizontalAlignments[1].screenEdgeMargin = view.screenEdgeMargin;
0303     t_horizontalAlignments[2].screenEdgeMargin = view.screenEdgeMargin;
0304     t_horizontalAlignments[3].screenEdgeMargin = view.screenEdgeMargin;
0305 
0306     return t_horizontalAlignments;
0307 }
0308 
0309 Data::ViewsTable Views::verticalAlignmentChoices(const Data::View &view) const
0310 {
0311     Data::ViewsTable t_verticalAlignments = s_verticalAlignments;
0312 
0313     t_verticalAlignments[0].edge = view.edge;
0314     t_verticalAlignments[1].edge = view.edge;
0315     t_verticalAlignments[2].edge = view.edge;
0316     t_verticalAlignments[3].edge = view.edge;
0317 
0318     t_verticalAlignments[0].screenEdgeMargin = view.screenEdgeMargin;
0319     t_verticalAlignments[1].screenEdgeMargin = view.screenEdgeMargin;
0320     t_verticalAlignments[2].screenEdgeMargin = view.screenEdgeMargin;
0321     t_verticalAlignments[3].screenEdgeMargin = view.screenEdgeMargin;
0322 
0323     return t_verticalAlignments;
0324 }
0325 
0326 bool Views::containsCurrentName(const QString &name) const
0327 {
0328     return m_viewsTable.containsName(name);
0329 }
0330 
0331 void Views::resetData()
0332 {
0333     clear();
0334     setOriginalData(o_viewsTable);
0335 }
0336 
0337 void Views::appendTemporaryView(const Latte::Data::View &view)
0338 {
0339     //int newRow = m_layoutsTable.sortedPosForName(layout.name);
0340 
0341     beginInsertRows(QModelIndex(), m_viewsTable.rowCount(), m_viewsTable.rowCount());
0342     m_viewsTable.appendTemporaryView(view);
0343     endInsertRows();
0344 
0345     emit rowsInserted();
0346 }
0347 
0348 void Views::removeView(const QString &id)
0349 {
0350     int index = m_viewsTable.indexOf(id);
0351 
0352     if (index >= 0) {
0353         removeRows(index, 1);
0354         emit rowsRemoved();
0355     }
0356 }
0357 
0358 bool Views::removeRows(int row, int count, const QModelIndex &parent)
0359 {
0360     Q_UNUSED(parent)
0361 
0362     int firstRow = row;
0363     int lastRow = row+count-1;
0364 
0365     if (count > 0 && m_viewsTable.rowExists(firstRow) && (m_viewsTable.rowExists(lastRow))) {
0366         beginRemoveRows(QModelIndex(), firstRow, lastRow);
0367         for(int i=0; i<count; ++i) {
0368             m_viewsTable.remove(firstRow);
0369         }
0370         endRemoveRows();
0371         return true;
0372     }
0373 
0374     return false;
0375 }
0376 
0377 bool Views::isVertical(const Plasma::Types::Location &location) const
0378 {
0379     return (location == Plasma::Types::LeftEdge || location == Plasma::Types::RightEdge);
0380 }
0381 
0382 QString Views::viewForSubContainment(const QString &sid)
0383 {
0384     for(int i=0; i<m_viewsTable.rowCount(); ++i) {
0385        if (m_viewsTable[i].hasSubContainment(sid)) {
0386            return m_viewsTable[i].id;
0387        }
0388     }
0389 
0390     return QString();
0391 }
0392 
0393 void Views::updateActiveStatesBasedOn(const CentralLayout *layout)
0394 {
0395     if (!layout) {
0396         return;
0397     }
0398 
0399     QVector<int> roles;
0400     roles << Qt::DisplayRole;
0401     roles << Qt::UserRole;
0402     roles << ISCHANGEDROLE;
0403     roles << ISACTIVEROLE;
0404     roles << HASCHANGEDVIEWROLE;
0405 
0406     for (int i=0; i<m_viewsTable.rowCount(); ++i) {
0407         uint viewid = m_viewsTable[i].id.toUInt();
0408         auto view = layout->viewForContainment(viewid);
0409 
0410         bool currentactivestate = (view != nullptr);
0411 
0412         if (currentactivestate != m_viewsTable[i].isActive) {
0413             m_viewsTable[i].isActive = currentactivestate;
0414             emit dataChanged(this->index(i, IDCOLUMN), this->index(i, SUBCONTAINMENTSCOLUMN), roles);
0415         }
0416     }
0417 }
0418 
0419 Latte::Data::Screen Views::screenData(const QString &viewId) const
0420 {
0421     int row = rowForId(viewId);
0422 
0423     if (row < 0) {
0424         return Latte::Data::Screen();
0425     }
0426 
0427    // QString primaryid = QString::number(m_corona->screenPool()->primaryScreenId());
0428     QString explicitid = QString::number(m_viewsTable[row].screen);
0429 
0430     Data::Screen scrData = s_screens[0]; //default
0431 
0432     if (m_viewsTable[row].onPrimary || (m_viewsTable[row].screensGroup == Latte::Types::AllScreensGroup)) {
0433         scrData = s_screens[0]; //primary, allscreens
0434     } else if (m_viewsTable[row].screensGroup == Latte::Types::AllSecondaryScreensGroup) {
0435         scrData = s_screens[2]; //allsecondaryscreens
0436     } else if (!m_viewsTable[row].onPrimary && s_screens.containsId(explicitid)) {
0437         scrData = s_screens[explicitid]; //explicit
0438     }
0439 
0440     if (m_viewsTable[row].screensGroup == Latte::Types::AllScreensGroup) {
0441         scrData.id = QString::number(Data::Screen::ONALLSCREENSID);
0442     } else if (m_viewsTable[row].screensGroup == Latte::Types::AllSecondaryScreensGroup) {
0443         scrData.id = QString::number(Data::Screen::ONALLSECONDARYSCREENSID);
0444     }
0445 
0446     return scrData;
0447 }
0448 
0449 Latte::Data::ViewsTable Views::alteredViews() const
0450 {
0451     Latte::Data::ViewsTable views;
0452 
0453     for(int i=0; i<rowCount(); ++i) {
0454         QString currentId = m_viewsTable[i].id;
0455 
0456         if (!o_viewsTable.containsId(currentId)
0457             || m_viewsTable[currentId] != o_viewsTable[currentId]) {
0458             views << m_viewsTable[i];
0459         }
0460     }
0461 
0462     return views;
0463 }
0464 
0465 Latte::Data::ViewsTable Views::newViews() const
0466 {
0467     Latte::Data::ViewsTable views;
0468 
0469     for(int i=0; i<rowCount(); ++i) {
0470         QString currentId = m_viewsTable[i].id;
0471 
0472         if (!o_viewsTable.containsId(currentId)) {
0473             views << m_viewsTable[i];
0474         }
0475     }
0476 
0477     return views;
0478 }
0479 
0480 void Views::clearErrorsAndWarnings()
0481 {
0482     for(int i=0; i<m_viewsTable.rowCount(); ++i) {
0483         m_viewsTable[i].errors = 0;
0484         m_viewsTable[i].warnings = 0;
0485     }
0486 
0487     QVector<int> roles;
0488     roles << Qt::DisplayRole;
0489     roles << Qt::UserRole;
0490     roles << ERRORSROLE;
0491     roles << WARNINGSROLE;
0492 
0493     emit dataChanged(this->index(0, IDCOLUMN), this->index(m_viewsTable.rowCount()-1, SUBCONTAINMENTSCOLUMN), roles);
0494 }
0495 
0496 void Views::populateScreens()
0497 {
0498     s_screens.clear();
0499     Data::Screen primary(QString::number(Data::Screen::ONPRIMARYID), i18n(" - On Primary Screen - "));
0500     Data::Screen allscreens(QString::number(Data::Screen::ONALLSCREENSID), i18n(" - On All Screens - "));
0501     Data::Screen allsecscreens(QString::number(Data::Screen::ONALLSECONDARYSCREENSID), i18n(" - On All Secondary Screens - "));
0502 
0503     primary.isActive = true;    
0504     allscreens.isActive = true;
0505     allsecscreens.isActive = (m_corona->screenPool()->secondaryScreenIds().count() > 0);
0506 
0507     s_screens << primary;
0508     s_screens << allscreens;
0509     s_screens << allsecscreens;
0510     int defcount = s_screens.rowCount();
0511     s_screens << m_corona->screenPool()->screensTable();
0512 
0513     for (int i=defcount; i<s_screens.rowCount(); ++i) {
0514         s_screens[i].isActive = m_corona->screenPool()->isScreenActive(s_screens[i].id.toInt());
0515     }
0516 }
0517 
0518 void Views::updateCurrentView(QString currentViewId, Latte::Data::View &view)
0519 {
0520     if (!m_viewsTable.containsId(currentViewId)) {
0521         return;
0522     }
0523 
0524     int currentrow = m_viewsTable.indexOf(currentViewId);
0525     m_viewsTable[currentrow] = view;
0526 
0527     QVector<int> roles;
0528     roles << Qt::DisplayRole;
0529     roles << Qt::UserRole;
0530     roles << ISCHANGEDROLE;
0531     roles << ISACTIVEROLE;
0532     roles << HASCHANGEDVIEWROLE;
0533     roles << ISMOVEORIGINROLE;
0534     roles << ERRORSROLE;
0535     roles << WARNINGSROLE;
0536 
0537     emit dataChanged(this->index(currentrow, IDCOLUMN), this->index(currentrow, SUBCONTAINMENTSCOLUMN), roles);
0538 }
0539 
0540 void Views::setOriginalView(QString currentViewId, Latte::Data::View &view)
0541 {
0542     if (!m_viewsTable.containsId(currentViewId)) {
0543         return;
0544     }
0545 
0546     int currentrow = m_viewsTable.indexOf(currentViewId);
0547     o_viewsTable << view;
0548     m_viewsTable[currentrow] = view;
0549 
0550     QVector<int> roles;
0551     roles << Qt::DisplayRole;
0552     roles << Qt::UserRole;
0553     roles << ISCHANGEDROLE;
0554     roles << ISACTIVEROLE;
0555     roles << HASCHANGEDVIEWROLE;
0556 
0557     emit dataChanged(this->index(currentrow, IDCOLUMN), this->index(currentrow, SUBCONTAINMENTSCOLUMN), roles);
0558 }
0559 
0560 void Views::setOriginalData(Latte::Data::ViewsTable &data)
0561 {
0562     clear();
0563 
0564     beginInsertRows(QModelIndex(), 0, data.rowCount() - 1);
0565     o_viewsTable = data;
0566     m_viewsTable = data;
0567     endInsertRows();
0568 
0569     emit rowsInserted();
0570 }
0571 
0572 QVariant Views::headerData(int section, Qt::Orientation orientation, int role) const
0573 {
0574     if (orientation != Qt::Horizontal) {
0575         return QAbstractTableModel::headerData(section, orientation, role);
0576     }
0577 
0578     if (role == Qt::FontRole) {
0579         QFont font = qvariant_cast<QFont>(QAbstractTableModel::headerData(section, orientation, role));
0580         font.setBold(true);
0581         return font;
0582     }
0583 
0584     switch(section) {
0585     case IDCOLUMN:
0586         if (role == Qt::DisplayRole) {
0587             return QString("#");
0588         }
0589         break;
0590     case NAMECOLUMN:
0591         if (role == Qt::DisplayRole) {
0592             return QString(i18n("Name"));
0593         }
0594         break;
0595     case SCREENCOLUMN:
0596         if (role == Qt::DisplayRole) {
0597             return QString(i18n("Screen"));
0598         }
0599         /*  } else if (role == Qt::DecorationRole) {
0600             return QIcon::fromTheme("desktop");
0601         }*/
0602         break;
0603     case EDGECOLUMN:
0604         if (role == Qt::DisplayRole) {
0605             return QString(i18nc("screen edge", "Edge"));
0606         }
0607         /*  } else if (role == Qt::DecorationRole) {
0608             return QIcon::fromTheme("transform-move");
0609         }*/
0610         break;
0611     case ALIGNMENTCOLUMN:
0612         if (role == Qt::DisplayRole) {
0613             return QString(i18n("Alignment"));
0614         }
0615         /*} else if (role == Qt::DecorationRole) {
0616             return QIcon::fromTheme("format-justify-center");
0617         }*/
0618         break;
0619     case SUBCONTAINMENTSCOLUMN:
0620         if (role == Qt::DisplayRole) {
0621             return QString(i18n("Includes"));
0622         }
0623     default:
0624         break;
0625     };
0626 
0627     return QAbstractTableModel::headerData(section, orientation, role);
0628 }
0629 
0630 Qt::ItemFlags Views::flags(const QModelIndex &index) const
0631 {
0632     const int column = index.column();
0633     const int row = index.row();
0634 
0635     auto flags = QAbstractTableModel::flags(index);
0636 
0637     if (column == NAMECOLUMN
0638             || column == SCREENCOLUMN
0639             || column == EDGECOLUMN
0640             || column == ALIGNMENTCOLUMN) {
0641         flags |= Qt::ItemIsEditable;
0642     }
0643 
0644     return flags;
0645 }
0646 
0647 bool Views::setData(const QModelIndex &index, const QVariant &value, int role)
0648 {
0649     const int row = index.row();
0650     const int column = index.column();
0651 
0652     if (!m_viewsTable.rowExists(row) || column<0 || column >= SUBCONTAINMENTSCOLUMN) {
0653         return false;
0654     }
0655 
0656     QVector<int> roles;
0657     roles << role;
0658     roles << ISCHANGEDROLE;
0659     roles << HASCHANGEDVIEWROLE;
0660     roles << SORTINGROLE;
0661 
0662     if (role != Qt::DisplayRole) {
0663         roles << Qt::DisplayRole;
0664     }
0665 
0666     //! specific roles to each independent cell
0667     switch (column) {
0668     case NAMECOLUMN:
0669         if (role == Qt::UserRole || role == Qt::EditRole) {
0670             if (m_viewsTable[row].name == value.toString()) {
0671                 return false;
0672             }
0673 
0674             m_viewsTable[row].name = value.toString();
0675             emit dataChanged(index, index, roles);
0676         }
0677         break;
0678     case SCREENCOLUMN:
0679         if (role == Qt::UserRole) {
0680             int screen = value.toString().toInt();
0681             bool onprimary = (screen == Latte::Data::Screen::ONPRIMARYID);
0682             bool onallscreens = (screen == Latte::Data::Screen::ONALLSCREENSID);
0683             bool onallsecscreens = (screen == Latte::Data::Screen::ONALLSECONDARYSCREENSID);
0684 
0685             if (onprimary) {
0686                 m_viewsTable[row].onPrimary = true;
0687                 m_viewsTable[row].screensGroup = Latte::Types::SingleScreenGroup;
0688             } else if (onallscreens) {
0689                 m_viewsTable[row].onPrimary = true;
0690                 m_viewsTable[row].screensGroup = Latte::Types::AllScreensGroup;
0691             } else if (onallsecscreens) {
0692                 m_viewsTable[row].onPrimary = false;
0693                 m_viewsTable[row].screensGroup = Latte::Types::AllSecondaryScreensGroup;
0694             } else {
0695                 m_viewsTable[row].onPrimary = false;
0696                 m_viewsTable[row].screensGroup = Latte::Types::SingleScreenGroup;
0697                 m_viewsTable[row].screen = screen;
0698             }
0699 
0700             if (onprimary || onallscreens || onallsecscreens) {
0701                 if (o_viewsTable.containsId(m_viewsTable[row].id)) {
0702                     //! we need to update screen also in order to not show that there are changes even though
0703                     //! they are not any
0704                     m_viewsTable[row].screen = o_viewsTable[m_viewsTable[row].id].screen;
0705                 }
0706             }
0707 
0708             emit dataChanged(this->index(row, NAMECOLUMN), this->index(row, ALIGNMENTCOLUMN), roles);
0709         }
0710         break;
0711     case EDGECOLUMN:
0712         if (role == Qt::UserRole) {
0713             Plasma::Types::Location edge = static_cast<Plasma::Types::Location>(value.toString().toInt());
0714 
0715             if (m_viewsTable[row].edge == edge) {
0716                 return false;
0717             }
0718 
0719             Plasma::Types::Location previousEdge = m_viewsTable[row].edge;
0720             m_viewsTable[row].edge = edge;
0721             emit dataChanged(index, index, roles);
0722 
0723             bool previousFactor = isVertical(previousEdge);
0724             bool currentFactor = isVertical(edge);
0725 
0726             if (previousFactor != currentFactor) {
0727                 if (m_viewsTable[row].alignment == Latte::Types::Left) {
0728                     m_viewsTable[row].alignment = Latte::Types::Top;
0729                 } else if (m_viewsTable[row].alignment == Latte::Types::Right) {
0730                     m_viewsTable[row].alignment = Latte::Types::Bottom;
0731                 } else if (m_viewsTable[row].alignment == Latte::Types::Top) {
0732                     m_viewsTable[row].alignment = Latte::Types::Left;
0733                 } else if (m_viewsTable[row].alignment == Latte::Types::Bottom) {
0734                     m_viewsTable[row].alignment = Latte::Types::Right;
0735                 }
0736 
0737                 emit dataChanged(this->index(row, NAMECOLUMN), this->index(row, ALIGNMENTCOLUMN), roles);
0738             }
0739 
0740             return true;
0741         }
0742         break;
0743     case ALIGNMENTCOLUMN:
0744         if (role == Qt::UserRole)  {
0745             int alignment = value.toString().toInt();
0746 
0747             if (m_viewsTable[row].alignment == alignment) {
0748                 return false;
0749             }
0750 
0751             m_viewsTable[row].alignment = static_cast<Latte::Types::Alignment>(alignment);
0752             emit dataChanged(this->index(row, NAMECOLUMN), this->index(row, ALIGNMENTCOLUMN), roles);
0753             return true;
0754         }
0755         break;
0756     };
0757 
0758     return false;
0759 }
0760 
0761 
0762 QVariant Views::data(const QModelIndex &index, int role) const
0763 {
0764     const int row = index.row();
0765     int column = index.column();
0766     //bool isNewLayout = !o_layoutsTable.containsId(m_layoutsTable[row].id);
0767 
0768     if (!m_viewsTable.rowExists(row)) {
0769         return QVariant{};
0770     }
0771 
0772     bool isNewView = !o_viewsTable.containsId(m_viewsTable[row].id);
0773     QString origviewid = !isNewView ? m_viewsTable[row].id : "";
0774 
0775     if (role == IDROLE) {
0776         return (m_viewsTable[row].state() == Data::View::IsCreated ? m_viewsTable[row].id : "#");
0777     } else if (role == ISACTIVEROLE) {
0778         return m_viewsTable[row].isActive;
0779     } else if (role == CHOICESROLE) {
0780         if (column == SCREENCOLUMN) {
0781             QVariant screensVariant;
0782 
0783             Latte::Data::ScreensTable currentScreens = s_screens;
0784 
0785             if (!m_viewsTable[row].onPrimary && !currentScreens.containsId(QString::number(m_viewsTable[row].screen))) {
0786                 Data::Screen explicitScr(QString::number(m_viewsTable[row].screen),
0787                                          i18nc("unknown screen", "Unknown: [%1]", explicitScr.id));
0788                 currentScreens.insertBasedOnId(explicitScr);
0789             }
0790 
0791             screensVariant.setValue<Latte::Data::ScreensTable>(currentScreens);
0792             return screensVariant;
0793         } else if (column == EDGECOLUMN) {
0794             QVariant edgesVariant;
0795             edgesVariant.setValue<Latte::Data::ViewsTable>(edgesChoices(m_viewsTable[row]));
0796             return edgesVariant;
0797         } else if (column == ALIGNMENTCOLUMN) {
0798             QVariant alignmentsVariant;
0799 
0800             if (isVertical(m_viewsTable[row].edge)) {
0801                 alignmentsVariant.setValue<Latte::Data::ViewsTable>(verticalAlignmentChoices(m_viewsTable[row]));
0802             } else {
0803                 alignmentsVariant.setValue<Latte::Data::ViewsTable>(horizontalAlignmentChoices(m_viewsTable[row]));
0804             }
0805 
0806             return alignmentsVariant;
0807         }
0808     } else if (role == HASCHANGEDVIEWROLE) {
0809         return (isNewView || (m_viewsTable[row] != o_viewsTable[origviewid]));
0810     } else if (role == SCREENROLE) {
0811         QVariant scrVariant;
0812         Latte::Data::Screen scrdata = screenData(m_viewsTable[row].id);
0813         scrVariant.setValue<Latte::Data::Screen>(scrdata);
0814         return scrVariant;
0815     } else if (role == VIEWROLE) {
0816         QVariant viewVariant;
0817         viewVariant.setValue<Latte::Data::View>(m_viewsTable[row]);
0818         return viewVariant;
0819     } else if (role == ISMOVEORIGINROLE) {
0820         return m_viewsTable[row].isMoveOrigin;
0821     } else if (role == ERRORSROLE) {
0822         return m_viewsTable[row].errors;
0823     } else if (role == WARNINGSROLE) {
0824         return m_viewsTable[row].warnings;
0825     }
0826 
0827     if (role == Qt::TextAlignmentRole && column != NAMECOLUMN){
0828         return static_cast<Qt::Alignment::Int>(Qt::AlignHCenter | Qt::AlignVCenter);
0829     }
0830 
0831     switch (column) {
0832     case IDCOLUMN:
0833         if (role == Qt::DisplayRole){
0834             return (m_viewsTable[row].state() == Data::View::IsCreated ? m_viewsTable[row].id : "#");
0835         } else if (role == Qt::UserRole) {
0836             return m_viewsTable[row].id;
0837         } else if (role == ISCHANGEDROLE) {
0838             return (isNewView || (m_viewsTable[row].id != o_viewsTable[origviewid].id));
0839         }  else if (role == SORTINGROLE) {
0840             int fsta = sortingFactorForState(m_viewsTable[row]);
0841             int fscr = sortingFactorForScreen(m_viewsTable[row]);
0842             int fedg = sortingFactorForEdge(m_viewsTable[row]);
0843             int fali = sortingFactorForAlignment(m_viewsTable[row]);
0844 
0845             int priority = (fsta * HIGHESTPRIORITY);
0846             return sortableText(priority, m_viewsTable[row].id);
0847         }
0848         break;
0849     case NAMECOLUMN:
0850         if (role == Qt::DisplayRole || role == Qt::UserRole || role == Qt::EditRole){
0851             return m_viewsTable[row].name;
0852         } else if (role == ISCHANGEDROLE) {
0853             return (isNewView || (m_viewsTable[row].name != o_viewsTable[origviewid].name));
0854         } else if (role == SORTINGROLE) {
0855             int fsta = sortingFactorForState(m_viewsTable[row]);
0856             int fscr = sortingFactorForScreen(m_viewsTable[row]);
0857             int fedg = sortingFactorForEdge(m_viewsTable[row]);
0858             int fali = sortingFactorForAlignment(m_viewsTable[row]);
0859 
0860             int priority = (fsta * HIGHESTPRIORITY);
0861             return sortableText(priority, m_viewsTable[row].name);
0862         }
0863         break;
0864     case SCREENCOLUMN:
0865         if (role == Qt::DisplayRole){
0866             if (m_viewsTable[row].screensGroup == Latte::Types::SingleScreenGroup &&  m_viewsTable[row].onPrimary) {
0867                 return i18nc("primary screen", "Primary");
0868             } else if (m_viewsTable[row].screensGroup == Latte::Types::AllScreensGroup) {
0869                 return i18n("All Screens");
0870             } else if (m_viewsTable[row].screensGroup == Latte::Types::AllSecondaryScreensGroup) {
0871                 return i18n("Secondary Screens");
0872             } else {
0873                 QString scrId = QString::number(m_viewsTable[row].screen);
0874                 if (s_screens.containsId(scrId)) {
0875                     return s_screens[scrId].name;
0876                 } else {
0877                     return i18nc("unknown screen", "Unknown: [%1]", scrId);
0878                 }
0879             }
0880         } else if (role == Qt::UserRole) {
0881             if (m_viewsTable[row].screensGroup == Latte::Types::SingleScreenGroup &&  m_viewsTable[row].onPrimary) {
0882                 return QString::number(Data::Screen::ONPRIMARYID);
0883             } else if (m_viewsTable[row].screensGroup == Latte::Types::AllScreensGroup) {
0884                 return QString::number(Data::Screen::ONALLSCREENSID);
0885             } else if (m_viewsTable[row].screensGroup == Latte::Types::AllSecondaryScreensGroup) {
0886                 return QString::number(Data::Screen::ONALLSECONDARYSCREENSID);
0887             } else {
0888                 return QString::number(m_viewsTable[row].screen);
0889             }
0890         } else if (role == ISCHANGEDROLE) {
0891             return (isNewView
0892                     || (m_viewsTable[row].onPrimary != o_viewsTable[origviewid].onPrimary)
0893                     || (!m_viewsTable[row].onPrimary && m_viewsTable[row].screen != o_viewsTable[origviewid].screen));
0894         } else if (role == SORTINGROLE) {
0895             int fsta = sortingFactorForState(m_viewsTable[row]);
0896             int fscr = sortingFactorForScreen(m_viewsTable[row]);
0897             int fedg = sortingFactorForEdge(m_viewsTable[row]);
0898             int fali = sortingFactorForAlignment(m_viewsTable[row]);
0899 
0900             int priority = (fsta * HIGHESTPRIORITY) + (fscr * HIGHPRIORITY) + (fedg * MEDIUMPRIORITY) + (fali * NORMALPRIORITY);
0901             return priority;
0902         }
0903         break;
0904     case EDGECOLUMN:
0905         if (role == Qt::DisplayRole){
0906             if (m_viewsTable[row].edge == Plasma::Types::BottomEdge) {
0907                 return i18nc("bottom location", "Bottom");
0908             } else if (m_viewsTable[row].edge == Plasma::Types::TopEdge) {
0909                 return i18nc("top location", "Top");
0910             } else if (m_viewsTable[row].edge == Plasma::Types::LeftEdge) {
0911                 return i18nc("left location", "Left");
0912             } else if (m_viewsTable[row].edge == Plasma::Types::RightEdge) {
0913                 return i18nc("right location", "Right");
0914             }
0915 
0916             return i18nc("unknown location", "Unknown");
0917         } else if (role == Qt::UserRole) {
0918             return QString::number(m_viewsTable[row].edge);
0919         } else if (role == ISCHANGEDROLE) {
0920             return (isNewView || (m_viewsTable[row].edge != o_viewsTable[origviewid].edge));
0921         } else if (role == SORTINGROLE) {
0922             int fsta = sortingFactorForState(m_viewsTable[row]);
0923             int fscr = sortingFactorForScreen(m_viewsTable[row]);
0924             int fedg = sortingFactorForEdge(m_viewsTable[row]);
0925             int fali = sortingFactorForAlignment(m_viewsTable[row]);
0926 
0927             int priority = (fsta * HIGHESTPRIORITY) + (fedg * HIGHPRIORITY) + (fscr * MEDIUMPRIORITY) + (fali * NORMALPRIORITY);
0928             return priority;
0929         }
0930         break;
0931     case ALIGNMENTCOLUMN:
0932         if (role == Qt::DisplayRole){
0933             if (m_viewsTable[row].alignment == Latte::Types::Center) {
0934                 return i18nc("center alignment", "Center");
0935             } else if (m_viewsTable[row].alignment == Latte::Types::Left) {
0936                 return i18nc("left alignment", "Left");
0937             } else if (m_viewsTable[row].alignment == Latte::Types::Right) {
0938                 return i18nc("right alignment", "Right");
0939             } else if (m_viewsTable[row].alignment == Latte::Types::Top) {
0940                 return i18nc("top alignment", "Top");
0941             } else if (m_viewsTable[row].alignment == Latte::Types::Bottom) {
0942                 return i18nc("bottom alignment", "Bottom");
0943             } else if (m_viewsTable[row].alignment == Latte::Types::Justify) {
0944                 return i18nc("justify alignment", "Justify");
0945             }
0946 
0947             return i18nc("unknown alignment", "Unknown");
0948         } else if (role == Qt::UserRole) {
0949             return QString::number(m_viewsTable[row].alignment);
0950         } else if (role == ISCHANGEDROLE) {
0951             return (isNewView || (m_viewsTable[row].alignment != o_viewsTable[origviewid].alignment));
0952         } else if (role == SORTINGROLE) {
0953             int fsta = sortingFactorForState(m_viewsTable[row]);
0954             int fscr = sortingFactorForScreen(m_viewsTable[row]);
0955             int fedg = sortingFactorForEdge(m_viewsTable[row]);
0956             int fali = sortingFactorForAlignment(m_viewsTable[row]);
0957 
0958             int priority = (fsta * HIGHESTPRIORITY) + (fali * HIGHPRIORITY) + (fscr * MEDIUMPRIORITY) + (fedg * NORMALPRIORITY);
0959             return priority;
0960         }
0961         break;
0962     case SUBCONTAINMENTSCOLUMN:
0963         if (role == Qt::DisplayRole){
0964             if (m_viewsTable[row].subcontainments.rowCount()>0) {
0965                 QString result = "{";
0966 
0967                 for (int i=0; i<m_viewsTable[row].subcontainments.rowCount(); ++i) {
0968                     if (i>0) {
0969                         result += " ";
0970                     }
0971                     result += (m_viewsTable[row].state() == Data::View::IsCreated ? m_viewsTable[row].subcontainments[i].id : TEMPIDDISPLAY);
0972 
0973                     if (i<m_viewsTable[row].subcontainments.rowCount()-1) {
0974                         result += ",";
0975                     }
0976                 }
0977 
0978                 result += "}";
0979                 return result;
0980             }
0981 
0982             return QString();
0983         } else if (role == ISCHANGEDROLE) {
0984             return (isNewView || (m_viewsTable[row].subcontainments != o_viewsTable[origviewid].subcontainments));
0985         } else if (role == SORTINGROLE) {
0986             int fsta = sortingFactorForState(m_viewsTable[row]);
0987             int fscr = sortingFactorForScreen(m_viewsTable[row]);
0988             int fedg = sortingFactorForEdge(m_viewsTable[row]);
0989             int fali = sortingFactorForAlignment(m_viewsTable[row]);
0990             int fsub = sortingFactorForSubContainments(m_viewsTable[row]);
0991 
0992             int priority = (fsta * HIGHESTPRIORITY) + (fsub * HIGHPRIORITY) + (fscr * MEDIUMPRIORITY) + (fedg * NORMALPRIORITY);
0993             return priority;
0994         }
0995     };
0996 
0997     return QVariant{};
0998 }
0999 
1000 }
1001 }
1002 }