Libksieve

sievescriptlistbox.cpp
1 /*
2  SPDX-FileCopyrightText: 2013-2021 Laurent Montel <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #include "sievescriptlistbox.h"
8 #include "sieveeditorgraphicalmodewidget.h"
9 #include "sieveforeverypartwidget.h"
10 #include "sieveglobalvariablewidget.h"
11 #include "sieveincludewidget.h"
12 #include "sievescriptdescriptiondialog.h"
13 #include "sievescriptpage.h"
14 #include <KLocalizedString>
15 #include <KMessageBox>
16 #include <QHBoxLayout>
17 #include <QIcon>
18 #include <QInputDialog>
19 #include <QPushButton>
20 #include <QXmlStreamReader>
21 
22 #include "libksieve_debug.h"
23 #include <QListWidget>
24 #include <QMenu>
25 #include <QPointer>
26 #include <QVBoxLayout>
27 
28 namespace
29 {
30 inline const QString defaultScriptName()
31 {
32  return QStringLiteral("SCRIPTNAME: ");
33 }
34 }
35 
36 using namespace KSieveUi;
37 
38 SieveScriptListItem::SieveScriptListItem(const QString &text, QListWidget *parent)
39  : QListWidgetItem(text, parent)
40 {
41 }
42 
43 SieveScriptListItem::~SieveScriptListItem()
44 {
45 }
46 
47 void SieveScriptListItem::setDescription(const QString &desc)
48 {
49  mDescription = desc;
50 }
51 
52 QString SieveScriptListItem::description() const
53 {
54  return mDescription;
55 }
56 
57 SieveScriptPage *SieveScriptListItem::scriptPage() const
58 {
59  return mScriptPage;
60 }
61 
62 void SieveScriptListItem::setScriptPage(SieveScriptPage *page)
63 {
64  mScriptPage = page;
65 }
66 
67 QString SieveScriptListItem::generatedScript(QStringList &required) const
68 {
69  QString script;
70  if (!mDescription.trimmed().isEmpty()) {
71  const QVector<QStringRef> commentList = mDescription.splitRef(QLatin1Char('\n'));
72  for (const QStringRef &str : commentList) {
73  if (str.isEmpty()) {
74  script += QLatin1Char('\n');
75  } else {
76  script += QLatin1Char('#') + str + QLatin1Char('\n');
77  }
78  }
79  }
80  if (mScriptPage) {
81  mScriptPage->generatedScript(script, required);
82  }
83  return script;
84 }
85 
86 SieveScriptListBox::SieveScriptListBox(const QString &title, QWidget *parent)
87  : QGroupBox(title, parent)
88 {
89  auto layout = new QVBoxLayout(this);
90  layout->setObjectName(QStringLiteral("layout"));
91  mSieveListScript = new QListWidget(this);
92  mSieveListScript->setObjectName(QStringLiteral("mSieveListScript"));
93  mSieveListScript->setDragDropMode(QAbstractItemView::InternalMove);
94  mSieveListScript->setContextMenuPolicy(Qt::CustomContextMenu);
95  connect(mSieveListScript, &QListWidget::customContextMenuRequested, this, &SieveScriptListBox::slotCustomMenuRequested);
96  layout->addWidget(mSieveListScript);
97 
98  //----------- the first row of buttons
99  auto hb = new QWidget(this);
100  auto hbHBoxLayout = new QHBoxLayout(hb);
101  hbHBoxLayout->setContentsMargins({});
102  hbHBoxLayout->setSpacing(4);
103 
104  mBtnTop = new QPushButton(hb);
105  hbHBoxLayout->addWidget(mBtnTop);
106  mBtnTop->setIcon(QIcon::fromTheme(QStringLiteral("go-top")));
107  mBtnTop->setMinimumSize(mBtnTop->sizeHint() * 1.2);
108 
109  mBtnUp = new QPushButton(hb);
110  hbHBoxLayout->addWidget(mBtnUp);
111  mBtnUp->setAutoRepeat(true);
112  mBtnUp->setIcon(QIcon::fromTheme(QStringLiteral("go-up")));
113  mBtnUp->setMinimumSize(mBtnUp->sizeHint() * 1.2);
114  mBtnDown = new QPushButton(hb);
115  hbHBoxLayout->addWidget(mBtnDown);
116  mBtnDown->setAutoRepeat(true);
117  mBtnDown->setIcon(QIcon::fromTheme(QStringLiteral("go-down")));
118  mBtnDown->setMinimumSize(mBtnDown->sizeHint() * 1.2);
119 
120  mBtnBottom = new QPushButton(hb);
121  hbHBoxLayout->addWidget(mBtnBottom);
122  mBtnBottom->setIcon(QIcon::fromTheme(QStringLiteral("go-bottom")));
123  mBtnBottom->setMinimumSize(mBtnBottom->sizeHint() * 1.2);
124 
125  mBtnUp->setToolTip(i18nc("Move selected filter up.", "Up"));
126  mBtnDown->setToolTip(i18nc("Move selected filter down.", "Down"));
127  mBtnTop->setToolTip(i18nc("Move selected filter to the top.", "Top"));
128  mBtnBottom->setToolTip(i18nc("Move selected filter to the bottom.", "Bottom"));
129 
130  layout->addWidget(hb);
131 
132  hb = new QWidget(this);
133  hbHBoxLayout = new QHBoxLayout(hb);
134  hbHBoxLayout->setContentsMargins({});
135  hbHBoxLayout->setSpacing(4);
136 
137  mBtnNew = new QPushButton(hb);
138  hbHBoxLayout->addWidget(mBtnNew);
139  mBtnNew->setIcon(QIcon::fromTheme(QStringLiteral("document-new")));
140  mBtnNew->setToolTip(i18n("New Script"));
141  mBtnNew->setMinimumSize(mBtnNew->sizeHint() * 1.2);
142 
143  mBtnDelete = new QPushButton(hb);
144  hbHBoxLayout->addWidget(mBtnDelete);
145  mBtnDelete->setIcon(QIcon::fromTheme(QStringLiteral("edit-delete")));
146  mBtnDelete->setToolTip(i18n("Delete Script"));
147  mBtnDelete->setMinimumSize(mBtnDelete->sizeHint() * 1.2);
148 
149  mBtnRename = new QPushButton(hb);
150  mBtnRename->setToolTip(i18n("Rename Script"));
151  mBtnRename->setIcon(QIcon::fromTheme(QStringLiteral("edit-rename")));
152  mBtnRename->setMinimumSize(mBtnRename->sizeHint() * 1.2);
153  hbHBoxLayout->addWidget(mBtnRename);
154 
155  mBtnDescription = new QPushButton(hb);
156  mBtnDescription->setToolTip(i18n("Edit Script Description"));
157  mBtnDescription->setIcon(QIcon::fromTheme(QStringLiteral("edit-comment")));
158  mBtnDescription->setMinimumSize(mBtnDescription->sizeHint() * 1.2);
159 
160  hbHBoxLayout->addWidget(mBtnDescription);
161 
162  layout->addWidget(hb);
163 
164  connect(mBtnNew, &QPushButton::clicked, this, &SieveScriptListBox::slotNew);
165  connect(mBtnDelete, &QPushButton::clicked, this, &SieveScriptListBox::slotDelete);
166  connect(mBtnRename, &QPushButton::clicked, this, &SieveScriptListBox::slotRename);
167  connect(mBtnDescription, &QPushButton::clicked, this, &SieveScriptListBox::slotEditDescription);
168 
169  connect(mBtnUp, &QPushButton::clicked, this, &SieveScriptListBox::slotUp);
170  connect(mBtnDown, &QPushButton::clicked, this, &SieveScriptListBox::slotDown);
171  connect(mBtnTop, &QPushButton::clicked, this, &SieveScriptListBox::slotTop);
172  connect(mBtnBottom, &QPushButton::clicked, this, &SieveScriptListBox::slotBottom);
173 
174  connect(mSieveListScript, &QListWidget::itemSelectionChanged, this, &SieveScriptListBox::updateButtons);
175  connect(mSieveListScript, &QListWidget::itemActivated, this, &SieveScriptListBox::slotItemActived);
176  connect(mSieveListScript, &QListWidget::itemDoubleClicked, this, &SieveScriptListBox::slotEditDescription);
177  updateButtons();
178 }
179 
180 SieveScriptListBox::~SieveScriptListBox()
181 {
182 }
183 
184 void SieveScriptListBox::slotCustomMenuRequested(const QPoint &pos)
185 {
186  QMenu menu(this);
187  QAction *newScriptAction = menu.addAction(i18nc("@action:inmenu", "New Script"));
188  newScriptAction->setIcon(QIcon::fromTheme(QStringLiteral("document-new")));
189  connect(newScriptAction, &QAction::triggered, this, &SieveScriptListBox::slotNew);
190 
191  if (mSieveListScript->itemAt(pos)) {
192  QAction *renameScriptAction = menu.addAction(i18nc("@action:inmenu", "Rename Script"));
193  renameScriptAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-rename")));
194  connect(renameScriptAction, &QAction::triggered, this, &SieveScriptListBox::slotRename);
195 
196  menu.addSeparator();
197  QAction *deleteScriptAction = menu.addAction(i18nc("@action:inmenu", "Delete Script"));
198  deleteScriptAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-delete")));
199  connect(deleteScriptAction, &QAction::triggered, this, &SieveScriptListBox::slotDelete);
200  }
201  menu.exec(mapToGlobal(pos));
202 }
203 
204 void SieveScriptListBox::setSieveEditorGraphicalModeWidget(SieveEditorGraphicalModeWidget *graphicalModeWidget)
205 {
206  mSieveGraphicalModeWidget = graphicalModeWidget;
207 }
208 
209 void SieveScriptListBox::slotItemActived(QListWidgetItem *item)
210 {
211  if (item) {
212  auto itemScript = static_cast<SieveScriptListItem *>(item);
213  Q_EMIT activatePage(itemScript->scriptPage());
214  }
215 }
216 
217 void SieveScriptListBox::updateButtons()
218 {
219  const int currentIndex = mSieveListScript->currentRow();
220  const bool theFirst = (currentIndex == 0);
221  const int numberOfElement(mSieveListScript->count());
222  const bool theLast = (currentIndex >= numberOfElement - 1);
223 
224  const QList<QListWidgetItem *> lst = mSieveListScript->selectedItems();
225  mBtnDelete->setEnabled(!lst.isEmpty());
226  mBtnRename->setEnabled(lst.count() == 1);
227  mBtnDescription->setEnabled(lst.count() == 1);
228  mBtnBottom->setEnabled(!lst.isEmpty() && !theLast);
229  mBtnTop->setEnabled(!lst.isEmpty() && !theFirst);
230  mBtnDown->setEnabled(!lst.isEmpty() && !theLast);
231  mBtnUp->setEnabled(!lst.isEmpty() && !theFirst);
232 }
233 
234 SieveScriptPage *SieveScriptListBox::createNewScript(const QString &newName, const QString &description)
235 {
236  auto item = new SieveScriptListItem(newName, mSieveListScript);
237  item->setDescription(description);
238  auto page = new SieveScriptPage(mSieveGraphicalModeWidget);
239  page->setListOfIncludeFile(mSieveGraphicalModeWidget->listOfIncludeFile());
240  item->setScriptPage(page);
241  Q_EMIT addNewPage(page);
242  Q_EMIT enableButtonOk(true);
243  mSieveListScript->setCurrentItem(item);
244  updateButtons();
245  return page;
246 }
247 
248 void SieveScriptListBox::slotNew()
249 {
250  const QString newName = QInputDialog::getText(this, i18nc("@title:window", "New Script"), i18n("New script name:"));
251  if (!newName.trimmed().isEmpty()) {
252  createNewScript(newName);
253  Q_EMIT valueChanged();
254  }
255 }
256 
257 void SieveScriptListBox::slotDelete()
258 {
259  QListWidgetItem *item = mSieveListScript->currentItem();
260  if (item) {
261  if (KMessageBox::warningYesNo(this, i18n("Do you want to delete \"%1\" script?", item->text()), i18nc("@title:window", "Delete Script"))
262  == KMessageBox::Yes) {
263  auto itemScript = static_cast<SieveScriptListItem *>(item);
264  Q_EMIT removePage(itemScript->scriptPage());
265  delete item;
266  Q_EMIT enableButtonOk(mSieveListScript->count() > 0);
267  updateButtons();
268  Q_EMIT valueChanged();
269  }
270  }
271 }
272 
273 void SieveScriptListBox::slotRename()
274 {
275  QListWidgetItem *item = mSieveListScript->currentItem();
276  if (item) {
277  QString newName =
278  QInputDialog::getText(this, i18nc("@title:window", "Rename Script"), i18n("New name for the script:"), QLineEdit::Normal, item->text());
279  newName = newName.trimmed();
280  if (!newName.isEmpty()) {
281  item->setText(newName);
282  Q_EMIT valueChanged();
283  }
284  }
285 }
286 
287 void SieveScriptListBox::slotEditDescription()
288 {
289  QListWidgetItem *item = mSieveListScript->currentItem();
290  if (item) {
291  auto sieveItem = static_cast<SieveScriptListItem *>(item);
292  QPointer<SieveScriptDescriptionDialog> dlg = new SieveScriptDescriptionDialog(this);
293  dlg->setDescription(sieveItem->description());
294  if (dlg->exec()) {
295  sieveItem->setDescription(dlg->description());
296  Q_EMIT valueChanged();
297  }
298  delete dlg;
299  }
300 }
301 
302 void SieveScriptListBox::slotTop()
303 {
304  QListWidgetItem *item = mSieveListScript->currentItem();
305  if (item) {
306  const int currentIndex = mSieveListScript->currentRow();
307  if (currentIndex != 0) {
308  item = mSieveListScript->takeItem(currentIndex);
309  mSieveListScript->insertItem(0, item);
310  mSieveListScript->setCurrentItem(item);
311  Q_EMIT valueChanged();
312  }
313  }
314 }
315 
316 void SieveScriptListBox::slotBottom()
317 {
318  QListWidgetItem *item = mSieveListScript->currentItem();
319  if (item) {
320  const int currentIndex = mSieveListScript->currentRow();
321  if (currentIndex != mSieveListScript->count() - 1) {
322  item = mSieveListScript->takeItem(currentIndex);
323  mSieveListScript->insertItem(mSieveListScript->count(), item);
324  mSieveListScript->setCurrentItem(item);
325  Q_EMIT valueChanged();
326  }
327  }
328 }
329 
330 void SieveScriptListBox::slotDown()
331 {
332  QListWidgetItem *item = mSieveListScript->currentItem();
333  if (item) {
334  const int currentIndex = mSieveListScript->currentRow();
335  if (currentIndex < mSieveListScript->count() - 1) {
336  item = mSieveListScript->takeItem(currentIndex);
337  mSieveListScript->insertItem(currentIndex + 1, item);
338  mSieveListScript->setCurrentItem(item);
339  Q_EMIT valueChanged();
340  }
341  }
342 }
343 
344 void SieveScriptListBox::slotUp()
345 {
346  QListWidgetItem *item = mSieveListScript->currentItem();
347  if (item) {
348  const int currentIndex = mSieveListScript->currentRow();
349  if (currentIndex >= 1) {
350  item = mSieveListScript->takeItem(currentIndex);
351  mSieveListScript->insertItem(currentIndex - 1, item);
352  mSieveListScript->setCurrentItem(item);
353  Q_EMIT valueChanged();
354  }
355  }
356 }
357 
358 QString SieveScriptListBox::generatedScript(QStringList &requireModules) const
359 {
360  QString resultScript;
361  QStringList lstRequires;
362  const int numberOfScripts(mSieveListScript->count());
363  for (int i = 0; i < numberOfScripts; ++i) {
364  auto item = static_cast<SieveScriptListItem *>(mSieveListScript->item(i));
365  if (i != 0) {
366  resultScript += QLatin1String("\n\n");
367  }
368  resultScript += QLatin1Char('#') + defaultScriptName() + item->text() + QLatin1Char('\n');
369  resultScript += item->generatedScript(lstRequires);
370  }
371  if (!resultScript.isEmpty()) {
372  resultScript += QLatin1Char('\n');
373  }
374 
375  QStringList endRequires;
376  for (const QString &r : qAsConst(lstRequires)) {
377  if (!endRequires.contains(r)) {
378  endRequires.append(r);
379  requireModules += QStringLiteral("require \"%1\";").arg(r);
380  }
381  }
382 
383  return resultScript;
384 }
385 
386 void SieveScriptListBox::clear()
387 {
388  mScriptNumber = 0;
389  Q_EMIT enableButtonOk(false);
390  // Clear tabpage
391  mSieveListScript->clear();
392  updateButtons();
393 }
394 
395 void SieveScriptListBox::loadScript(const QString &doc, QString &error)
396 {
397  clear();
398  QXmlStreamReader streamReader(doc);
399  if (streamReader.readNextStartElement()) {
400  if (streamReader.name() == QLatin1String("script")) {
401  SieveScriptPage *currentPage = nullptr;
402  ParseSieveScriptTypeBlock typeBlock = TypeUnknown;
403  loadBlock(streamReader, currentPage, typeBlock, error);
404  }
405  }
406 }
407 
408 void SieveScriptListBox::loadBlock(QXmlStreamReader &n, SieveScriptPage *currentPage, ParseSieveScriptTypeBlock typeBlock, QString &error)
409 {
410  QString scriptName;
411  QString comment;
412  bool hasCreatedAIfBlock = false;
413  bool previousElementWasAComment = false;
414  while (n.readNextStartElement()) {
415  const QStringRef tagName = n.name();
416  // qDebug() <<"SieveScriptListBox::loadBlock tagName " << tagName;
417  if (tagName == QLatin1String("control")) {
418  previousElementWasAComment = false;
419  // Create a new page when before it was "onlyactions"
420  if (typeBlock == TypeBlockAction) {
421  currentPage = nullptr;
422  }
423  if (n.attributes().hasAttribute(QLatin1String("name"))) {
424  const QString controlType = n.attributes().value(QLatin1String("name")).toString();
425  // qCDebug(LIBKSIEVE_LOG)<<" controlType"<<controlType;
426  if (controlType == QLatin1String("if")) {
427  typeBlock = TypeBlockIf;
428  if (!currentPage || hasCreatedAIfBlock) {
429  currentPage = createNewScript(scriptName.isEmpty() ? createUniqName() : scriptName, comment);
430  }
431  hasCreatedAIfBlock = true;
432  comment.clear();
433  currentPage->blockIfWidget()->loadScript(n, false, error);
434  } else if (controlType == QLatin1String("elsif")) {
435  typeBlock = TypeBlockElsif;
436  if (!currentPage) {
437  qCDebug(LIBKSIEVE_LOG) << " script is not correct missing if block";
438  currentPage = createNewScript(scriptName.isEmpty() ? createUniqName() : scriptName, comment);
439  }
440  SieveScriptBlockWidget *blockWidget = currentPage->addScriptBlock(KSieveUi::SieveWidgetPageAbstract::BlockElsIf);
441  if (blockWidget) {
442  blockWidget->loadScript(n, false, error);
443  }
444  } else if (controlType == QLatin1String("else")) {
445  typeBlock = TypeBlockElse;
446  if (!currentPage) {
447  currentPage = createNewScript(scriptName.isEmpty() ? createUniqName() : scriptName, comment);
448  qCDebug(LIBKSIEVE_LOG) << " script is not correct missing if block";
449  }
450  SieveScriptBlockWidget *blockWidget = currentPage->addScriptBlock(KSieveUi::SieveWidgetPageAbstract::BlockElse);
451  if (blockWidget) {
452  blockWidget->loadScript(n, false, error);
453  }
454  // We are sure that we can't have another elsif
455  currentPage = nullptr;
456  } else if (controlType == QLatin1String("foreverypart")) {
457  typeBlock = TypeBlockForeachBlock;
458  if (!currentPage) {
459  currentPage = createNewScript(scriptName.isEmpty() ? createUniqName() : scriptName, comment);
460  comment.clear();
461  }
462  if (currentPage->forEveryPartWidget()) {
463  currentPage->forEveryPartWidget()->loadScript(n, error);
464  } else {
465  error += i18n("forEveryPart is not supported by your server") + QLatin1Char('\n');
466  }
467  // TODO verify it.
468 #ifdef QDOMELEMENT_FIXME
469  QDomNode block = e.firstChildElement(QStringLiteral("block")).firstChild();
470  loadBlock(block, currentPage, typeBlock, error);
471 #endif
472  } else if (controlType == QLatin1String("require")) {
473  n.skipCurrentElement();
474  // Nothing. autogenerated
475  } else {
476  qCDebug(LIBKSIEVE_LOG) << " unknown controlType :" << controlType;
477  }
478  }
479  } else if (tagName == QLatin1String("comment")) {
480  previousElementWasAComment = true;
481 #ifdef FIXME_COMMENT
482  if (e.hasAttribute(QStringLiteral("hash"))) {
483  // TODO
484  } else if (e.hasAttribute(QStringLiteral("bracket"))) {
485  // TODO
486  }
487 #endif
488  QString str(n.readElementText());
489  if (str.contains(defaultScriptName())) {
490  scriptName = str.remove(defaultScriptName());
491  } else {
492  if (!comment.isEmpty()) {
493  comment += QLatin1Char('\n');
494  }
495  comment += str;
496  }
497  // qDebug() << " COMMENT " << comment;
498  } else if (tagName == QLatin1String("action")) {
499  previousElementWasAComment = false;
500  if (n.attributes().hasAttribute(QLatin1String("name"))) {
501  const QString actionName = n.attributes().value(QLatin1String("name")).toString();
502  if (actionName == QLatin1String("include")) {
503  if (!currentPage || (typeBlock == TypeBlockIf) || (typeBlock == TypeBlockElse) || (typeBlock == TypeBlockElsif)) {
504  currentPage = createNewScript(scriptName.isEmpty() ? createUniqName() : scriptName, comment);
505  comment.clear();
506  }
507  typeBlock = TypeBlockInclude;
508  if (currentPage->includeWidget()) {
509  currentPage->includeWidget()->loadScript(n, error);
510  } else {
511  qCDebug(LIBKSIEVE_LOG) << " include not supported";
512  }
513  } else if (actionName == QLatin1String("global")) {
514  if (!currentPage || (typeBlock == TypeBlockIf) || (typeBlock == TypeBlockElse) || (typeBlock == TypeBlockElsif)) {
515  currentPage = createNewScript(scriptName.isEmpty() ? createUniqName() : scriptName, comment);
516  comment.clear();
517  }
518  typeBlock = TypeBlockGlobal;
519  if (currentPage->globalVariableWidget()) {
520  currentPage->globalVariableWidget()->loadScript(n, error);
521  } else {
522  qCDebug(LIBKSIEVE_LOG) << " globalVariable not supported";
523  }
524  } else if (actionName == QLatin1String("set") && (typeBlock == TypeBlockGlobal)) {
525  // FIXME global not global variable.
526  if (currentPage->globalVariableWidget()) {
527  const SieveGlobalVariableActionWidget::VariableElement var = currentPage->globalVariableWidget()->loadSetVariable(n, error);
528  if (var.isValid()) {
529  qCDebug(LIBKSIEVE_LOG) << "It's not a global variable";
530  if ((typeBlock == TypeBlockIf) || (typeBlock == TypeBlockElse) || (typeBlock == TypeBlockElsif)) {
531  currentPage = createNewScript(scriptName.isEmpty() ? createUniqName() : scriptName, comment);
532  }
533  typeBlock = TypeBlockAction;
534  comment.clear();
535  currentPage->blockIfWidget()->loadLocalVariable(var);
536  }
537  } else {
538  qCDebug(LIBKSIEVE_LOG) << " set not supported";
539  }
540  } else {
541  if (!currentPage || (typeBlock == TypeBlockIf) || (typeBlock == TypeBlockElse) || (typeBlock == TypeBlockElsif)) {
542  currentPage = createNewScript(scriptName.isEmpty() ? createUniqName() : scriptName, comment);
543  }
544  typeBlock = TypeBlockAction;
545  comment.clear();
546  currentPage->blockIfWidget()->loadScript(n, true, error);
547  }
548  }
549  } else if (tagName == QLatin1String("crlf")) {
550  // If it was a comment previously you will create a \n
551  if (previousElementWasAComment) {
552  comment += QLatin1Char('\n');
553  }
554  n.skipCurrentElement();
555  } else {
556  qCDebug(LIBKSIEVE_LOG) << " unknown tagname" << tagName;
557  }
558  }
559 }
560 
561 QString SieveScriptListBox::createUniqName()
562 {
563  const QString pattern = i18n("Script part %1", mScriptNumber);
564  ++mScriptNumber;
565  return pattern;
566 }
QLayout * layout() const const
void customContextMenuRequested(const QPoint &pos)
void triggered(bool checked)
bool readNextStartElement()
QString toString() const const
void setIcon(const QIcon &icon)
bool contains(const QString &str, Qt::CaseSensitivity cs) const const
QPoint mapToGlobal(const QPoint &pos) const const
QStringRef value(const QString &namespaceUri, const QString &name) const const
QString & remove(int position, int n)
CustomContextMenu
void clear()
void skipCurrentElement()
int count(const T &value) const const
void append(const T &value)
QString pattern(Mode mode=Reading)
QString readElementText(QXmlStreamReader::ReadElementTextBehaviour behaviour)
QString i18nc(const char *context, const char *text, const TYPE &arg...)
bool isEmpty() const const
void setObjectName(const QString &name)
bool isEmpty() const const
QString trimmed() const const
void clicked(bool checked)
QPoint pos() const const
void addWidget(QWidget *w)
QString getText(QWidget *parent, const QString &title, const QString &label, QLineEdit::EchoMode mode, const QString &text, bool *ok, Qt::WindowFlags flags, Qt::InputMethodHints inputMethodHints)
bool hasAttribute(const QString &qualifiedName) const const
QString i18n(const char *text, const TYPE &arg...)
QDomNode firstChild() const const
QDomElement firstChildElement(const QString &tagName) const const
QWidget(QWidget *parent, Qt::WindowFlags f)
QXmlStreamAttributes attributes() const const
void itemActivated(QListWidgetItem *item)
QIcon fromTheme(const QString &name)
void itemSelectionChanged()
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * parent() const const
QStringRef name() const const
QString text() const const
Q_EMITQ_EMIT
void itemDoubleClicked(QListWidgetItem *item)
void setText(const QString &text)
ButtonCode warningYesNo(QWidget *parent, const QString &text, const QString &caption=QString(), const KGuiItem &buttonYes=KStandardGuiItem::yes(), const KGuiItem &buttonNo=KStandardGuiItem::no(), const QString &dontAskAgainName=QString(), Options options=Options(Notify|Dangerous))
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Fri Apr 16 2021 23:09:34 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.