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-2024 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
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...)
Type type(const QSqlDatabase &db)
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)
KGuiItem del()
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const=0
bool removeRow(int row, const QModelIndex &parent)
virtual bool setData(const QModelIndex &index, const QVariant &value, int role)
QModelIndex currentIndex() const const
QAbstractItemModel * model() const const
void setCurrentIndex(const QModelIndex &index)
virtual QRect visualRect(const QModelIndex &index) const const=0
QDate fromString(QStringView string, QStringView format, QCalendar cal)
QDateTime fromString(QStringView string, QStringView format, QCalendar cal)
MouseButtonRelease
void paint(QPainter *painter, const QRect &rect, Qt::Alignment alignment, Mode mode, State state) const const
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
bool contains(const QPoint &point, bool proper) const const
int right() const const
void setLeft(int x)
int height() const const
int width() const const
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-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:13:20 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.