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>
18#include <KLocalizedString>
23#include <QItemSelectionModel>
25#include <QRegularExpression>
34 , mParent(parentWidget)
38 [[nodiscard]]
QModelIndex currentGroupIndex()
const;
40 void selectionChanged();
46 void addSnippetGroup();
47 void editSnippetGroup();
48 void deleteSnippetGroup();
50 void insertSelectedSnippet();
51 void insertActionSnippet();
55 void slotAddNewDndSnippset(
const QString &);
57 void updateActionCollection(
const QString &oldName,
66 void initializeAction(
const QString &newName,
74 void initializeActionCollection();
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;
95QModelIndex SnippetsManager::SnippetsManagerPrivate::currentGroupIndex()
const
105 return mModel->parent(index);
109void SnippetsManager::SnippetsManagerPrivate::selectionChanged()
111 const bool itemSelected = !mSelectionModel->selectedIndexes().isEmpty();
114 const QModelIndex index = mSelectionModel->selectedIndexes().first();
117 mEditSnippetAction->setEnabled(
false);
118 mDeleteSnippetAction->setEnabled(
false);
119 mEditSnippetGroupAction->setEnabled(
true);
120 mDeleteSnippetGroupAction->setEnabled(
true);
121 mInsertSnippetAction->setEnabled(
false);
123 mEditSnippetAction->setEnabled(
true);
124 mDeleteSnippetAction->setEnabled(
true);
125 mEditSnippetGroupAction->setEnabled(
false);
126 mDeleteSnippetGroupAction->setEnabled(
false);
127 mInsertSnippetAction->setEnabled(
true);
130 mEditSnippetAction->setEnabled(
false);
131 mDeleteSnippetAction->setEnabled(
false);
132 mEditSnippetGroupAction->setEnabled(
false);
133 mDeleteSnippetGroupAction->setEnabled(
false);
134 mInsertSnippetAction->setEnabled(
false);
138void SnippetsManager::SnippetsManagerPrivate::addSnippet()
143void SnippetsManager::SnippetsManagerPrivate::createSnippet(
const QString &text)
145 const bool noGroupAvailable = (mModel->rowCount() == 0);
147 if (noGroupAvailable) {
149 if (!mModel->insertRow(mModel->rowCount(),
QModelIndex())) {
160 dlg->setWindowTitle(
i18nc(
"@title:window",
"Add Snippet"));
161 dlg->setGroupModel(mModel);
162 dlg->setGroupIndex(currentGroupIndex());
172 if (!mModel->insertRow(mModel->rowCount(groupIndex), groupIndex)) {
177 const QModelIndex index = mModel->index(mModel->rowCount(groupIndex) - 1, 0, groupIndex);
204void SnippetsManager::SnippetsManagerPrivate::slotAddNewDndSnippset(
const QString &text)
209void SnippetsManager::SnippetsManagerPrivate::dndDone()
214void SnippetsManager::SnippetsManagerPrivate::editSnippet()
216 QModelIndex index = mSelectionModel->selectedIndexes().first();
221 const QModelIndex oldGroupIndex = currentGroupIndex();
226 dlg->setWindowTitle(
i18nc(
"@title:window",
"Edit Snippet"));
227 dlg->setGroupModel(mModel);
228 dlg->setGroupIndex(oldGroupIndex);
229 dlg->setName(oldSnippetName);
243 const QModelIndex newGroupIndex = dlg->groupIndex();
245 if (oldGroupIndex != newGroupIndex) {
246 mModel->removeRow(index.
row(), oldGroupIndex);
247 mModel->insertRow(mModel->rowCount(newGroupIndex), newGroupIndex);
249 oldIndex = mModel->index(mModel->rowCount(newGroupIndex) - 1, 0, newGroupIndex);
262 Q_EMIT mModel->updateActionCollection(oldSnippetName,
278void SnippetsManager::SnippetsManagerPrivate::deleteSnippet()
280 const QModelIndex index = mSelectionModel->selectedIndexes().first();
286 "Do you really want to remove snippet \"%1\"?<nl/>"
287 "<warning>There is no way to undo the removal.</warning>",
295 mModel->removeRow(index.
row(), currentGroupIndex());
302void SnippetsManager::SnippetsManagerPrivate::addSnippetGroup()
305 dlg->setWindowTitle(
i18nc(
"@title:window",
"Add Group"));
308 if (!mModel->insertRow(mModel->rowCount(),
QModelIndex())) {
309 qCDebug(MAILCOMMON_LOG) <<
"unable to insert row";
322void SnippetsManager::SnippetsManagerPrivate::editSnippetGroup()
324 const QModelIndex groupIndex = currentGroupIndex();
330 dlg->setWindowTitle(
i18nc(
"@title:window",
"Edit Group"));
332 dlg->setName(oldGroupName);
335 if (oldGroupName == dlg->name()) {
347void SnippetsManager::SnippetsManagerPrivate::deleteSnippetGroup()
349 const QModelIndex groupIndex = currentGroupIndex();
356 if (mModel->rowCount(groupIndex) > 0) {
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>",
369 i18nc(
"@info",
"Do you really want to remove group \"%1\"?", groupName),
382void SnippetsManager::SnippetsManagerPrivate::insertSelectedSnippet()
384 if (!mSelectionModel->hasSelection()) {
388 const QModelIndex index = mSelectionModel->selectedIndexes().first();
399 Q_EMIT q->insertSnippetInfo({subject, text, to, cc, bcc, attachment});
402void SnippetsManager::SnippetsManagerPrivate::insertActionSnippet()
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});
418void SnippetsManager::SnippetsManagerPrivate::initializeActionCollection()
420 if (mActionCollection) {
423 initializeAction(info.newName, info.keySequence, info.text, info.subject, info.to, info.cc, info.bcc, info.attachment);
428void SnippetsManager::SnippetsManagerPrivate::initializeAction(
const QString &newName,
437 const QString actionName =
i18nc(
"@action",
"Snippet %1", newName);
440 QAction *action = mActionCollection->addAction(normalizedName, q);
442 insertActionSnippet();
449 action->
setProperty(
"snippetAttachment", attachment);
451 mActionCollection->setDefaultShortcut(action, keySequence);
454void SnippetsManager::SnippetsManagerPrivate::updateActionCollection(
const QString &oldName,
465 if (!oldName.
isEmpty() && mActionCollection) {
466 const QString actionName =
i18nc(
"@action",
"Snippet %1", oldName);
469 QAction *action = mActionCollection->action(normalizedName);
471 mActionCollection->removeAction(action);
476 initializeAction(newName, keySequence, text, subject, to, cc, bcc, attachment);
480QString SnippetsManager::SnippetsManagerPrivate::replaceVariables(
const QString &text)
495 variableName = text.
mid(iFound, iEnd - iFound);
498 if (!localVariables.contains(variableName)) {
501 if (dlg->saveVariableIsChecked()) {
504 variableValue = dlg->variableValue();
511 variableValue = localVariables.value(variableName);
517 result.
replace(variableName, variableValue);
518 localVariables[variableName] = variableValue;
520 }
while (iFound != -1);
521 SnippetsModel::instance()->setSavedVariables(tempLocalVariables);
526void SnippetsManager::SnippetsManagerPrivate::save()
532 SnippetsModel::instance()->save();
538 , d(new SnippetsManagerPrivate(this, parentWidget))
540 d->mModel = SnippetsModel::instance();
542 &SnippetsModel::updateActionCollection,
553 d->updateActionCollection(oldName, newName, keySequence, text, subject, to, cc, bcc, attachment);
556 d->mActionCollection = actionCollection;
558 d->mAddSnippetAction =
new QAction(
i18nc(
"@action",
"Add Snippet…"),
this);
559 d->mAddSnippetAction->setIcon(
QIcon::fromTheme(QStringLiteral(
"list-add")));
560 d->mEditSnippetAction =
new QAction(
i18nc(
"@action",
"Edit Snippet…"),
this);
561 d->mEditSnippetAction->setIcon(
QIcon::fromTheme(QStringLiteral(
"document-properties")));
562 d->mDeleteSnippetAction =
new QAction(
i18nc(
"@action",
"Remove Snippet"),
this);
563 d->mDeleteSnippetAction->setIcon(
QIcon::fromTheme(QStringLiteral(
"edit-delete")));
565 d->mAddSnippetGroupAction =
new QAction(
i18nc(
"@action",
"Add Group…"),
this);
566 d->mAddSnippetGroupAction->setIcon(
QIcon::fromTheme(QStringLiteral(
"list-add")));
567 d->mEditSnippetGroupAction =
new QAction(
i18nc(
"@action",
"Rename Group…"),
this);
568 d->mEditSnippetGroupAction->setIcon(
QIcon::fromTheme(QStringLiteral(
"edit-rename")));
569 d->mDeleteSnippetGroupAction =
new QAction(
i18nc(
"@action",
"Remove Group"),
this);
570 d->mDeleteSnippetGroupAction->setIcon(
QIcon::fromTheme(QStringLiteral(
"edit-delete")));
572 d->mInsertSnippetAction =
new QAction(
i18nc(
"@action",
"Insert Snippet"),
this);
573 d->mInsertSnippetAction->setIcon(
QIcon::fromTheme(QStringLiteral(
"insert-text")));
576 d->selectionChanged();
578 connect(d->mModel, &SnippetsModel::dndDone,
this, [
this]() {
581 connect(d->mModel, &SnippetsModel::addNewDndSnippset,
this, [
this](
const QString &str) {
582 d->slotAddNewDndSnippset(str);
596 d->addSnippetGroup();
599 d->editSnippetGroup();
602 d->deleteSnippetGroup();
606 d->insertSelectedSnippet();
609 d->initializeActionCollection();
610 d->selectionChanged();
611 connect(
this, &SnippetsManager::insertSnippet,
this, [
this]() {
612 d->insertSelectedSnippet();
628 return d->mSelectionModel;
633 return d->mAddSnippetAction;
638 return d->mEditSnippetAction;
643 return d->mDeleteSnippetAction;
648 return d->mAddSnippetGroupAction;
653 return d->mEditSnippetGroupAction;
658 return d->mDeleteSnippetGroupAction;
663 return d->mInsertSnippetAction;
668 if (d->mSelectionModel->selectedIndexes().isEmpty()) {
677 if (d->mSelectionModel->selectedIndexes().isEmpty()) {
684#include "moc_snippetsmanager.cpp"
The SnippetsManager class.
QString selectedName() const
Returns the name of the currently selected snippet or snippet group.
QAction * editSnippetAction() const
Returns the action that handles editing the currently selected snippet.
bool snippetGroupSelected() const
Returns whether the currently selected item is a snippet group.
QAction * deleteSnippetAction() const
Returns the action that handles deleting the currently selected snippet.
QAction * addSnippetAction() const
Returns the action that handles adding new snippets.
QAbstractItemModel * model() const
Returns the model that represents the snippets.
QAction * addSnippetGroupAction() const
Returns the action that handles adding new snippet groups.
QAction * insertSnippetAction() const
Returns the action that handles inserting a snippet into the editor.
QAction * deleteSnippetGroupAction() const
Returns the action that handles deleting the currently selected snippet group.
QItemSelectionModel * selectionModel() const
Returns the selection model that is used by the manager to select the snippet or snippet group to wor...
~SnippetsManager() override
Destroys the snippets manager.
QAction * editSnippetGroupAction() const
Returns the action that handles editing the currently selected snippet group.
SnippetsManager(KActionCollection *actionCollection, QObject *parent=nullptr, QWidget *widget=nullptr)
Creates a new snippets manager.
@ AttachmentRole
The Attachment of a snippet.
@ KeywordRole
The keyword which will replace by snippet.
@ CcRole
The Cc of a snippet.
@ SubjectRole
The subject of a snippet.
@ BccRole
The Cc of a snippet.
@ KeySequenceRole
The key sequence to activate a snippet.
@ IsGroupRole
Returns whether the index represents a group.
@ ToRole
The To of a snippet.
@ NameRole
The name of a snippet or group.
@ TextRole
The text of a snippet.
QString xi18nc(const char *context, const char *text, const TYPE &arg...)
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
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)
const QList< QKeySequence > & save()
void setText(const QString &text)
void triggered(bool checked)
QIcon fromTheme(const QString &name)
void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
QKeySequence fromString(const QString &str, SequenceFormat format)
QVariant data(int role) const const
bool isValid() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QObject * parent() const const
T qobject_cast(QObject *object)
bool setProperty(const char *name, QVariant &&value)
QString first(qsizetype n) const const
qsizetype indexOf(QChar ch, qsizetype from, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
QString mid(qsizetype position, qsizetype n) const const
QString & replace(QChar before, QChar after, Qt::CaseSensitivity cs)
bool toBool() const const
QString toString() const const