1 /*
2  * SPDX-FileCopyrightText: 2014 Sandro Knauß <knauss@kolabsys.com>
3  *
4  * SPDX-License-Identifier: GPL-2.0-or-later WITH Qt-Commercial-exception-1.0
5  */
6 
7 #include "attendeecomboboxdelegate.h"
8 
9 #include "attendeeline.h"
10 
11 #include <QAbstractItemView>
12 #include <QApplication>
13 #include <QHelpEvent>
14 #include <QMenu>
15 #include <QToolTip>
16 #include <QWhatsThis>
17 
18 using namespace IncidenceEditorNG;
19 
AttendeeComboBoxDelegate(QObject * parent)20 AttendeeComboBoxDelegate::AttendeeComboBoxDelegate(QObject *parent)
21     : QStyledItemDelegate(parent)
22 {
23     connect(this, &AttendeeComboBoxDelegate::closeEditor, this, &AttendeeComboBoxDelegate::doCloseEditor);
24 }
25 
addItem(const QIcon & icon,const QString & text)26 void AttendeeComboBoxDelegate::addItem(const QIcon &icon, const QString &text)
27 {
28     QPair<QIcon, QString> pair;
29     pair.first = icon;
30     pair.second = text;
31     mEntries << pair;
32 }
33 
clear()34 void AttendeeComboBoxDelegate::clear()
35 {
36     mEntries.clear();
37 }
38 
setToolTip(const QString & tT)39 void AttendeeComboBoxDelegate::setToolTip(const QString &tT)
40 {
41     mToolTip = tT;
42 }
43 
setWhatsThis(const QString & wT)44 void AttendeeComboBoxDelegate::setWhatsThis(const QString &wT)
45 {
46     mWhatsThis = wT;
47 }
48 
setStandardIndex(int index)49 void AttendeeComboBoxDelegate::setStandardIndex(int index)
50 {
51     mStandardIndex = index;
52 }
53 
createEditor(QWidget * parent,const QStyleOptionViewItem &,const QModelIndex &) const54 QWidget *AttendeeComboBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem & /* option */, const QModelIndex & /* index */) const
55 {
56     auto editor = new AttendeeComboBox(parent);
57 
58     for (const QPair<QIcon, QString> &pair : std::as_const(mEntries)) {
59         editor->addItem(pair.first, pair.second);
60     }
61 
62     connect(editor, &AttendeeComboBox::leftPressed, this, &AttendeeComboBoxDelegate::leftPressed);
63     connect(editor, &AttendeeComboBox::rightPressed, this, &AttendeeComboBoxDelegate::rightPressed);
64 
65     editor->setPopupMode(QToolButton::MenuButtonPopup);
66     editor->setToolTip(mToolTip);
67     editor->setWhatsThis(mWhatsThis);
68     return editor;
69 }
70 
setEditorData(QWidget * editor,const QModelIndex & index) const71 void AttendeeComboBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
72 {
73     auto comboBox = static_cast<AttendeeComboBox *>(editor);
74     int value = index.model()->data(index, Qt::EditRole).toUInt();
75     if (value >= mEntries.count()) {
76         value = mStandardIndex;
77     }
78     comboBox->setCurrentIndex(value);
79 }
80 
setModelData(QWidget * editor,QAbstractItemModel * model,const QModelIndex & index) const81 void AttendeeComboBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
82 {
83     auto comboBox = static_cast<AttendeeComboBox *>(editor);
84     model->setData(index, comboBox->currentIndex(), Qt::EditRole);
85     comboBox->menu()->close();
86 }
87 
updateEditorGeometry(QWidget * editor,const QStyleOptionViewItem & option,const QModelIndex &) const88 void AttendeeComboBoxDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex & /* index */) const
89 {
90     editor->setGeometry(option.rect);
91 }
92 
paint(QPainter * painter,const QStyleOptionViewItem & option,const QModelIndex & index) const93 void AttendeeComboBoxDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
94 {
95     QStyleOptionButton myOption;
96 
97     int value = index.model()->data(index).toUInt();
98     if (value >= mEntries.count()) {
99         value = mStandardIndex;
100     }
101 
102     myOption.rect = option.rect;
103     myOption.state = option.state;
104     myOption.icon = mEntries[value].first;
105     myOption.iconSize = myOption.icon.actualSize(option.rect.size());
106 
107     QApplication::style()->drawControl(QStyle::CE_PushButton, &myOption, painter);
108 }
109 
eventFilter(QObject * editor,QEvent * event)110 bool AttendeeComboBoxDelegate::eventFilter(QObject *editor, QEvent *event)
111 {
112     if (event->type() == QEvent::Enter) {
113         auto comboBox = static_cast<AttendeeComboBox *>(editor);
114         comboBox->showMenu();
115         return editor->eventFilter(editor, event);
116     }
117 
118     return QStyledItemDelegate::eventFilter(editor, event);
119 }
120 
doCloseEditor(QWidget * editor)121 void AttendeeComboBoxDelegate::doCloseEditor(QWidget *editor)
122 {
123     auto comboBox = static_cast<AttendeeComboBox *>(editor);
124     comboBox->menu()->close();
125 }
126 
leftPressed()127 void AttendeeComboBoxDelegate::leftPressed()
128 {
129     Q_EMIT closeEditor(static_cast<QWidget *>(QObject::sender()), QAbstractItemDelegate::EditPreviousItem);
130 }
131 
rightPressed()132 void AttendeeComboBoxDelegate::rightPressed()
133 {
134     Q_EMIT closeEditor(static_cast<QWidget *>(QObject::sender()), QAbstractItemDelegate::EditNextItem);
135 }
136 
helpEvent(QHelpEvent * event,QAbstractItemView * view,const QStyleOptionViewItem & option,const QModelIndex & index)137 bool AttendeeComboBoxDelegate::helpEvent(QHelpEvent *event, QAbstractItemView *view, const QStyleOptionViewItem &option, const QModelIndex &index)
138 {
139     if (!event || !view) {
140         return false;
141     }
142     switch (event->type()) {
143 #ifndef QT_NO_TOOLTIP
144     case QEvent::ToolTip: {
145         QToolTip::showText(event->globalPos(), mToolTip, view);
146         return true;
147     }
148 #endif
149 #ifndef QT_NO_WHATSTHIS
150     case QEvent::QueryWhatsThis:
151         return true;
152     case QEvent::WhatsThis: {
153         QWhatsThis::showText(event->globalPos(), mWhatsThis, view);
154         return true;
155     }
156 #endif
157     default:
158         break;
159     }
160     return QStyledItemDelegate::helpEvent(event, view, option, index);
161 }
162