File indexing completed on 2024-04-21 05:31:00

0001 /*
0002     SPDX-FileCopyrightText: 2021 Michail Vourlakos <mvourlakos@gmail.com>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 #include "singleoptiondelegate.h"
0007 
0008 // local
0009 #include "custommenuitemwidget.h"
0010 #include "../viewsmodel.h"
0011 #include "../../generic/generictools.h"
0012 #include "../../../data/genericbasictable.h"
0013 #include "../../../data/screendata.h"
0014 
0015 // Qt
0016 #include <QApplication>
0017 #include <QMenu>
0018 #include <QPushButton>
0019 #include <QTextDocument>
0020 #include <QWidgetAction>
0021 
0022 #define PRESSEDPROPERTY "PRESSED"
0023 
0024 namespace Latte {
0025 namespace Settings {
0026 namespace View {
0027 namespace Delegate {
0028 
0029 SingleOption::SingleOption(QObject *parent)
0030     : SingleText(parent)
0031 {
0032 }
0033 
0034 QWidget *SingleOption::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
0035 {
0036     const int row = index.row();
0037     const int column = index.column();
0038 
0039     QPushButton *button = new QPushButton(parent);
0040 
0041     QMenu *menu = new QMenu(button);
0042     button->setMenu(menu);
0043     menu->setMinimumWidth(option.rect.width());
0044 
0045     bool isViewActive = index.data(Model::Views::ISACTIVEROLE).toBool();
0046 
0047     QString currentChoice = index.data(Qt::UserRole).toString();
0048 
0049     Latte::Data::GenericBasicTable choices;
0050     QStringList activeChoices;
0051 
0052     Latte::Data::ScreensTable screens;
0053     Latte::Data::ViewsTable views; //views are used as examples for edges and alignments
0054 
0055     if (column == Model::Views::SCREENCOLUMN) {
0056         screens = index.data(Model::Views::CHOICESROLE).value<Latte::Data::ScreensTable>();
0057 
0058         for (int i=0; i<screens.rowCount(); ++i) {
0059             choices << Latte::Data::Generic(screens[i].id, screens[i].name);
0060 
0061             if (screens[i].isActive) {
0062                 activeChoices << screens[i].id;
0063             }
0064         }
0065     } else {
0066         views = index.data(Model::Views::CHOICESROLE).value<Latte::Data::ViewsTable>();
0067 
0068         for (int i=0; i<views.rowCount(); ++i) {
0069             choices << Latte::Data::Generic(views[i].id, views[i].name);
0070         }
0071     }
0072 
0073     for (int i=0; i<choices.rowCount(); ++i) {
0074         QWidgetAction *action = new QWidgetAction(menu);
0075         action->setText(choices[i].name);
0076         action->setData(choices[i].id);
0077 
0078         if (choices[i].id == currentChoice) {
0079             action->setCheckable(true);
0080             action->setChecked(true);
0081         }
0082 
0083         if (activeChoices.contains(choices[i].id)) {
0084             QFont font = action->font();
0085             font.setBold(true);
0086             action->setFont(font);
0087         }
0088 
0089         connect(action, &QAction::triggered, this, [this, button, menu, action](bool checked) {
0090             menu->setProperty(PRESSEDPROPERTY, action->data());
0091             button->clearFocus();
0092         });
0093 
0094         Settings::View::Widget::CustomMenuItemWidget *optioncustomwidget = new Settings::View::Widget::CustomMenuItemWidget(action, menu);
0095 
0096         if (column == Model::Views::SCREENCOLUMN) {
0097             optioncustomwidget->setScreen(screens[i]);
0098         } else {
0099             Latte::Data::Screen viewscreen = index.data(Model::Views::SCREENROLE).value<Latte::Data::Screen>();
0100             optioncustomwidget->setScreen(viewscreen);
0101             optioncustomwidget->setView(views[i]);
0102         }
0103 
0104         action->setDefaultWidget(optioncustomwidget);
0105         menu->addAction(action);
0106     }
0107 
0108     return button;
0109 }
0110 
0111 void SingleOption::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
0112 {
0113     editor->setGeometry(option.rect);
0114 }
0115 
0116 void SingleOption::setEditorData(QWidget *editor, const QModelIndex &index) const
0117 {
0118     updateButton(editor, index.data(Qt::DisplayRole).toString());
0119 }
0120 
0121 bool SingleOption::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option,
0122                                const QModelIndex &index)
0123 {
0124     Q_ASSERT(event);
0125     Q_ASSERT(model);
0126 
0127     return QStyledItemDelegate::editorEvent(event, model, option, index);
0128 }
0129 
0130 void SingleOption::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
0131 {
0132     QPushButton *button = static_cast<QPushButton *>(editor);
0133     QMenu *menu = button->menu();
0134 
0135     if (menu->property(PRESSEDPROPERTY).toString().isEmpty()) {
0136         return;
0137     }
0138 
0139     model->setData(index, menu->property(PRESSEDPROPERTY), Qt::UserRole);
0140     updateButton(editor, index.data(Qt::DisplayRole).toString());
0141 }
0142 
0143 void SingleOption::updateButton(QWidget *editor, const QString &text) const
0144 {
0145     QPushButton *button = static_cast<QPushButton *>(editor);
0146     button->setText(text);
0147 }
0148 
0149 void SingleOption::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
0150 {
0151     QStyleOptionViewItem myOptions = option;
0152     //! Remove the focus dotted lines
0153     myOptions.state = (myOptions.state & ~QStyle::State_HasFocus);
0154     myOptions.text = index.model()->data(index, Qt::DisplayRole).toString();
0155     myOptions.displayAlignment = static_cast<Qt::Alignment>(index.model()->data(index, Qt::TextAlignmentRole).toInt());
0156 
0157     bool isActive = index.data(Model::Views::ISACTIVEROLE).toBool();
0158     bool isMoveOrigin = index.data(Model::Views::ISMOVEORIGINROLE).toBool();
0159     bool isChanged = index.data(Model::Views::ISCHANGEDROLE).toBool() || isMoveOrigin;
0160 
0161     float textopacity = 1.0;
0162 
0163     if (isActive) {
0164         myOptions.text = "<b>" + myOptions.text + "</b>";
0165     }
0166 
0167     if (isChanged) {
0168         myOptions.text = "<i>" + myOptions.text + "</i>";
0169     }
0170 
0171     if (isMoveOrigin) {
0172         textopacity = 0.25;
0173     }
0174 
0175     Latte::drawBackground(painter, option);
0176     Latte::drawFormattedText(painter, myOptions, textopacity);
0177 }
0178 
0179 }
0180 }
0181 }
0182 }