Mailcommon

snippetsmanager.cpp
1 /*
2  SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
3  SPDX-FileContributor: Tobias Koenig <[email protected]>
4 
5  SPDX-FileCopyrightText: 2019-2023 Laurent Montel <[email protected]>
6 
7  SPDX-License-Identifier: LGPL-2.0-or-later
8 */
9 
10 #include "snippetsmanager.h"
11 #include "mailcommon_debug.h"
12 #include "snippetdialog.h"
13 #include "snippetsmodel.h"
14 #include "snippetvariabledialog.h"
15 #include <KActionCollection>
16 #include <KSharedConfig>
17 
18 #include <KLocalizedString>
19 #include <KMessageBox>
20 #include <QIcon>
21 
22 #include <QAction>
23 #include <QItemSelectionModel>
24 #include <QPointer>
25 #include <QRegularExpression>
26 
27 using namespace MailCommon;
28 
29 class Q_DECL_HIDDEN SnippetsManager::SnippetsManagerPrivate
30 {
31 public:
32  SnippetsManagerPrivate(SnippetsManager *qq, QWidget *parentWidget)
33  : q(qq)
34  , mParent(parentWidget)
35  {
36  }
37 
38  Q_REQUIRED_RESULT QModelIndex currentGroupIndex() const;
39 
40  void selectionChanged();
41  void dndDone();
42  void addSnippet();
43  void editSnippet();
44  void deleteSnippet();
45 
46  void addSnippetGroup();
47  void editSnippetGroup();
48  void deleteSnippetGroup();
49 
50  void insertSelectedSnippet();
51  void insertActionSnippet();
52 
53  void createSnippet(const QString &text = QString());
54 
55  void slotAddNewDndSnippset(const QString &);
56 
57  void updateActionCollection(const QString &oldName,
58  const QString &newName,
59  const QKeySequence &keySequence,
60  const QString &text,
61  const QString &subject,
62  const QString &to,
63  const QString &cc,
64  const QString &bcc,
65  const QString &attachment);
66  void initializeAction(const QString &newName,
67  const QKeySequence &keySequence,
68  const QString &text,
69  const QString &subject,
70  const QString &to,
71  const QString &cc,
72  const QString &bcc,
73  const QString &attachment);
74  void initializeActionCollection();
75 
76  QString replaceVariables(const QString &text);
77 
78  void save();
79 
80  SnippetsManager *const q;
81  SnippetsModel *mModel = nullptr;
82  QItemSelectionModel *mSelectionModel = nullptr;
83  KActionCollection *mActionCollection = nullptr;
84  QAction *mAddSnippetAction = nullptr;
85  QAction *mEditSnippetAction = nullptr;
86  QAction *mDeleteSnippetAction = nullptr;
87  QAction *mAddSnippetGroupAction = nullptr;
88  QAction *mEditSnippetGroupAction = nullptr;
89  QAction *mDeleteSnippetGroupAction = nullptr;
90  QAction *mInsertSnippetAction = nullptr;
91  QWidget *mParent = nullptr;
92  bool mDirty = false;
93 };
94 
95 QModelIndex SnippetsManager::SnippetsManagerPrivate::currentGroupIndex() const
96 {
97  if (mSelectionModel->selectedIndexes().isEmpty()) {
98  return {};
99  }
100 
101  const QModelIndex index = mSelectionModel->selectedIndexes().first();
102  if (index.data(SnippetsModel::IsGroupRole).toBool()) {
103  return index;
104  } else {
105  return mModel->parent(index);
106  }
107 }
108 
109 void SnippetsManager::SnippetsManagerPrivate::selectionChanged()
110 {
111  const bool itemSelected = !mSelectionModel->selectedIndexes().isEmpty();
112 
113  if (itemSelected) {
114  const QModelIndex index = mSelectionModel->selectedIndexes().first();
115  const bool isGroup = index.data(SnippetsModel::IsGroupRole).toBool();
116  if (isGroup) {
117  mEditSnippetAction->setEnabled(false);
118  mDeleteSnippetAction->setEnabled(false);
119  mEditSnippetGroupAction->setEnabled(true);
120  mDeleteSnippetGroupAction->setEnabled(true);
121  mInsertSnippetAction->setEnabled(false);
122  } else {
123  mEditSnippetAction->setEnabled(true);
124  mDeleteSnippetAction->setEnabled(true);
125  mEditSnippetGroupAction->setEnabled(false);
126  mDeleteSnippetGroupAction->setEnabled(false);
127  mInsertSnippetAction->setEnabled(true);
128  }
129  } else {
130  mEditSnippetAction->setEnabled(false);
131  mDeleteSnippetAction->setEnabled(false);
132  mEditSnippetGroupAction->setEnabled(false);
133  mDeleteSnippetGroupAction->setEnabled(false);
134  mInsertSnippetAction->setEnabled(false);
135  }
136 }
137 
138 void SnippetsManager::SnippetsManagerPrivate::addSnippet()
139 {
140  createSnippet();
141 }
142 
143 void SnippetsManager::SnippetsManagerPrivate::createSnippet(const QString &text)
144 {
145  const bool noGroupAvailable = (mModel->rowCount() == 0);
146 
147  if (noGroupAvailable) {
148  // create a 'General' snippet group
149  if (!mModel->insertRow(mModel->rowCount(), QModelIndex())) {
150  return;
151  }
152 
153  const QModelIndex groupIndex = mModel->index(mModel->rowCount() - 1, 0, QModelIndex());
154  mModel->setData(groupIndex, i18n("General"), SnippetsModel::NameRole);
155 
156  mSelectionModel->select(groupIndex, QItemSelectionModel::ClearAndSelect);
157  }
158 
159  QPointer<SnippetDialog> dlg = new SnippetDialog(mActionCollection, false, mParent);
160  dlg->setWindowTitle(i18nc("@title:window", "Add Snippet"));
161  dlg->setGroupModel(mModel);
162  dlg->setGroupIndex(currentGroupIndex());
163  dlg->setText(text);
164 
165  q->connect(dlg, &SnippetDialog::rejected, q, [dlg]() {
166  delete dlg;
167  });
168 
169  q->connect(dlg, &SnippetDialog::accepted, q, [dlg, this]() {
170  const QModelIndex groupIndex = dlg->groupIndex();
171 
172  if (!mModel->insertRow(mModel->rowCount(groupIndex), groupIndex)) {
173  delete dlg;
174  return;
175  }
176 
177  const QModelIndex index = mModel->index(mModel->rowCount(groupIndex) - 1, 0, groupIndex);
178  mModel->setData(index, dlg->name(), SnippetsModel::NameRole);
179  mModel->setData(index, dlg->text(), SnippetsModel::TextRole);
180  mModel->setData(index, dlg->keySequence().toString(), SnippetsModel::KeySequenceRole);
181  mModel->setData(index, dlg->keyword(), SnippetsModel::KeywordRole);
182  mModel->setData(index, dlg->subject(), SnippetsModel::SubjectRole);
183  mModel->setData(index, dlg->to(), SnippetsModel::ToRole);
184  mModel->setData(index, dlg->cc(), SnippetsModel::CcRole);
185  mModel->setData(index, dlg->bcc(), SnippetsModel::BccRole);
186  mModel->setData(index, dlg->attachment(), SnippetsModel::AttachmentRole);
187 
188  Q_EMIT mModel->updateActionCollection(QString(),
189  dlg->name(),
190  dlg->keySequence(),
191  dlg->text(),
192  dlg->subject(),
193  dlg->to(),
194  dlg->cc(),
195  dlg->bcc(),
196  dlg->attachment());
197  mDirty = true;
198  save();
199  delete dlg;
200  });
201  dlg->show();
202 }
203 
204 void SnippetsManager::SnippetsManagerPrivate::slotAddNewDndSnippset(const QString &text)
205 {
206  createSnippet(text);
207 }
208 
209 void SnippetsManager::SnippetsManagerPrivate::dndDone()
210 {
211  mDirty = true;
212 }
213 
214 void SnippetsManager::SnippetsManagerPrivate::editSnippet()
215 {
216  QModelIndex index = mSelectionModel->selectedIndexes().first();
217  if (!index.isValid() || index.data(SnippetsModel::IsGroupRole).toBool()) {
218  return;
219  }
220 
221  const QModelIndex oldGroupIndex = currentGroupIndex();
222 
223  const QString oldSnippetName = index.data(SnippetsModel::NameRole).toString();
224 
225  QPointer<SnippetDialog> dlg = new SnippetDialog(mActionCollection, false, mParent);
226  dlg->setWindowTitle(i18nc("@title:window", "Edit Snippet"));
227  dlg->setGroupModel(mModel);
228  dlg->setGroupIndex(oldGroupIndex);
229  dlg->setName(oldSnippetName);
230  dlg->setText(index.data(SnippetsModel::TextRole).toString());
231  dlg->setKeyword(index.data(SnippetsModel::KeywordRole).toString());
232  dlg->setSubject(index.data(SnippetsModel::SubjectRole).toString());
233  dlg->setTo(index.data(SnippetsModel::ToRole).toString());
234  dlg->setCc(index.data(SnippetsModel::CcRole).toString());
235  dlg->setBcc(index.data(SnippetsModel::BccRole).toString());
236  dlg->setAttachment(index.data(SnippetsModel::AttachmentRole).toString());
238  q->connect(dlg, &SnippetDialog::rejected, q, [dlg]() {
239  delete dlg;
240  });
241 
242  q->connect(dlg, &SnippetDialog::accepted, q, [dlg, this, oldGroupIndex, index, oldSnippetName]() {
243  const QModelIndex newGroupIndex = dlg->groupIndex();
244  QModelIndex oldIndex = index;
245  if (oldGroupIndex != newGroupIndex) {
246  mModel->removeRow(index.row(), oldGroupIndex);
247  mModel->insertRow(mModel->rowCount(newGroupIndex), newGroupIndex);
248 
249  oldIndex = mModel->index(mModel->rowCount(newGroupIndex) - 1, 0, newGroupIndex);
250  }
251 
252  mModel->setData(oldIndex, dlg->name(), SnippetsModel::NameRole);
253  mModel->setData(oldIndex, dlg->text(), SnippetsModel::TextRole);
254  mModel->setData(oldIndex, dlg->keySequence().toString(), SnippetsModel::KeySequenceRole);
255  mModel->setData(oldIndex, dlg->keyword(), SnippetsModel::KeywordRole);
256  mModel->setData(oldIndex, dlg->subject(), SnippetsModel::SubjectRole);
257  mModel->setData(oldIndex, dlg->to(), SnippetsModel::ToRole);
258  mModel->setData(oldIndex, dlg->cc(), SnippetsModel::CcRole);
259  mModel->setData(oldIndex, dlg->bcc(), SnippetsModel::BccRole);
260  mModel->setData(oldIndex, dlg->attachment(), SnippetsModel::AttachmentRole);
261 
262  Q_EMIT mModel->updateActionCollection(oldSnippetName,
263  dlg->name(),
264  dlg->keySequence(),
265  dlg->text(),
266  dlg->subject(),
267  dlg->to(),
268  dlg->cc(),
269  dlg->bcc(),
270  dlg->attachment());
271  mDirty = true;
272  save();
273  delete dlg;
274  });
275  dlg->show();
276 }
277 
278 void SnippetsManager::SnippetsManagerPrivate::deleteSnippet()
279 {
280  const QModelIndex index = mSelectionModel->selectedIndexes().first();
281 
282  const QString snippetName = index.data(SnippetsModel::NameRole).toString();
283 
285  xi18nc("@info",
286  "Do you really want to remove snippet \"%1\"?<nl/>"
287  "<warning>There is no way to undo the removal.</warning>",
288  snippetName),
289  QString(),
291  == KMessageBox::Cancel) {
292  return;
293  }
294 
295  mModel->removeRow(index.row(), currentGroupIndex());
296 
297  Q_EMIT mModel->updateActionCollection(snippetName, QString(), QKeySequence(), QString(), QString(), QString(), QString(), QString(), QString());
298  mDirty = true;
299  save();
300 }
301 
302 void SnippetsManager::SnippetsManagerPrivate::addSnippetGroup()
303 {
304  QPointer<SnippetDialog> dlg = new SnippetDialog(mActionCollection, true, mParent);
305  dlg->setWindowTitle(i18nc("@title:window", "Add Group"));
306 
307  if (dlg->exec()) {
308  if (!mModel->insertRow(mModel->rowCount(), QModelIndex())) {
309  qCDebug(MAILCOMMON_LOG) << "unable to insert row";
310  delete dlg;
311  return;
312  }
313 
314  const QModelIndex groupIndex = mModel->index(mModel->rowCount() - 1, 0, QModelIndex());
315  mModel->setData(groupIndex, dlg->name(), SnippetsModel::NameRole);
316  mDirty = true;
317  save();
318  }
319  delete dlg;
320 }
321 
322 void SnippetsManager::SnippetsManagerPrivate::editSnippetGroup()
323 {
324  const QModelIndex groupIndex = currentGroupIndex();
325  if (!groupIndex.isValid() || !groupIndex.data(SnippetsModel::IsGroupRole).toBool()) {
326  return;
327  }
328 
329  QPointer<SnippetDialog> dlg = new SnippetDialog(mActionCollection, true, mParent);
330  dlg->setWindowTitle(i18nc("@title:window", "Edit Group"));
331  const QString oldGroupName = groupIndex.data(SnippetsModel::NameRole).toString();
332  dlg->setName(oldGroupName);
333 
334  if (dlg->exec()) {
335  if (oldGroupName == dlg->name()) {
336  delete dlg;
337  return;
338  }
339 
340  mModel->setData(groupIndex, dlg->name(), SnippetsModel::NameRole);
341  mDirty = true;
342  save();
343  }
344  delete dlg;
345 }
346 
347 void SnippetsManager::SnippetsManagerPrivate::deleteSnippetGroup()
348 {
349  const QModelIndex groupIndex = currentGroupIndex();
350  if (!groupIndex.isValid()) {
351  return;
352  }
353 
354  const QString groupName = groupIndex.data(SnippetsModel::NameRole).toString();
355 
356  if (mModel->rowCount(groupIndex) > 0) {
358  xi18nc("@info",
359  "Do you really want to remove group \"%1\" along with all its snippets?<nl/>"
360  "<warning>There is no way to undo the removal.</warning>",
361  groupName),
362  QString(),
364  == KMessageBox::Cancel) {
365  return;
366  }
367  } else {
369  i18nc("@info", "Do you really want to remove group \"%1\"?", groupName),
370  QString(),
372  == KMessageBox::Cancel) {
373  return;
374  }
375  }
376 
377  mModel->removeRow(groupIndex.row(), QModelIndex());
378  mDirty = true;
379  save();
380 }
381 
382 void SnippetsManager::SnippetsManagerPrivate::insertSelectedSnippet()
383 {
384  if (!mSelectionModel->hasSelection()) {
385  return;
386  }
387 
388  const QModelIndex index = mSelectionModel->selectedIndexes().first();
389  if (index.data(SnippetsModel::IsGroupRole).toBool()) {
390  return;
391  }
392 
393  const QString text = replaceVariables(index.data(SnippetsModel::TextRole).toString());
394  const QString subject = replaceVariables(index.data(SnippetsModel::SubjectRole).toString());
395  const QString to = index.data(SnippetsModel::ToRole).toString();
396  const QString cc = index.data(SnippetsModel::CcRole).toString();
397  const QString bcc = index.data(SnippetsModel::BccRole).toString();
398  const QString attachment = index.data(SnippetsModel::AttachmentRole).toString();
399  Q_EMIT q->insertSnippetInfo({subject, text, to, cc, bcc, attachment});
400 }
401 
402 void SnippetsManager::SnippetsManagerPrivate::insertActionSnippet()
403 {
404  auto action = qobject_cast<QAction *>(q->sender());
405  if (!action) {
406  return;
407  }
408 
409  const QString text = replaceVariables(action->property("snippetText").toString());
410  const QString subject = replaceVariables(action->property("snippetSubject").toString());
411  const QString to = action->property("snippetTo").toString();
412  const QString cc = action->property("snippetCc").toString();
413  const QString bcc = action->property("snippetBcc").toString();
414  const QString attachment = action->property("snippetAttachment").toString();
415  Q_EMIT q->insertSnippetInfo({subject, text, to, cc, bcc, attachment});
416 }
417 
418 void SnippetsManager::SnippetsManagerPrivate::initializeActionCollection()
419 {
420  if (mActionCollection) {
421  const QList<SnippetsInfo> infos = mModel->snippetsInfo();
422  for (const SnippetsInfo &info : infos) {
423  initializeAction(info.newName, info.keySequence, info.text, info.subject, info.to, info.cc, info.bcc, info.attachment);
424  }
425  }
426 }
427 
428 void SnippetsManager::SnippetsManagerPrivate::initializeAction(const QString &newName,
429  const QKeySequence &keySequence,
430  const QString &text,
431  const QString &subject,
432  const QString &to,
433  const QString &cc,
434  const QString &bcc,
435  const QString &attachment)
436 {
437  const QString actionName = i18nc("@action", "Snippet %1", newName);
438  const QString normalizedName = QString(actionName).replace(QLatin1Char(' '), QLatin1Char('_'));
439 
440  QAction *action = mActionCollection->addAction(normalizedName, q);
441  connect(action, &QAction::triggered, q, [this]() {
442  insertActionSnippet();
443  });
444  action->setProperty("snippetText", text);
445  action->setProperty("snippetSubject", subject);
446  action->setProperty("snippetTo", to);
447  action->setProperty("snippetCc", cc);
448  action->setProperty("snippetBcc", bcc);
449  action->setProperty("snippetAttachment", attachment);
450  action->setText(actionName);
451  mActionCollection->setDefaultShortcut(action, keySequence);
452 }
453 
454 void SnippetsManager::SnippetsManagerPrivate::updateActionCollection(const QString &oldName,
455  const QString &newName,
456  const QKeySequence &keySequence,
457  const QString &text,
458  const QString &subject,
459  const QString &to,
460  const QString &cc,
461  const QString &bcc,
462  const QString &attachment)
463 {
464  // remove previous action in case that the name changed
465  if (!oldName.isEmpty() && mActionCollection) {
466  const QString actionName = i18nc("@action", "Snippet %1", oldName);
467  const QString normalizedName = QString(actionName).replace(QLatin1Char(' '), QLatin1Char('_'));
468 
469  QAction *action = mActionCollection->action(normalizedName);
470  if (action) {
471  mActionCollection->removeAction(action);
472  }
473  }
474 
475  if (!newName.isEmpty()) {
476  initializeAction(newName, keySequence, text, subject, to, cc, bcc, attachment);
477  }
478 }
479 
480 QString SnippetsManager::SnippetsManagerPrivate::replaceVariables(const QString &text)
481 {
482  QString result = text;
483  QString variableName;
484  QString variableValue;
485  QMap<QString, QString> localVariables(SnippetsModel::instance()->savedVariables());
486  int iFound = -1;
487  int iEnd = -1;
488  QMap<QString, QString> tempLocalVariables(localVariables);
489  do {
490  // find the next variable by this regex
491  iFound = text.indexOf(QRegularExpression(QStringLiteral("\\$[A-Za-z\\-_0-9\\s]*\\$")), iEnd + 1);
492  if (iFound >= 0) {
493  iEnd = text.indexOf(QLatin1Char('$'), iFound + 1) + 1;
494 
495  variableName = text.mid(iFound, iEnd - iFound);
496 
497  if (variableName != QLatin1String("$$")) { // if not double-delimiter
498  if (!localVariables.contains(variableName)) { // and not already in map
499  QPointer<SnippetVariableDialog> dlg = new SnippetVariableDialog(variableName, &tempLocalVariables, mParent);
500  if (dlg->exec()) {
501  if (dlg->saveVariableIsChecked()) {
502  mDirty = true;
503  }
504  variableValue = dlg->variableValue();
505  } else {
506  delete dlg;
507  return {};
508  }
509  delete dlg;
510  } else {
511  variableValue = localVariables.value(variableName);
512  }
513  } else {
514  variableValue = QLatin1Char('$'); // if double-delimiter -> replace by single character
515  }
516 
517  result.replace(variableName, variableValue);
518  localVariables[variableName] = variableValue;
519  }
520  } while (iFound != -1);
521  SnippetsModel::instance()->setSavedVariables(tempLocalVariables);
522 
523  return result;
524 }
525 
526 void SnippetsManager::SnippetsManagerPrivate::save()
527 {
528  if (!mDirty) {
529  return;
530  }
531 
532  SnippetsModel::instance()->save();
533  mDirty = false;
534 }
535 
536 SnippetsManager::SnippetsManager(KActionCollection *actionCollection, QObject *parent, QWidget *parentWidget)
537  : QObject(parent)
538  , d(new SnippetsManagerPrivate(this, parentWidget))
539 {
540  d->mModel = SnippetsModel::instance();
541  connect(d->mModel,
542  &SnippetsModel::updateActionCollection,
543  this,
544  [this](const QString &oldName,
545  const QString &newName,
546  const QKeySequence &keySequence,
547  const QString &text,
548  const QString &subject,
549  const QString &to,
550  const QString &cc,
551  const QString &bcc,
552  const QString &attachment) {
553  d->updateActionCollection(oldName, newName, keySequence, text, subject, to, cc, bcc, attachment);
554  });
555  d->mSelectionModel = new QItemSelectionModel(d->mModel);
556  d->mActionCollection = actionCollection;
557 
558  d->mAddSnippetAction = new QAction(i18n("Add Snippet..."), this);
559  d->mAddSnippetAction->setIcon(QIcon::fromTheme(QStringLiteral("list-add")));
560  d->mEditSnippetAction = new QAction(i18n("Edit Snippet..."), this);
561  d->mEditSnippetAction->setIcon(QIcon::fromTheme(QStringLiteral("document-properties")));
562  d->mDeleteSnippetAction = new QAction(i18n("Remove Snippet"), this);
563  d->mDeleteSnippetAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-delete")));
564 
565  d->mAddSnippetGroupAction = new QAction(i18n("Add Group..."), this);
566  d->mAddSnippetGroupAction->setIcon(QIcon::fromTheme(QStringLiteral("list-add")));
567  d->mEditSnippetGroupAction = new QAction(i18n("Rename Group..."), this);
568  d->mEditSnippetGroupAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-rename")));
569  d->mDeleteSnippetGroupAction = new QAction(i18n("Remove Group"), this);
570  d->mDeleteSnippetGroupAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-delete")));
571 
572  d->mInsertSnippetAction = new QAction(i18n("Insert Snippet"), this);
573  d->mInsertSnippetAction->setIcon(QIcon::fromTheme(QStringLiteral("insert-text")));
574 
575  connect(d->mSelectionModel, &QItemSelectionModel::selectionChanged, this, [this]() {
576  d->selectionChanged();
577  });
578  connect(d->mModel, &SnippetsModel::dndDone, this, [this]() {
579  d->dndDone();
580  });
581  connect(d->mModel, &SnippetsModel::addNewDndSnippset, this, [this](const QString &str) {
582  d->slotAddNewDndSnippset(str);
583  });
584 
585  connect(d->mAddSnippetAction, &QAction::triggered, this, [this]() {
586  d->addSnippet();
587  });
588  connect(d->mEditSnippetAction, &QAction::triggered, this, [this]() {
589  d->editSnippet();
590  });
591  connect(d->mDeleteSnippetAction, &QAction::triggered, this, [this]() {
592  d->deleteSnippet();
593  });
594 
595  connect(d->mAddSnippetGroupAction, &QAction::triggered, this, [this]() {
596  d->addSnippetGroup();
597  });
598  connect(d->mEditSnippetGroupAction, &QAction::triggered, this, [this]() {
599  d->editSnippetGroup();
600  });
601  connect(d->mDeleteSnippetGroupAction, &QAction::triggered, this, [this]() {
602  d->deleteSnippetGroup();
603  });
604 
605  connect(d->mInsertSnippetAction, &QAction::triggered, this, [this]() {
606  d->insertSelectedSnippet();
607  });
608 
609  d->initializeActionCollection();
610  d->selectionChanged();
611  connect(this, &SnippetsManager::insertSnippet, this, [this]() {
612  d->insertSelectedSnippet();
613  });
614 }
615 
617 {
618  d->save();
619 }
620 
622 {
623  return d->mModel;
624 }
625 
627 {
628  return d->mSelectionModel;
629 }
630 
632 {
633  return d->mAddSnippetAction;
634 }
635 
637 {
638  return d->mEditSnippetAction;
639 }
640 
642 {
643  return d->mDeleteSnippetAction;
644 }
645 
647 {
648  return d->mAddSnippetGroupAction;
649 }
650 
652 {
653  return d->mEditSnippetGroupAction;
654 }
655 
657 {
658  return d->mDeleteSnippetGroupAction;
659 }
660 
662 {
663  return d->mInsertSnippetAction;
664 }
665 
667 {
668  if (d->mSelectionModel->selectedIndexes().isEmpty()) {
669  return false;
670  }
671 
672  return d->mSelectionModel->selectedIndexes().first().data(SnippetsModel::IsGroupRole).toBool();
673 }
674 
676 {
677  if (d->mSelectionModel->selectedIndexes().isEmpty()) {
678  return {};
679  }
680 
681  return d->mSelectionModel->selectedIndexes().first().data(SnippetsModel::NameRole).toString();
682 }
683 
684 #include "moc_snippetsmanager.cpp"
@ IsGroupRole
Returns whether the index represents a group.
Definition: snippetsmodel.h:43
void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
The SnippetsManager class.
QString xi18nc(const char *context, const char *text, const TYPE &arg...)
QAction * deleteSnippetAction() const
Returns the action that handles deleting the currently selected snippet.
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)
QAction * editSnippetAction() const
Returns the action that handles editing the currently selected snippet.
@ NameRole
The name of a snippet or group.
Definition: snippetsmodel.h:44
QIcon fromTheme(const QString &name)
@ BccRole
The Cc of a snippet.
Definition: snippetsmodel.h:51
@ KeySequenceRole
The key sequence to activate a snippet.
Definition: snippetsmodel.h:46
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QItemSelectionModel * selectionModel() const
Returns the selection model that is used by the manager to select the snippet or snippet group to wor...
QAction * addSnippetGroupAction() const
Returns the action that handles adding new snippet groups.
QAction * deleteSnippetGroupAction() const
Returns the action that handles deleting the currently selected snippet group.
QVariant data(int role) const const
QString selectedName() const
Returns the name of the currently selected snippet or snippet group.
QAction * insertSnippetAction() const
Returns the action that handles inserting a snippet into the editor.
QString i18n(const char *text, const TYPE &arg...)
bool isEmpty() const const
void setText(const QString &text)
@ KeywordRole
The keyword which will replace by snippet.
Definition: snippetsmodel.h:47
KGuiItem remove()
QAction * addSnippetAction() const
Returns the action that handles adding new snippets.
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const const
bool isValid() const const
bool toBool() const const
QString & replace(int position, int n, QChar after)
int row() const const
QKeySequence fromString(const QString &str, QKeySequence::SequenceFormat format)
bool setProperty(const char *name, const QVariant &value)
bool snippetGroupSelected() const
Returns whether the currently selected item is a snippet group.
void triggered(bool checked)
@ ToRole
The To of a snippet.
Definition: snippetsmodel.h:49
@ AttachmentRole
The Attachment of a snippet.
Definition: snippetsmodel.h:52
@ TextRole
The text of a snippet.
Definition: snippetsmodel.h:45
QString i18nc(const char *context, const char *text, const TYPE &arg...)
The SnippetsModel class.
Definition: snippetsmodel.h:38
QAbstractItemModel * model() const
Returns the model that represents the snippets.
QModelIndex parent() const const
QChar * data()
~SnippetsManager() override
Destroys the snippets manager.
@ CcRole
The Cc of a snippet.
Definition: snippetsmodel.h:50
SnippetsManager(KActionCollection *actionCollection, QObject *parent=nullptr, QWidget *widget=nullptr)
Creates a new snippets manager.
@ SubjectRole
The subject of a snippet.
Definition: snippetsmodel.h:48
The SnippetsInfo struct.
Definition: snippetsmodel.h:22
QString mid(int position, int n) const const
QAction * editSnippetGroupAction() const
Returns the action that handles editing the currently selected snippet group.
The filter dialog.
QString toString() const const
QAction * save(const QObject *recvr, const char *slot, QObject *parent)
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Sun Oct 1 2023 04:00:19 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.