Akonadi Contacts

customfieldslistdelegate.cpp
1 /*
2  This file is part of Contact Editor.
3 
4  SPDX-FileCopyrightText: 2010 Tobias Koenig <[email protected]>
5  SPDX-FileCopyrightText: 2016-2023 Laurent Montel <[email protected]>
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 
26 using namespace ContactEditor;
27 CustomFieldsListDelegate::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 
35 CustomFieldsListDelegate::~CustomFieldsListDelegate() = default;
36 
37 QWidget *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 
81 void 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() == QLatin1String("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 {
121  QStyledItemDelegate::setEditorData(editor, index);
122  }
123 }
124 
125 void 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 
166 void 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 
175 QSize 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 
189 bool 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 
206 void CustomFieldsListDelegate::setFirstColumnAsCurrent()
207 {
208  mItemView->setCurrentIndex(mItemView->model()->index(mItemView->currentIndex().row(), 0));
209 }
210 
211 void CustomFieldsListDelegate::removeField(int row, QAbstractItemModel *model)
212 {
214  i18nc("Custom Fields", "Do you really want to delete the selected custom field?"),
215  i18n("Confirm Delete"),
217  != KMessageBox::Continue) {
218  return;
219  }
220 
221  model->removeRow(row);
222  QTimer::singleShot(0, this, &CustomFieldsListDelegate::setFirstColumnAsCurrent);
223 }
bool removeRow(int row, const QModelIndex &parent)
QPoint pos() const const
AlignRight
EditRole
MouseButtonRelease
QString number(int n, int base)
QTime fromString(const QString &string, Qt::DateFormat format)
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)
int right() const const
Type type(const QSqlDatabase &db)
int column() const const
bool contains(const QRect &rectangle, bool proper) const const
QVariant data(int role) const const
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const const override
QString i18n(const char *text, const TYPE &arg...)
int toInt(bool *ok) const const
AKONADI_CALENDAR_EXPORT KCalendarCore::Event::Ptr event(const Akonadi::Item &item)
virtual void setEditorData(QWidget *editor, const QModelIndex &index) const const override
QDateTime fromString(const QString &string, Qt::DateFormat format)
QAction * hint(const QObject *recvr, const char *slot, QObject *parent)
int row() const const
virtual QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const const override
KGuiItem del()
QDate fromString(const QString &string, Qt::DateFormat format)
QString i18nc(const char *context, const char *text, const TYPE &arg...)
virtual bool setData(const QModelIndex &index, const QVariant &value, int role)
void setLeft(int x)
virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const const override
virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const const override
QString toString() const const
virtual bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) override
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Sat Apr 1 2023 04:09:04 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.