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-2021 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()
36 {
37 }
38 
39 QWidget *CustomFieldsListDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &item, const QModelIndex &index) const
40 {
41  if (index.column() == 1) {
42  const CustomField::Type type = static_cast<CustomField::Type>(index.data(CustomFieldsModel::TypeRole).toInt());
43 
44  switch (type) {
45  case CustomField::TextType:
46  case CustomField::UrlType:
47  default:
48  return QStyledItemDelegate::createEditor(parent, item, index);
49  case CustomField::NumericType: {
50  auto editor = new QSpinBox(parent);
51  editor->setFrame(false);
52  editor->setAutoFillBackground(true);
53  return editor;
54  }
55  case CustomField::BooleanType: {
56  auto editor = new QCheckBox(parent);
57  return editor;
58  }
59  case CustomField::DateType: {
60  auto editor = new QDateEdit(parent);
61  editor->setFrame(false);
62  editor->setAutoFillBackground(true);
63  return editor;
64  }
65  case CustomField::TimeType: {
66  auto editor = new QTimeEdit(parent);
67  editor->setFrame(false);
68  editor->setAutoFillBackground(true);
69  return editor;
70  }
71  case CustomField::DateTimeType: {
72  auto editor = new QDateTimeEdit(parent);
73  editor->setFrame(false);
74  editor->setAutoFillBackground(true);
75  return editor;
76  }
77  }
78  } else {
79  return QStyledItemDelegate::createEditor(parent, item, index);
80  }
81 }
82 
83 void CustomFieldsListDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
84 {
85  if (index.column() == 1) {
86  const CustomField::Type type = static_cast<CustomField::Type>(index.data(CustomFieldsModel::TypeRole).toInt());
87 
88  switch (type) {
89  case CustomField::TextType:
90  case CustomField::UrlType:
92  break;
93  case CustomField::NumericType: {
94  auto widget = qobject_cast<QSpinBox *>(editor);
95  widget->setValue(index.data(Qt::EditRole).toInt());
96  break;
97  }
98  case CustomField::BooleanType: {
99  auto widget = qobject_cast<QCheckBox *>(editor);
100  widget->setChecked(index.data(Qt::EditRole).toString() == QLatin1String("true"));
101  break;
102  }
103  case CustomField::DateType: {
104  auto widget = qobject_cast<QDateEdit *>(editor);
105  widget->setDisplayFormat(QStringLiteral("dd.MM.yyyy"));
106  widget->setDate(QDate::fromString(index.data(Qt::EditRole).toString(), Qt::ISODate));
107  break;
108  }
109  case CustomField::TimeType: {
110  auto widget = qobject_cast<QTimeEdit *>(editor);
111  widget->setDisplayFormat(QStringLiteral("hh:mm"));
112  widget->setTime(QTime::fromString(index.data(Qt::EditRole).toString(), Qt::ISODate));
113  break;
114  }
115  case CustomField::DateTimeType: {
116  auto widget = qobject_cast<QDateTimeEdit *>(editor);
117  widget->setDisplayFormat(QStringLiteral("dd.MM.yyyy hh:mm"));
118  widget->setDateTime(QDateTime::fromString(index.data(Qt::EditRole).toString(), Qt::ISODate));
119  break;
120  }
121  }
122  } else {
123  QStyledItemDelegate::setEditorData(editor, index);
124  }
125 }
126 
127 void CustomFieldsListDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
128 {
129  if (index.column() == 1) {
130  const CustomField::Type type = static_cast<CustomField::Type>(index.data(CustomFieldsModel::TypeRole).toInt());
131 
132  switch (type) {
133  case CustomField::TextType:
134  case CustomField::UrlType:
135  QStyledItemDelegate::setModelData(editor, model, index);
136  break;
137  case CustomField::NumericType: {
138  auto widget = qobject_cast<QSpinBox *>(editor);
139  model->setData(index, QString::number(widget->value()));
140  break;
141  }
142  case CustomField::BooleanType: {
143  auto widget = qobject_cast<QCheckBox *>(editor);
144  model->setData(index, widget->isChecked() ? QStringLiteral("true") : QStringLiteral("false"));
145  break;
146  }
147  case CustomField::DateType: {
148  auto widget = qobject_cast<QDateEdit *>(editor);
149  model->setData(index, widget->date().toString(Qt::ISODate));
150  break;
151  }
152  case CustomField::TimeType: {
153  auto widget = qobject_cast<QTimeEdit *>(editor);
154  model->setData(index, widget->time().toString(Qt::ISODate));
155  break;
156  }
157  case CustomField::DateTimeType: {
158  auto widget = qobject_cast<QDateTimeEdit *>(editor);
159  model->setData(index, widget->dateTime().toString(Qt::ISODate));
160  break;
161  }
162  }
163  } else {
164  QStyledItemDelegate::setModelData(editor, model, index);
165  }
166 }
167 
168 void CustomFieldsListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
169 {
170  // TODO: somehow mark local/global/external fields
171  QStyledItemDelegate::paint(painter, option, index);
172  if (index.column() == 1) {
173  mIcon.paint(painter, option.rect, Qt::AlignRight);
174  }
175 }
176 
177 QSize CustomFieldsListDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
178 {
179  Q_UNUSED(option)
180 
181  QSize hint = QStyledItemDelegate::sizeHint(option, index);
182  hint.setHeight(qMax(hint.height(), mButtonSize.height()));
183 
184  if (index.column() == 1) {
185  hint.setWidth(hint.width() + mButtonSize.width());
186  }
187 
188  return hint;
189 }
190 
191 bool CustomFieldsListDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
192 {
193  if (index.column() == 1) {
194  if (event->type() == QEvent::MouseButtonRelease) {
195  const QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
196  QRect buttonRect = mItemView->visualRect(index);
197  buttonRect.setLeft(buttonRect.right() - mButtonSize.width());
198 
199  if (buttonRect.contains(mouseEvent->pos())) {
200  removeField(index.row(), model);
201  return true;
202  }
203  }
204  }
205  return QStyledItemDelegate::editorEvent(event, model, option, index);
206 }
207 
208 void CustomFieldsListDelegate::setFirstColumnAsCurrent()
209 {
210  mItemView->setCurrentIndex(mItemView->model()->index(mItemView->currentIndex().row(), 0));
211 }
212 
213 void CustomFieldsListDelegate::removeField(int row, QAbstractItemModel *model)
214 {
216  i18nc("Custom Fields", "Do you really want to delete the selected custom field?"),
217  i18n("Confirm Delete"),
219  != KMessageBox::Continue) {
220  return;
221  }
222 
223  model->removeRow(row);
224  QTimer::singleShot(0, this, &CustomFieldsListDelegate::setFirstColumnAsCurrent);
225 }
virtual void setEditorData(QWidget *editor, const QModelIndex &index) const const override
MouseButtonRelease
QEvent::Type type() const const
int right() const const
bool removeRow(int row, const QModelIndex &parent)
void setDisplayFormat(const QString &format)
QTime fromString(const QString &string, Qt::DateFormat format)
AlignRight
KGuiItem del()
QDate fromString(const QString &string, Qt::DateFormat format)
QString number(int n, int base)
ButtonCode warningContinueCancel(QWidget *parent, const QString &text, const QString &caption=QString(), const KGuiItem &buttonContinue=KStandardGuiItem::cont(), const KGuiItem &buttonCancel=KStandardGuiItem::cancel(), const QString &dontAskAgainName=QString(), Options options=Notify)
int toInt(bool *ok) const const
QString i18nc(const char *context, const char *text, const TYPE &arg...)
Type type(const QSqlDatabase &db)
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const const override
virtual QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const const override
EditRole
int row() const const
virtual QSize sizeHint() const const override
QAction * hint(const QObject *recvr, const char *slot, QObject *parent)
virtual bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) override
QDateTime fromString(const QString &string, Qt::DateFormat format)
void setChecked(bool)
QString i18n(const char *text, const TYPE &arg...)
bool contains(const QRect &rectangle, bool proper) const const
QVariant data(int role) const const
void setValue(int val)
virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const const override
int column() const const
virtual bool setData(const QModelIndex &index, const QVariant &value, int role)
QPoint pos() const const
T qobject_cast(QObject *object)
QObject * parent() const const
QString toString() const const
virtual bool event(QEvent *event) override
void setLeft(int x)
int height() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Wed Jun 23 2021 23:09:24 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.