• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.9.5 API Reference
  • KDE Home
  • Contact Us
 

akonadi

  • akonadi
  • contact
  • editor
kedittagsdialog.cpp
1 /*****************************************************************************
2  * Copyright (C) 2009 by Peter Penz <peter.penz@gmx.at> *
3  * *
4  * This library is free software; you can redistribute it and/or *
5  * modify it under the terms of the GNU Library General Public *
6  * License version 2 as published by the Free Software Foundation. *
7  * *
8  * This library is distributed in the hope that it will be useful, *
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
11  * Library General Public License for more details. *
12  * *
13  * You should have received a copy of the GNU Library General Public License *
14  * along with this library; see the file COPYING.LIB. If not, write to *
15  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
16  * Boston, MA 02110-1301, USA. *
17  *****************************************************************************/
18 
19 #include "kedittagsdialog_p.h"
20 
21 #include <kicon.h>
22 #include <klineedit.h>
23 #include <klocale.h>
24 #include <kmessagebox.h>
25 
26 #include <QEvent>
27 #include <QHBoxLayout>
28 #include <QLabel>
29 #include <QListWidget>
30 #include <QPushButton>
31 #include <QTimer>
32 #include <QVBoxLayout>
33 #include <QWidget>
34 
35 KEditTagsDialog::KEditTagsDialog(const QVector<Nepomuk::Tag>& tags,
36  QWidget* parent,
37  Qt::WFlags flags) :
38  KDialog(parent, flags),
39  m_tags(tags),
40  m_tagsList(0),
41  m_newTagItem(0),
42  m_deleteCandidate(0),
43  m_newTagEdit(0),
44  m_deleteButtonTimer(0)
45 {
46 
47  const QString caption = (tags.count() > 0) ?
48  i18nc("@title:window", "Change Tags") :
49  i18nc("@title:window", "Add Tags");
50  setCaption(caption);
51  setButtons(KDialog::Ok | KDialog::Cancel);
52  setDefaultButton(KDialog::Ok);
53 
54  QWidget* mainWidget = new QWidget(this);
55  QVBoxLayout* topLayout = new QVBoxLayout(mainWidget);
56 
57  QLabel* label = new QLabel(i18nc("@label:textbox",
58  "Configure which tags should "
59  "be applied."), this);
60 
61  m_tagsList = new QListWidget(this);
62  m_tagsList->setMouseTracking(true);
63  m_tagsList->setSortingEnabled(true);
64  m_tagsList->setSelectionMode(QAbstractItemView::NoSelection);
65  m_tagsList->installEventFilter(this);
66  connect(m_tagsList, SIGNAL(itemEntered(QListWidgetItem*)),
67  this, SLOT(slotItemEntered(QListWidgetItem*)));
68  connect(m_tagsList, SIGNAL(itemEntered(QListWidgetItem*)),
69  this, SLOT(slotItemEntered(QListWidgetItem*)));
70 
71  QLabel* newTagLabel = new QLabel(i18nc("@label", "Create new tag:"));
72  m_newTagEdit = new KLineEdit(this);
73  m_newTagEdit->setClearButtonShown(true);
74  connect(m_newTagEdit, SIGNAL(textEdited(QString)),
75  this, SLOT(slotTextEdited(QString)));
76 
77  QHBoxLayout* newTagLayout = new QHBoxLayout();
78  newTagLayout->addWidget(newTagLabel);
79  newTagLayout->addWidget(m_newTagEdit, 1);
80 
81  topLayout->addWidget(label);
82  topLayout->addWidget(m_tagsList);
83  topLayout->addLayout(newTagLayout);
84 
85  setMainWidget(mainWidget);
86 
87  loadTags();
88 
89  // create the delete button, which is shown when
90  // hovering the items
91  m_deleteButton = new QPushButton(m_tagsList->viewport());
92  m_deleteButton->setIcon(KIcon(QLatin1String("edit-delete")));
93  m_deleteButton->setToolTip(i18nc("@info", "Delete tag"));
94  m_deleteButton->hide();
95  connect(m_deleteButton, SIGNAL(clicked()), this, SLOT(deleteTag()));
96 
97  m_deleteButtonTimer = new QTimer(this);
98  m_deleteButtonTimer->setSingleShot(true);
99  m_deleteButtonTimer->setInterval(500);
100  connect(m_deleteButtonTimer, SIGNAL(timeout()), this, SLOT(showDeleteButton()));
101 }
102 
103 KEditTagsDialog::~KEditTagsDialog()
104 {
105 }
106 
107 QVector<Nepomuk::Tag> KEditTagsDialog::tags() const
108 {
109  return m_tags;
110 }
111 
112 bool KEditTagsDialog::eventFilter(QObject* watched, QEvent* event)
113 {
114  if ((watched == m_tagsList) && (event->type() == QEvent::Leave)) {
115  m_deleteButtonTimer->stop();
116  m_deleteButton->hide();
117  }
118  return KDialog::eventFilter(watched, event);
119 }
120 
121 void KEditTagsDialog::slotButtonClicked(int button)
122 {
123  if (button == KDialog::Ok) {
124  // update m_tags with the checked values, so
125  // that the caller of the KEditTagsDialog can
126  // receive the tags by KEditTagsDialog::tags()
127  m_tags.clear();
128 
129  const int count = m_tagsList->count();
130  for (int i = 0; i < count; ++i) {
131  QListWidgetItem* item = m_tagsList->item(i);
132  if (item->checkState() == Qt::Checked) {
133  const QString label = item->data(Qt::UserRole).toString();
134  Nepomuk::Tag tag(label);
135  tag.setLabel(label);
136  m_tags.append(tag);
137  }
138  }
139 
140  accept();
141  } else {
142  KDialog::slotButtonClicked(button);
143  }
144 }
145 
146 void KEditTagsDialog::slotTextEdited(const QString& text)
147 {
148  // Remove unnecessary spaces from a new tag is
149  // mandatory, as the user cannot see the difference
150  // between a tag "Test" and "Test ".
151  const QString tagText = text.simplified();
152  if (tagText.isEmpty()) {
153  removeNewTagItem();
154  return;
155  }
156 
157  // Check whether the new tag already exists. If this
158  // is the case, remove the new tag item.
159  const int count = m_tagsList->count();
160  for (int i = 0; i < count; ++i) {
161  const QListWidgetItem* item = m_tagsList->item(i);
162  const bool remove = (item->text() == tagText) &&
163  ((m_newTagItem == 0) || (m_newTagItem != item));
164  if (remove) {
165  m_tagsList->scrollToItem(item);
166  removeNewTagItem();
167  return;
168  }
169  }
170 
171  // There is no tag in the list with the the passed text.
172  if (m_newTagItem == 0) {
173  m_newTagItem = new QListWidgetItem(tagText, m_tagsList);
174  } else {
175  m_newTagItem->setText(tagText);
176  }
177  m_newTagItem->setData(Qt::UserRole, tagText);
178  m_newTagItem->setCheckState(Qt::Checked);
179  m_tagsList->scrollToItem(m_newTagItem);
180 }
181 
182 void KEditTagsDialog::slotItemEntered(QListWidgetItem* item)
183 {
184  // align the delete-button to stay on the right border
185  // of the item
186  const QRect rect = m_tagsList->visualItemRect(item);
187  const int size = rect.height();
188  const int x = rect.right() - size;
189  const int y = rect.top();
190  m_deleteButton->move(x, y);
191  m_deleteButton->resize(size, size);
192 
193  m_deleteCandidate = item;
194  m_deleteButtonTimer->start();
195 }
196 
197 void KEditTagsDialog::showDeleteButton()
198 {
199  m_deleteButton->show();
200 }
201 
202 void KEditTagsDialog::deleteTag()
203 {
204  Q_ASSERT(m_deleteCandidate != 0);
205  const QString text = i18nc("@info",
206  "Should the tag <resource>%1</resource> really be deleted for all files?",
207  m_deleteCandidate->text());
208  const QString caption = i18nc("@title", "Delete tag");
209  const KGuiItem deleteItem(i18nc("@action:button", "Delete"), KIcon(QLatin1String("edit-delete")));
210  const KGuiItem cancelItem(i18nc("@action:button", "Cancel"), KIcon(QLatin1String("dialog-cancel")));
211  if (KMessageBox::warningYesNo(this, text, caption, deleteItem, cancelItem) == KMessageBox::Yes) {
212  const QString label = m_deleteCandidate->data(Qt::UserRole).toString();
213  Nepomuk::Tag tag(label);
214  tag.remove();
215 
216  // clear list and reload it
217  for (int i = m_tagsList->count() - 1; i >= 0; --i) {
218  QListWidgetItem* item = m_tagsList->takeItem(i);
219  delete item;
220  }
221  loadTags();
222  }
223 }
224 
225 void KEditTagsDialog::loadTags()
226 {
227  // load all available tags and mark those tags as checked
228  // that have been passed to the KEditTagsDialog
229  foreach (const Nepomuk::Tag& tag, Nepomuk::Tag::allTags()) {
230  const QString label = tag.label();
231 
232  QListWidgetItem* item = new QListWidgetItem(label, m_tagsList);
233  item->setData(Qt::UserRole, label);
234 
235  bool check = false;
236  foreach (const Nepomuk::Tag& selectedTag, m_tags) {
237  if (selectedTag.label() == label) {
238  check = true;
239  break;
240  }
241  }
242  item->setCheckState(check ? Qt::Checked : Qt::Unchecked);
243  }
244 }
245 
246 void KEditTagsDialog::removeNewTagItem()
247 {
248  if (m_newTagItem != 0) {
249  const int row = m_tagsList->row(m_newTagItem);
250  m_tagsList->takeItem(row);
251  delete m_newTagItem;
252  m_newTagItem = 0;
253  }
254 }
255 
256 #include "kedittagsdialog_p.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2013 The KDE developers.
Generated on Sat Jan 5 2013 19:46:04 by doxygen 1.8.1.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

akonadi

Skip menu "akonadi"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • Modules
  • Related Pages

kdepimlibs-4.9.5 API Reference

Skip menu "kdepimlibs-4.9.5 API Reference"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal