1 /*
2 * SPDX-FileCopyrightText: 2014 Andreas Cord-Landwehr <cordlandwehr@kde.org>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5 */
6
7 #include "nodetypesdelegate.h"
8 #include "libgraphtheory/nodetype.h"
9 #include "libgraphtheory/dialogs/nodetypeproperties.h"
10 #include "libgraphtheory/models/nodetypemodel.h"
11 #include <KColorButton>
12 #include <KLocalizedString>
13 #include <QApplication>
14 #include <QAbstractItemView>
15 #include <QDebug>
16 #include <QLabel>
17 #include <QLineEdit>
18 #include <QPainter>
19 #include <QPointer>
20 #include <QPushButton>
21 #include <QToolButton>
22
23 using namespace GraphTheory;
24
NodeTypesDelegate(QAbstractItemView * parent)25 NodeTypesDelegate::NodeTypesDelegate(QAbstractItemView* parent)
26 : KWidgetItemDelegate(parent, parent->viewport())
27 {
28
29 }
30
~NodeTypesDelegate()31 NodeTypesDelegate::~NodeTypesDelegate()
32 {
33
34 }
35
paint(QPainter * painter,const QStyleOptionViewItem & option,const QModelIndex & index) const36 void NodeTypesDelegate::paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
37 {
38 if (!index.isValid()) {
39 return;
40 }
41 QApplication::style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter, nullptr);
42 }
43
sizeHint(const QStyleOptionViewItem & option,const QModelIndex & index) const44 QSize NodeTypesDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
45 {
46 Q_UNUSED(index);
47 int iconHeight = option.decorationSize.height() + (m_vPadding * 2); //icon height + padding either side
48 int textHeight = option.fontMetrics.height()*2 + (m_vPadding * 2) + 10; // text height * 2 + padding + some space between the lines
49 return QSize(-1,qMax(iconHeight, textHeight)); // any width, he view should give us the whole thing
50 }
51
createItemWidgets(const QModelIndex & index) const52 QList< QWidget* > NodeTypesDelegate::createItemWidgets(const QModelIndex &index) const
53 {
54 // items created by this method and added to the return-list will be
55 // deleted by KWidgetItemDelegate
56
57 KColorButton *colorButton = new KColorButton(index.data(NodeTypeModel::ColorRole).value<QColor>());
58 colorButton->setFlat(true);
59 QLineEdit *title = new QLineEdit(index.data(NodeTypeModel::TitleRole).toString());
60 title->setMinimumWidth(100);
61 QLabel *idLabel = new QLabel(index.data(NodeTypeModel::IdRole).toString());
62 idLabel->setToolTip(i18n("Unique ID of the node type."));
63 QToolButton *propertiesButton = new QToolButton();
64 propertiesButton->setIcon(QIcon::fromTheme("document-properties"));
65
66 connect(colorButton, &KColorButton::changed,
67 this, &NodeTypesDelegate::onColorChanged);
68 connect(colorButton, &KColorButton::pressed,
69 this, &NodeTypesDelegate::onColorDialogOpened);
70 connect(title, &QLineEdit::textEdited,
71 this, &NodeTypesDelegate::onNameChanged);
72 connect(propertiesButton, &QToolButton::clicked,
73 this, &NodeTypesDelegate::showPropertiesDialog);
74
75 return { colorButton, title, idLabel, propertiesButton };
76 }
77
updateItemWidgets(const QList<QWidget * > widgets,const QStyleOptionViewItem & option,const QPersistentModelIndex & index) const78 void NodeTypesDelegate::updateItemWidgets(const QList< QWidget* > widgets, const QStyleOptionViewItem& option, const QPersistentModelIndex& index) const
79 {
80 // widgets:
81 // ColorButton | Title | ID
82
83 if (!index.isValid()) {
84 return;
85 }
86
87 Q_ASSERT(widgets.size() == 4);
88
89 KColorButton *colorButton = qobject_cast<KColorButton*>(widgets.at(0));
90 QLineEdit *title = qobject_cast<QLineEdit*>(widgets.at(1));
91 QLabel *id = qobject_cast<QLabel*>(widgets.at(2));
92 QToolButton *propertiesButton = qobject_cast<QToolButton*>(widgets.at(3));
93
94 Q_ASSERT(title);
95 Q_ASSERT(colorButton);
96 Q_ASSERT(id);
97 Q_ASSERT(propertiesButton);
98
99 colorButton->setColor(index.data(NodeTypeModel::ColorRole).value<QColor>());
100 title->setText(index.data(NodeTypeModel::TitleRole).toString());
101 id->setText(index.data(NodeTypeModel::IdRole).toString());
102
103 QRect outerRect(0, 0, option.rect.width(), option.rect.height());
104 QRect contentRect = outerRect.adjusted(m_hPadding, m_vPadding, -m_hPadding, -m_vPadding);
105
106 int colorButtonLeftMargin = contentRect.left();
107 int colorButtonTopMargin = (outerRect.height() - colorButton->height()) / 2;
108 colorButton->move(colorButtonLeftMargin, colorButtonTopMargin);
109
110 int titleLeftMargin = colorButtonLeftMargin + colorButton->width() + 10;
111 int titleTopMargin = (outerRect.height() - title->height()) / 2;
112 title->move(titleLeftMargin, titleTopMargin);
113
114 // construct remaining from right to left
115 int propertiesLeftMargin = contentRect.right() - propertiesButton->width() - m_hPadding;
116 int propertiesTopMargin = (outerRect.height() - propertiesButton->height()) / 2;
117 propertiesButton->move(propertiesLeftMargin, propertiesTopMargin);
118
119 int idLeftMargin = propertiesLeftMargin - id->width() - 10;
120 int idTopMargin = (outerRect.height() - id->height()) / 2;
121 id->move(idLeftMargin, idTopMargin);
122
123 // title gets remaining space
124 title->setFixedWidth(qMax(0, idLeftMargin - titleLeftMargin - 10));
125 }
126
onColorChanged(const QColor & color)127 void NodeTypesDelegate::onColorChanged(const QColor &color)
128 {
129 // use temporary stored index, since focusedIndex() does not return current index
130 // reason: the color dialog signal does not allow for correct index estimation
131 Q_EMIT colorChanged(m_workaroundColorButtonIndex, color);
132 }
133
onColorDialogOpened()134 void NodeTypesDelegate::onColorDialogOpened()
135 {
136 m_workaroundColorButtonIndex = focusedIndex();
137 }
138
onNameChanged(const QString & name)139 void NodeTypesDelegate::onNameChanged(const QString &name)
140 {
141 QModelIndex index = focusedIndex();
142 Q_EMIT nameChanged(index, name);
143 }
144
showPropertiesDialog()145 void NodeTypesDelegate::showPropertiesDialog()
146 {
147 QModelIndex index = focusedIndex();
148 NodeType *type = qobject_cast<NodeType*>(index.data(NodeTypeModel::DataRole).value<QObject*>());
149 QPointer<NodeTypeProperties> dialog = new NodeTypeProperties(nullptr);
150 dialog->setType(type->self());
151 dialog->exec();
152 dialog->deleteLater();
153 }
154