Akonadi Contacts

customfieldslistdelegate.cpp
1/*
2 This file is part of Contact Editor.
3
4 SPDX-FileCopyrightText: 2010 Tobias Koenig <tokoe@kde.org>
5 SPDX-FileCopyrightText: 2016-2025 Laurent Montel <montel@kde.org>
6
7 SPDX-License-Identifier: LGPL-2.0-or-later
8*/
9
10#include "customfieldslistdelegate.h"
11
12#include "customfieldsmodel.h"
13
14#include <KLocalizedString>
15#include <KMessageBox>
16
17#include <QAbstractItemView>
18#include <QCheckBox>
19#include <QDateEdit>
20#include <QDateTimeEdit>
21#include <QMouseEvent>
22#include <QSpinBox>
23#include <QTimeEdit>
24#include <QTimer>
25
26using namespace Akonadi;
27CustomFieldsListDelegate::CustomFieldsListDelegate(QAbstractItemView *view, QObject *parent)
28 : QStyledItemDelegate(parent)
29 , mIcon(QIcon::fromTheme(QStringLiteral("list-remove")))
30 , mButtonSize(16, 16)
31 , mItemView(view)
32{
33}
34
35CustomFieldsListDelegate::~CustomFieldsListDelegate() = default;
36
37QWidget *CustomFieldsListDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &item, const QModelIndex &index) const
38{
39 if (index.column() == 1) {
40 const CustomField::Type type = static_cast<CustomField::Type>(index.data(CustomFieldsModel::TypeRole).toInt());
41
42 switch (type) {
43 case CustomField::TextType:
44 case CustomField::UrlType:
45 default:
46 return QStyledItemDelegate::createEditor(parent, item, index);
47 case CustomField::NumericType: {
48 auto editor = new QSpinBox(parent);
49 editor->setFrame(false);
50 editor->setAutoFillBackground(true);
51 return editor;
52 }
53 case CustomField::BooleanType: {
54 auto editor = new QCheckBox(parent);
55 return editor;
56 }
57 case CustomField::DateType: {
58 auto editor = new QDateEdit(parent);
59 editor->setFrame(false);
60 editor->setAutoFillBackground(true);
61 return editor;
62 }
63 case CustomField::TimeType: {
64 auto editor = new QTimeEdit(parent);
65 editor->setFrame(false);
66 editor->setAutoFillBackground(true);
67 return editor;
68 }
69 case CustomField::DateTimeType: {
70 auto editor = new QDateTimeEdit(parent);
71 editor->setFrame(false);
72 editor->setAutoFillBackground(true);
73 return editor;
74 }
75 }
76 } else {
77 return QStyledItemDelegate::createEditor(parent, item, index);
78 }
79}
80
81void CustomFieldsListDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
82{
83 if (index.column() == 1) {
84 const CustomField::Type type = static_cast<CustomField::Type>(index.data(CustomFieldsModel::TypeRole).toInt());
85
86 switch (type) {
87 case CustomField::TextType:
88 case CustomField::UrlType:
90 break;
91 case CustomField::NumericType: {
92 auto widget = qobject_cast<QSpinBox *>(editor);
93 widget->setValue(index.data(Qt::EditRole).toInt());
94 break;
95 }
96 case CustomField::BooleanType: {
97 auto widget = qobject_cast<QCheckBox *>(editor);
98 widget->setChecked(index.data(Qt::EditRole).toString() == QLatin1StringView("true"));
99 break;
100 }
101 case CustomField::DateType: {
102 auto widget = qobject_cast<QDateEdit *>(editor);
103 widget->setDisplayFormat(QStringLiteral("dd.MM.yyyy"));
104 widget->setDate(QDate::fromString(index.data(Qt::EditRole).toString(), Qt::ISODate));
105 break;
106 }
107 case CustomField::TimeType: {
108 auto widget = qobject_cast<QTimeEdit *>(editor);
109 widget->setDisplayFormat(QStringLiteral("hh:mm"));
110 widget->setTime(QTime::fromString(index.data(Qt::EditRole).toString(), Qt::ISODate));
111 break;
112 }
113 case CustomField::DateTimeType: {
114 auto widget = qobject_cast<QDateTimeEdit *>(editor);
115 widget->setDisplayFormat(QStringLiteral("dd.MM.yyyy hh:mm"));
116 widget->setDateTime(QDateTime::fromString(index.data(Qt::EditRole).toString(), Qt::ISODate));
117 break;
118 }
119 }
120 } else {
122 }
123}
124
125void CustomFieldsListDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
126{
127 if (index.column() == 1) {
128 const CustomField::Type type = static_cast<CustomField::Type>(index.data(CustomFieldsModel::TypeRole).toInt());
129
130 switch (type) {
131 case CustomField::TextType:
132 case CustomField::UrlType:
133 QStyledItemDelegate::setModelData(editor, model, index);
134 break;
135 case CustomField::NumericType: {
136 auto widget = qobject_cast<QSpinBox *>(editor);
137 model->setData(index, QString::number(widget->value()));
138 break;
139 }
140 case CustomField::BooleanType: {
141 auto widget = qobject_cast<QCheckBox *>(editor);
142 model->setData(index, widget->isChecked() ? QStringLiteral("true") : QStringLiteral("false"));
143 break;
144 }
145 case CustomField::DateType: {
146 auto widget = qobject_cast<QDateEdit *>(editor);
147 model->setData(index, widget->date().toString(Qt::ISODate));
148 break;
149 }
150 case CustomField::TimeType: {
151 auto widget = qobject_cast<QTimeEdit *>(editor);
152 model->setData(index, widget->time().toString(Qt::ISODate));
153 break;
154 }
155 case CustomField::DateTimeType: {
156 auto widget = qobject_cast<QDateTimeEdit *>(editor);
157 model->setData(index, widget->dateTime().toString(Qt::ISODate));
158 break;
159 }
160 }
161 } else {
162 QStyledItemDelegate::setModelData(editor, model, index);
163 }
164}
165
166void CustomFieldsListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
167{
168 // TODO: somehow mark local/global/external fields
169 QStyledItemDelegate::paint(painter, option, index);
170 if (index.column() == 1) {
171 mIcon.paint(painter, option.rect, Qt::AlignRight);
172 }
173}
174
175QSize CustomFieldsListDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
176{
177 Q_UNUSED(option)
178
179 QSize hint = QStyledItemDelegate::sizeHint(option, index);
180 hint.setHeight(qMax(hint.height(), mButtonSize.height()));
181
182 if (index.column() == 1) {
183 hint.setWidth(hint.width() + mButtonSize.width());
184 }
185
186 return hint;
187}
188
189bool CustomFieldsListDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
190{
191 if (index.column() == 1) {
192 if (event->type() == QEvent::MouseButtonRelease) {
193 const QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
194 QRect buttonRect = mItemView->visualRect(index);
195 buttonRect.setLeft(buttonRect.right() - mButtonSize.width());
196
197 if (buttonRect.contains(mouseEvent->pos())) {
198 removeField(index.row(), model);
199 return true;
200 }
201 }
202 }
203 return QStyledItemDelegate::editorEvent(event, model, option, index);
204}
205
206void CustomFieldsListDelegate::setFirstColumnAsCurrent()
207{
208 mItemView->setCurrentIndex(mItemView->model()->index(mItemView->currentIndex().row(), 0));
209}
210
211void CustomFieldsListDelegate::removeField(int row, QAbstractItemModel *model)
212{
214 i18nc("Custom Fields", "Do you really want to delete the selected custom field?"),
215 i18nc("@title:window", "Confirm Delete"),
218 return;
219 }
220
221 model->removeRow(row);
222 QTimer::singleShot(0, this, &CustomFieldsListDelegate::setFirstColumnAsCurrent);
223}
224
225#include "moc_customfieldslistdelegate.cpp"
QString i18nc(const char *context, const char *text, const TYPE &arg...)
A widget for editing the display name of a contact.
QAction * hint(const QObject *recvr, const char *slot, QObject *parent)
ButtonCode warningContinueCancel(QWidget *parent, const QString &text, const QString &title=QString(), const KGuiItem &buttonContinue=KStandardGuiItem::cont(), const KGuiItem &buttonCancel=KStandardGuiItem::cancel(), const QString &dontAskAgainName=QString(), Options options=Notify)
VehicleSection::Type type(QStringView coachNumber, QStringView coachClassification)
KGuiItem del()
bool removeRow(int row, const QModelIndex &parent)
virtual bool setData(const QModelIndex &index, const QVariant &value, int role)
QDate fromString(QStringView string, QStringView format, QCalendar cal)
QDateTime fromString(QStringView string, QStringView format, QCalendar cal)
MouseButtonRelease
int column() const const
QVariant data(int role) const const
int row() const const
QPoint pos() const const
virtual bool event(QEvent *e)
QObject * parent() const const
T qobject_cast(QObject *object)
bool contains(const QPoint &point, bool proper) const const
int right() const const
void setLeft(int x)
QString number(double n, char format, int precision)
virtual QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const const override
virtual bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) override
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const const override
virtual void setEditorData(QWidget *editor, const QModelIndex &index) const const override
virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const const override
virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const const override
AlignRight
EditRole
QTime fromString(QStringView string, QStringView format)
int toInt(bool *ok) const const
QString toString() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Jan 24 2025 11:55:33 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.