8#include "customtemplates.h"
9#include "customtemplates_kfg.h"
10#include "globalsettings_templateparser.h"
11#include "templateparser/templatesinsertcommandpushbutton.h"
12#include "templateparseremailaddressrequesterinterfacewidget.h"
13#include "ui_customtemplates_base.h"
14#include <KLineEditEventHandler>
15#include <TextCustomEditor/PlainTextEditor>
17#include <KLocalizedString>
23using namespace TemplateParser;
27 , mUi(new Ui_CustomTemplatesBase)
32 mUi->mAdd->setEnabled(
false);
36 mUi->mList->setColumnWidth(0, 100);
37 mUi->mList->header()->setStretchLastSection(
true);
38 mUi->mList->setItemDelegate(
new CustomTemplateItemDelegate(
this));
39 mUi->mList->header()->setSectionsMovable(
false);
40 mUi->mEditFrame->setEnabled(
false);
44 connect(mUi->mToEdit, &TemplateParser::TemplateParserEmailAddressRequesterInterfaceWidget::textChanged,
this, &CustomTemplates::slotTextChanged);
45 connect(mUi->mCCEdit, &TemplateParser::TemplateParserEmailAddressRequesterInterfaceWidget::textChanged,
this, &CustomTemplates::slotTextChanged);
52 qOverload<const QString &, int>(&TemplateParser::TemplatesInsertCommandPushButton::insertCommand),
54 &CustomTemplates::slotInsertCommand);
65 mUi->mKeySequenceWidget->setCheckActionCollections(actionCollection);
72 mUi->mType->addItem(
QPixmap(),
i18nc(
"Message->",
"Universal"));
73 mUi->mType->addItem(mReplyPix,
i18nc(
"Message->",
"Reply"));
74 mUi->mType->addItem(mReplyAllPix,
i18nc(
"Message->",
"Reply to All"));
75 mUi->mType->addItem(mForwardPix,
i18nc(
"Message->",
"Forward"));
77 mUi->mHelp->setText(
i18n(
"<a href=\"whatsthis\">How does this work?</a>"));
81 slotNameChanged(mUi->mName->text());
84void CustomTemplates::slotHelpLinkClicked(
const QString &)
88 "<p>Here you can add, edit, and delete custom message "
89 "templates to use when you compose a reply or forwarding message. "
90 "Create the custom template by typing the name into the input box "
91 "and press the '+' button. Also, you can bind a keyboard "
92 "combination to the template for faster operations.</p>"
93 "<p>Message templates support substitution commands, "
94 "by simply typing them or selecting them from the "
95 "<i>Insert command</i> menu.</p>"
96 "<p>There are four types of custom templates: used to "
97 "<i>Reply</i>, <i>Reply to All</i>, <i>Forward</i>, and "
98 "<i>Universal</i> which can be used for all kinds of operations. "
99 "You cannot bind a keyboard shortcut to <i>Universal</i> templates.</p>"
105CustomTemplates::~CustomTemplates()
108 disconnect(mUi->mToEdit, &TemplateParser::TemplateParserEmailAddressRequesterInterfaceWidget::textChanged,
this, &CustomTemplates::slotTextChanged);
109 disconnect(mUi->mCCEdit, &TemplateParser::TemplateParserEmailAddressRequesterInterfaceWidget::textChanged,
this, &CustomTemplates::slotTextChanged);
113void CustomTemplates::slotNameChanged(
const QString &text)
115 mUi->mAdd->setEnabled(!text.trimmed().
isEmpty());
118QString CustomTemplates::indexToType(
int index)
123 typeStr =
i18nc(
"Message->",
"Universal");
129 typeStr =
i18nc(
"Message->",
"Reply");
132 typeStr =
i18nc(
"Message->",
"Reply to All");
135 typeStr =
i18nc(
"Message->",
"Forward");
138 typeStr =
i18nc(
"Message->",
"Unknown");
144void CustomTemplates::slotTextChanged()
148 auto vitem =
static_cast<CustomTemplateItem *
>(item);
149 vitem->setContent(mUi->mEdit->toPlainText());
150 if (!mBlockChangeSignal) {
151 vitem->setTo(mUi->mToEdit->text());
152 vitem->setCc(mUi->mCCEdit->text());
156 if (!mBlockChangeSignal) {
161void CustomTemplates::iconFromType(CustomTemplates::Type type, CustomTemplateItem *item)
168 item->
setIcon(0, mReplyAllPix);
179void CustomTemplates::load()
181 const QStringList list = TemplateParserSettings::self()->customTemplates();
187 auto type =
static_cast<Type
>(t.type());
188 auto item =
new CustomTemplateItem(mUi->mList, *it, t.content(), shortcut, type, t.to(), t.cC());
190 item->
setText(0, indexToType(type));
191 iconFromType(type, item);
193 const bool enabled = mUi->mList->topLevelItemCount() > 0 && mUi->mList->currentItem();
194 mUi->mRemove->setEnabled(
enabled);
195 mUi->mDuplicate->setEnabled(
enabled);
198void CustomTemplates::save()
203 for (
const QString &item : std::as_const(mItemsToDelete)) {
205 const QString configGroup = t.currentGroup();
206 config->deleteGroup(configGroup);
212 auto it =
static_cast<CustomTemplateItem *
>(*lit);
217 QString content = it->content();
219 content = QStringLiteral(
"%BLANK");
222 t.setContent(content);
223 t.setShortcut(it->shortcut().toString());
224 t.setType(it->customType());
231 TemplateParserSettings::self()->setCustomTemplates(list);
232 TemplateParserSettings::self()->save();
234 Q_EMIT templatesUpdated();
237void CustomTemplates::slotInsertCommand(
const QString &cmd,
int adjustCursor)
242 mUi->mEdit->editor()->setTextCursor(
cursor);
243 mUi->mEdit->editor()->setFocus();
251 if ((name == str) && ((*lit) != item)) {
260void CustomTemplates::slotAddClicked()
262 const QString str = mUi->mName->text();
264 if (nameAlreadyExists(str)) {
269 auto item =
new CustomTemplateItem(mUi->mList, str,
QString(), nullShortcut, TUniversal,
QString(),
QString());
270 item->
setText(0, indexToType(TUniversal));
272 mUi->mList->setCurrentItem(item);
273 mUi->mRemove->setEnabled(
true);
274 mUi->mDuplicate->setEnabled(
true);
276 mUi->mKeySequenceWidget->setEnabled(
false);
277 if (!mBlockChangeSignal) {
283QString CustomTemplates::createUniqueName(
const QString &name)
const
295 const QString itemName = (*lit)->text(1);
296 if (!itemName.
compare(uniqueName)) {
310void CustomTemplates::slotDuplicateClicked()
316 auto origItem =
static_cast<CustomTemplateItem *
>(currentItem);
317 const QString templateName = createUniqueName(origItem->text(1));
319 CustomTemplates::Type type = origItem->customType();
320 auto item =
new CustomTemplateItem(mUi->mList, templateName, origItem->content(), nullShortcut, type, origItem->to(), origItem->cc());
321 item->
setText(0, indexToType(type));
322 item->
setText(1, templateName);
323 iconFromType(type, item);
325 mUi->mList->setCurrentItem(item);
326 mUi->mRemove->setEnabled(
true);
327 mUi->mDuplicate->setEnabled(
true);
329 mUi->mKeySequenceWidget->setEnabled(type != TUniversal);
334void CustomTemplates::slotRemoveClicked()
344 i18nc(
"@info",
"Do you really want to remove template \"%1\"?", templateName),
345 i18nc(
"@title:window",
"Remove Template?"),
349 mItemsToDelete.
append(templateName);
350 delete mUi->mList->takeTopLevelItem(mUi->mList->indexOfTopLevelItem(item));
351 mUi->mRemove->setEnabled(mUi->mList->topLevelItemCount() > 0);
352 mUi->mDuplicate->setEnabled(mUi->mList->topLevelItemCount() > 0);
353 if (!mBlockChangeSignal) {
359void CustomTemplates::slotListSelectionChanged()
363 mUi->mEditFrame->setEnabled(
true);
364 mUi->mRemove->setEnabled(
true);
365 mUi->mDuplicate->setEnabled(
true);
366 auto vitem =
static_cast<CustomTemplateItem *
>(item);
367 mBlockChangeSignal =
true;
368 mUi->mEdit->setPlainText(vitem->content());
370 CustomTemplates::Type type = vitem->customType();
372 mUi->mType->setCurrentIndex(mUi->mType->findText(indexToType(type)));
373 mUi->mToEdit->setText(vitem->to());
374 mUi->mCCEdit->setText(vitem->cc());
375 mBlockChangeSignal =
false;
382 mUi->mKeySequenceWidget->setEnabled(type != TUniversal);
384 mUi->mEditFrame->setEnabled(
false);
385 mUi->mEdit->editor()->clear();
387 mUi->mKeySequenceWidget->clearKeySequence();
388 mUi->mType->setCurrentIndex(0);
389 mUi->mToEdit->clear();
390 mUi->mCCEdit->clear();
394void CustomTemplates::slotTypeActivated(
int index)
398 auto vitem =
static_cast<CustomTemplateItem *
>(item);
399 auto customtype =
static_cast<Type
>(index);
400 vitem->setCustomType(customtype);
401 vitem->setText(0, indexToType(customtype));
403 iconFromType(customtype, vitem);
406 mUi->mKeySequenceWidget->setEnabled(customtype != TUniversal);
408 if (!mBlockChangeSignal) {
414void CustomTemplates::slotShortcutChanged(
const QKeySequence &newSeq)
418 auto vitem =
static_cast<CustomTemplateItem *
>(item);
419 vitem->setShortcut(newSeq);
420 mUi->mKeySequenceWidget->applyStealShortcut();
423 if (!mBlockChangeSignal) {
428void CustomTemplates::slotItemChanged(
QTreeWidgetItem *item,
int column)
431 auto vitem =
static_cast<CustomTemplateItem *
>(item);
435 const QString oldName = vitem->oldName();
436 if (nameAlreadyExists(newName, item)) {
437 vitem->setText(1, oldName);
440 if (newName != oldName) {
441 mItemsToDelete.
append(oldName);
442 vitem->setOldName(newName);
443 if (!mBlockChangeSignal) {
452CustomTemplateItemDelegate::CustomTemplateItemDelegate(
QObject *parent)
457CustomTemplateItemDelegate::~CustomTemplateItemDelegate() =
default;
461 auto lineEdit =
static_cast<QLineEdit *
>(editor);
462 const QString text = lineEdit->text();
470 if (index.
column() == 1) {
476CustomTemplateItem::CustomTemplateItem(
QTreeWidget *parent,
480 CustomTemplates::Type type,
494CustomTemplateItem::~CustomTemplateItem() =
default;
496void CustomTemplateItem::setCustomType(CustomTemplates::Type type)
501CustomTemplates::Type CustomTemplateItem::customType()
const
506QString CustomTemplateItem::to()
const
511QString CustomTemplateItem::cc()
const
516QString CustomTemplateItem::content()
const
521void CustomTemplateItem::setContent(
const QString &content)
526void CustomTemplateItem::setTo(
const QString &to)
531void CustomTemplateItem::setCc(
const QString &cc)
541void CustomTemplateItem::setShortcut(
const QKeySequence &shortcut)
546QString CustomTemplateItem::oldName()
const
551void CustomTemplateItem::setOldName(
const QString &name)
556#include "moc_customtemplates.cpp"
constexpr bool isEmpty() const
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, QStandardPaths::StandardLocation type=QStandardPaths::GenericConfigLocation)
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
KCRASH_EXPORT void setFlags(KCrash::CrashFlags flags)
void catchReturnKey(QObject *lineEdit)
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)
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
KIOCORE_EXPORT QStringList list(const QString &fileClass)
QString name(StandardAction id)
const QList< QKeySequence > & end()
const QList< QKeySequence > & shortcut(StandardShortcut id)
const QList< QKeySequence > & help()
virtual bool setData(const QModelIndex &index, const QVariant &value, int role)
void activated(int index)
QIcon fromTheme(const QString &name)
void linkActivated(const QString &link)
void textChanged(const QString &text)
void append(QList< T > &&value)
const_iterator constBegin() const const
const_iterator constEnd() const const
bool disconnect(const QMetaObject::Connection &connection)
QObject * parent() const const
int compare(QLatin1StringView s1, const QString &s2, Qt::CaseSensitivity cs)
bool isEmpty() const const
QString number(double n, char format, int precision)
QString trimmed() const const
virtual QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const const override
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
void setText(int column, const QString &text)
QString text(int column) const const
void showText(const QPoint &pos, const QString &text, QWidget *w)