21#include "tageditwidget.h"
25#include <klocalizedstring.h>
26#include <kmessagebox.h>
27#include <kcheckableproxymodel.h>
29#include <akonadi/changerecorder.h>
30#include <akonadi/tagcreatejob.h>
31#include <akonadi/tagdeletejob.h>
32#include <akonadi/tagfetchscope.h>
33#include <akonadi/tagattribute.h>
47class TagEditWidget::Private :
public QObject
51 Private(Akonadi::TagModel *model, QWidget *parent);
54 void slotTextEdited(
const QString &text);
55 void slotItemEntered(
const QModelIndex &index);
56 void showDeleteButton();
59 void slotCreateTagFinished(KJob *job);
60 void onRowsInserted(
const QModelIndex &parent,
int start,
int end);
63 void select(
const QModelIndex &parent,
int start,
int end, QItemSelectionModel::SelectionFlag selectionFlag);
65 UrlTag = Qt::UserRole + 1
69 Akonadi::Tag::List m_tags;
70 Akonadi::TagModel *m_model;
71 QListView *m_tagsView;
72 KCheckableProxyModel *m_checkableProxy;
73 QModelIndex m_deleteCandidate;
74 QPushButton *m_newTagButton;
75 KLineEdit *m_newTagEdit;
77 QPushButton *m_deleteButton;
78 QTimer *m_deleteButtonTimer;
81TagEditWidget::Private::Private(Akonadi::TagModel *model, QWidget *parent)
89 , m_deleteButtonTimer(0)
94void TagEditWidget::Private::select(
const QModelIndex &parent,
int start,
int end, QItemSelectionModel::SelectionFlag selectionFlag)
96 QItemSelection selection;
97 for (
int i = start; i <= end; i++) {
98 const QModelIndex index = m_model->index(i, 0, parent);
100 if (m_tags.contains(insertedTag)) {
101 selection.select(index, index);
104 m_checkableProxy->selectionModel()->select(selection, selectionFlag);
107void TagEditWidget::Private::onRowsInserted(
const QModelIndex &parent,
int start,
int end)
109 select(parent, start, end, QItemSelectionModel::Select);
112void TagEditWidget::Private::slotCreateTag()
114 if (m_newTagButton->isEnabled()) {
116 connect(createJob, SIGNAL(finished(KJob*)),
117 this, SLOT(slotCreateTagFinished(KJob*)));
119 m_newTagEdit->clear();
120 m_newTagEdit->setEnabled(
false);
121 m_newTagButton->setEnabled(
false);
125void TagEditWidget::Private::slotCreateTagFinished(KJob *job)
128 KMessageBox::error(d, i18n(
"An error occurred while creating a new tag"),
129 i18n(
"Failed to create a new tag"));
132 m_newTagEdit->setEnabled(
true);
135void TagEditWidget::Private::slotTextEdited(
const QString &text)
140 const QString tagText = text.simplified();
141 if (tagText.isEmpty()) {
142 m_newTagButton->setEnabled(
false);
147 const int count = m_model->rowCount();
149 for (
int i = 0; i < count; ++i) {
150 const QModelIndex index = m_model->index(i, 0, QModelIndex());
151 if (index.data(Qt::DisplayRole).toString() == tagText) {
156 m_newTagButton->setEnabled(!exists);
159void TagEditWidget::Private::slotItemEntered(
const QModelIndex &index)
163 const QRect rect = m_tagsView->visualRect(index);
164 const int size = rect.height();
165 const int x = rect.right() - size;
166 const int y = rect.top();
167 m_deleteButton->move(x, y);
168 m_deleteButton->resize(size, size);
170 m_deleteCandidate = index;
171 m_deleteButtonTimer->start();
174void TagEditWidget::Private::showDeleteButton()
176 m_deleteButton->show();
179void TagEditWidget::Private::deleteTag()
181 Q_ASSERT(m_deleteCandidate.isValid());
183 const QString text = i18nc(
"@info",
184 "Do you really want to remove the tag <resource>%1</resource>?",
186 const QString caption = i18nc(
"@title",
"Delete tag");
187 const KGuiItem deleteItem(i18nc(
"@action:button",
"Delete"), KIcon(QLatin1String(
"edit-delete")));
188 const KGuiItem cancelItem(i18nc(
"@action:button",
"Cancel"), KIcon(QLatin1String(
"dialog-cancel")));
189 if (KMessageBox::warningYesNo(d, text, caption, deleteItem, cancelItem) == KMessageBox::Yes) {
194TagEditWidget::TagEditWidget(Akonadi::TagModel *model, QWidget *parent,
bool enableSelection)
196 , d(new Private(model, this))
198 QVBoxLayout *topLayout =
new QVBoxLayout(
this);
200 QItemSelectionModel *selectionModel =
new QItemSelectionModel(d->m_model,
this);
201 d->m_checkableProxy =
new KCheckableProxyModel(
this);
202 d->m_checkableProxy->setSourceModel(d->m_model);
203 d->m_checkableProxy->setSelectionModel(selectionModel);
204 connect(d->m_model, SIGNAL(rowsInserted(QModelIndex,
int,
int)), d.data(), SLOT(onRowsInserted(QModelIndex,
int,
int)));
206 d->m_tagsView =
new QListView(
this);
207 d->m_tagsView->setMouseTracking(
true);
208 d->m_tagsView->setSelectionMode(QAbstractItemView::NoSelection);
209 d->m_tagsView->installEventFilter(
this);
210 if (enableSelection) {
211 d->m_tagsView->setModel(d->m_checkableProxy);
213 d->m_tagsView->setModel(d->m_model);
215 connect(d->m_tagsView, SIGNAL(entered(QModelIndex)),
216 d.data(), SLOT(slotItemEntered(QModelIndex)));
218 d->m_newTagEdit =
new KLineEdit(
this);
219 d->m_newTagEdit->setTrapReturnKey(
true);
220 d->m_newTagEdit->setClearButtonShown(
true);
221 connect(d->m_newTagEdit, SIGNAL(textEdited(QString)),
222 d.data(), SLOT(slotTextEdited(QString)));
223 connect(d->m_newTagEdit, SIGNAL(returnPressed()),
224 d.data(), SLOT(slotCreateTag()));
226 d->m_newTagButton =
new QPushButton(i18nc(
"@label",
"Create new tag"));
227 d->m_newTagButton->setEnabled(
false);
228 connect(d->m_newTagButton , SIGNAL(clicked(
bool)),
229 d.data(), SLOT(slotCreateTag()));
231 QHBoxLayout *newTagLayout =
new QHBoxLayout();
232 newTagLayout->addWidget(d->m_newTagEdit, 1);
233 newTagLayout->addWidget(d->m_newTagButton);
235 if (enableSelection) {
236 QLabel *label =
new QLabel(i18nc(
"@label:textbox",
237 "Configure which tags should "
238 "be applied."),
this);
239 topLayout->addWidget(label);
241 topLayout->addWidget(d->m_tagsView);
242 topLayout->addLayout(newTagLayout);
244 setLayout(topLayout);
248 d->m_deleteButton =
new QPushButton(d->m_tagsView->viewport());
249 d->m_deleteButton->setIcon(KIcon(QLatin1String(
"edit-delete")));
250 d->m_deleteButton->setToolTip(i18nc(
"@info",
"Delete tag"));
251 d->m_deleteButton->hide();
252 connect(d->m_deleteButton, SIGNAL(clicked()), d.data(), SLOT(deleteTag()));
254 d->m_deleteButtonTimer =
new QTimer(
this);
255 d->m_deleteButtonTimer->setSingleShot(
true);
256 d->m_deleteButtonTimer->setInterval(500);
257 connect(d->m_deleteButtonTimer, SIGNAL(timeout()), d.data(), SLOT(showDeleteButton()));
260TagEditWidget::~TagEditWidget()
265void TagEditWidget::setSelection(
const Akonadi::Tag::List &tags)
268 d->select(QModelIndex(), 0, d->m_model->rowCount() - 1, QItemSelectionModel::ClearAndSelect);
271Akonadi::Tag::List TagEditWidget::selection()
const
273 Akonadi::Tag::List list;
274 for (
int i = 0; i < d->m_checkableProxy->rowCount(); ++i) {
275 if (d->m_checkableProxy->selectionModel()->isRowSelected(i, QModelIndex())) {
276 const QModelIndex index = d->m_checkableProxy->index(i, 0, QModelIndex());
284bool TagEditWidget::eventFilter(QObject *watched, QEvent *event)
286 if ((watched == d->m_tagsView) && (event->type() == QEvent::Leave)) {
287 d->m_deleteButtonTimer->stop();
288 d->m_deleteButton->hide();
290 return QWidget::eventFilter(watched, event);
293#include "tageditwidget.moc"
Job that creates a new tag in the Akonadi storage.
FreeBusyManager::Singleton.