Messagelib

templatesconfiguration.cpp
1 /*
2  * SPDX-FileCopyrightText: 2006 Dmitry Morozhnikov <[email protected]>
3  * SPDX-FileCopyrightText: 2012-2023 Laurent Montel <[email protected]>
4  *
5  * SPDX-License-Identifier: GPL-2.0-or-later
6  */
7 
8 #include "templatesconfiguration.h"
9 #include "globalsettings_templateparser.h"
10 #include "templatesconfiguration_kfg.h"
11 #include <TextCustomEditor/PlainTextEditor>
12 
13 #include "templateparser_debug.h"
14 #include <KLocalizedString>
15 #include <KMessageBox>
16 
17 #include <QWhatsThis>
18 
19 using namespace TemplateParser;
20 class TemplateParser::TemplatesConfigurationPrivate
21 {
22 public:
23  TemplatesConfigurationPrivate() = default;
24 
25  QString mHelpString;
26 };
27 
28 TemplatesConfiguration::TemplatesConfiguration(QWidget *parent, const QString &name)
29  : QWidget(parent)
30  , d(new TemplateParser::TemplatesConfigurationPrivate)
31 {
32  setupUi(this);
33  setObjectName(name);
34 
36  sizeHint();
37 
38  connect(textEdit_new->editor(), &QPlainTextEdit::textChanged, this, &TemplatesConfiguration::slotTextChanged);
39  connect(textEdit_reply->editor(), &QPlainTextEdit::textChanged, this, &TemplatesConfiguration::slotTextChanged);
40  connect(textEdit_reply_all->editor(), &QPlainTextEdit::textChanged, this, &TemplatesConfiguration::slotTextChanged);
41  connect(textEdit_forward->editor(), &QPlainTextEdit::textChanged, this, &TemplatesConfiguration::slotTextChanged);
42  connect(lineEdit_quote, &QLineEdit::textChanged, this, &TemplatesConfiguration::slotTextChanged);
43 
44  connect(mInsertCommand,
45  qOverload<const QString &, int>(&TemplateParser::TemplatesInsertCommandPushButton::insertCommand),
46  this,
47  &TemplatesConfiguration::slotInsertCommand);
48 
49  d->mHelpString = i18n(
50  "<p>Here you can create and manage templates to use when "
51  "composing new messages, replies or forwarded messages.</p>"
52  "<p>The message templates support substitution commands, "
53  "either simply type them or select them from "
54  "the <i>Insert command</i> menu.</p>");
55  const QString templateConfigurationName(name);
56  if (templateConfigurationName == QLatin1String("folder-templates")) {
57  d->mHelpString += i18n(
58  "<p>Templates specified here are folder-specific. "
59  "They override both global templates and per-identity "
60  "templates.</p>");
61  } else if (templateConfigurationName == QLatin1String("identity-templates")) {
62  d->mHelpString += i18n(
63  "<p>Templates specified here are identity-specific. "
64  "They override global templates, but can be overridden by "
65  "per-folder templates if they are specified.</p>");
66  } else {
67  d->mHelpString += i18n(
68  "<p>These are global (default) templates. They can be overridden "
69  "by per-identity templates or per-folder templates "
70  "if they are specified.</p>");
71  }
72 
73  mHelp->setText(i18n("<a href=\"whatsthis\">How does this work?</a>"));
74  connect(mHelp, &QLabel::linkActivated, this, &TemplatesConfiguration::slotHelpLinkClicked);
75  mHelp->setContextMenuPolicy(Qt::NoContextMenu);
76 }
77 
78 TemplatesConfiguration::~TemplatesConfiguration()
79 {
80  disconnect(textEdit_new->editor(), &QPlainTextEdit::textChanged, this, &TemplatesConfiguration::slotTextChanged);
81  disconnect(textEdit_reply->editor(), &QPlainTextEdit::textChanged, this, &TemplatesConfiguration::slotTextChanged);
82  disconnect(textEdit_reply_all->editor(), &QPlainTextEdit::textChanged, this, &TemplatesConfiguration::slotTextChanged);
83  disconnect(textEdit_forward->editor(), &QPlainTextEdit::textChanged, this, &TemplatesConfiguration::slotTextChanged);
84  disconnect(lineEdit_quote, &QLineEdit::textChanged, this, &TemplatesConfiguration::slotTextChanged);
85 }
86 
87 void TemplatesConfiguration::slotHelpLinkClicked(const QString &)
88 {
89  QWhatsThis::showText(QCursor::pos(), d->mHelpString);
90 }
91 
92 void TemplatesConfiguration::slotTextChanged()
93 {
94  Q_EMIT changed();
95 }
96 
97 void TemplatesConfiguration::resetToDefault()
98 {
99  const int choice = KMessageBox::questionTwoActionsCancel(nullptr,
100  i18n("Do you want to reset current template or all templates to default?"),
101  i18nc("@title:window", "Reset to default"),
102  KGuiItem(i18n("Reset Current Template")),
103  KGuiItem(i18n("Reset All Templates")),
105 
106  if (choice == KMessageBox::Cancel) {
107  return;
108  } else if (choice == KMessageBox::ButtonCode::PrimaryAction) {
109  const int toolboxCurrentIndex(toolBox1->currentIndex());
110  if (toolBox1->widget(toolboxCurrentIndex) == page_new) {
111  textEdit_new->setPlainText(DefaultTemplates::defaultNewMessage());
112  } else if (toolBox1->widget(toolboxCurrentIndex) == page_reply) {
113  textEdit_reply->setPlainText(DefaultTemplates::defaultReply());
114  } else if (toolBox1->widget(toolboxCurrentIndex) == page_reply_all) {
115  textEdit_reply_all->setPlainText(DefaultTemplates::defaultReplyAll());
116  } else if (toolBox1->widget(toolboxCurrentIndex) == page_forward) {
117  textEdit_forward->setPlainText(DefaultTemplates::defaultForward());
118  } else {
119  qCDebug(TEMPLATEPARSER_LOG) << "Unknown current page in TemplatesConfiguration!";
120  }
121  } else {
122  textEdit_new->setPlainText(DefaultTemplates::defaultNewMessage());
123  textEdit_reply->setPlainText(DefaultTemplates::defaultReply());
124  textEdit_reply_all->setPlainText(DefaultTemplates::defaultReplyAll());
125  textEdit_forward->setPlainText(DefaultTemplates::defaultForward());
126  }
127  lineEdit_quote->setText(DefaultTemplates::defaultQuoteString());
128 }
129 
130 QLabel *TemplatesConfiguration::helpLabel() const
131 {
132  return mHelp;
133 }
134 
135 void TemplatesConfiguration::loadFromGlobal()
136 {
137  QString str;
138  str = TemplateParserSettings::self()->templateNewMessage();
139  if (str.isEmpty()) {
140  textEdit_new->setPlainText(DefaultTemplates::defaultNewMessage());
141  } else {
142  textEdit_new->setPlainText(str);
143  }
144  str = TemplateParserSettings::self()->templateReply();
145  if (str.isEmpty()) {
146  textEdit_reply->setPlainText(DefaultTemplates::defaultReply());
147  } else {
148  textEdit_reply->setPlainText(str);
149  }
150  str = TemplateParserSettings::self()->templateReplyAll();
151  if (str.isEmpty()) {
152  textEdit_reply_all->setPlainText(DefaultTemplates::defaultReplyAll());
153  } else {
154  textEdit_reply_all->setPlainText(str);
155  }
156  str = TemplateParserSettings::self()->templateForward();
157  if (str.isEmpty()) {
158  textEdit_forward->setPlainText(DefaultTemplates::defaultForward());
159  } else {
160  textEdit_forward->setPlainText(str);
161  }
162  str = TemplateParserSettings::self()->quoteString();
163  if (str.isEmpty()) {
164  lineEdit_quote->setText(DefaultTemplates::defaultQuoteString());
165  } else {
166  lineEdit_quote->setText(str);
167  }
168 }
169 
170 void TemplatesConfiguration::saveToGlobal()
171 {
172  TemplateParserSettings::self()->setTemplateNewMessage(strOrBlank(textEdit_new->toPlainText()));
173  TemplateParserSettings::self()->setTemplateReply(strOrBlank(textEdit_reply->toPlainText()));
174  TemplateParserSettings::self()->setTemplateReplyAll(strOrBlank(textEdit_reply_all->toPlainText()));
175  TemplateParserSettings::self()->setTemplateForward(strOrBlank(textEdit_forward->toPlainText()));
176  TemplateParserSettings::self()->setQuoteString(lineEdit_quote->text());
177  TemplateParserSettings::self()->save();
178 }
179 
180 void TemplatesConfiguration::loadFromIdentity(uint id)
181 {
182  Templates t(configIdString(id));
183 
184  QString str;
185 
186  str = t.templateNewMessage();
187  if (str.isEmpty()) {
188  str = TemplateParserSettings::self()->templateNewMessage();
189  }
190  if (str.isEmpty()) {
191  str = DefaultTemplates::defaultNewMessage();
192  }
193  textEdit_new->setPlainText(str);
194 
195  str = t.templateReply();
196  if (str.isEmpty()) {
197  str = TemplateParserSettings::self()->templateReply();
198  }
199  if (str.isEmpty()) {
200  str = DefaultTemplates::defaultReply();
201  }
202  textEdit_reply->setPlainText(str);
203 
204  str = t.templateReplyAll();
205  if (str.isEmpty()) {
206  str = TemplateParserSettings::self()->templateReplyAll();
207  }
208  if (str.isEmpty()) {
209  str = DefaultTemplates::defaultReplyAll();
210  }
211  textEdit_reply_all->setPlainText(str);
212 
213  str = t.templateForward();
214  if (str.isEmpty()) {
215  str = TemplateParserSettings::self()->templateForward();
216  }
217  if (str.isEmpty()) {
218  str = DefaultTemplates::defaultForward();
219  }
220  textEdit_forward->setPlainText(str);
221 
222  str = t.quoteString();
223  if (str.isEmpty()) {
224  str = TemplateParserSettings::self()->quoteString();
225  }
226  if (str.isEmpty()) {
227  str = DefaultTemplates::defaultQuoteString();
228  }
229  lineEdit_quote->setText(str);
230 }
231 
232 void TemplatesConfiguration::saveToIdentity(uint id)
233 {
234  Templates t(configIdString(id));
235  t.setTemplateNewMessage(strOrBlank(textEdit_new->toPlainText()));
236  t.setTemplateReply(strOrBlank(textEdit_reply->toPlainText()));
237  t.setTemplateReplyAll(strOrBlank(textEdit_reply_all->toPlainText()));
238  t.setTemplateForward(strOrBlank(textEdit_forward->toPlainText()));
239  t.setQuoteString(lineEdit_quote->text());
240  t.save();
241 }
242 
243 void TemplatesConfiguration::loadFromFolder(const QString &id, uint identity)
244 {
245  Templates t(id);
246  Templates *tid = nullptr;
247 
248  if (identity) {
249  tid = new Templates(configIdString(identity));
250  }
251 
252  QString str;
253 
254  str = t.templateNewMessage();
255  if (str.isEmpty() && tid) {
256  str = tid->templateNewMessage();
257  }
258  if (str.isEmpty()) {
259  str = TemplateParserSettings::self()->templateNewMessage();
260  if (str.isEmpty()) {
261  str = DefaultTemplates::defaultNewMessage();
262  }
263  }
264  textEdit_new->setPlainText(str);
265 
266  str = t.templateReply();
267  if (str.isEmpty() && tid) {
268  str = tid->templateReply();
269  }
270  if (str.isEmpty()) {
271  str = TemplateParserSettings::self()->templateReply();
272  if (str.isEmpty()) {
273  str = DefaultTemplates::defaultReply();
274  }
275  }
276  textEdit_reply->setPlainText(str);
277 
278  str = t.templateReplyAll();
279  if (str.isEmpty() && tid) {
280  str = tid->templateReplyAll();
281  if (str.isEmpty()) {
282  str = TemplateParserSettings::self()->templateReplyAll();
283  }
284  }
285  if (str.isEmpty()) {
286  str = DefaultTemplates::defaultReplyAll();
287  }
288  textEdit_reply_all->setPlainText(str);
289 
290  str = t.templateForward();
291  if (str.isEmpty() && tid) {
292  str = tid->templateForward();
293  if (str.isEmpty()) {
294  str = TemplateParserSettings::self()->templateForward();
295  }
296  }
297  if (str.isEmpty()) {
298  str = DefaultTemplates::defaultForward();
299  }
300  textEdit_forward->setPlainText(str);
301 
302  str = t.quoteString();
303  if (str.isEmpty() && tid) {
304  str = tid->quoteString();
305  }
306  if (str.isEmpty()) {
307  str = TemplateParserSettings::self()->quoteString();
308  if (str.isEmpty()) {
309  str = DefaultTemplates::defaultQuoteString();
310  }
311  }
312  lineEdit_quote->setText(str);
313 
314  delete (tid);
315 }
316 
317 void TemplatesConfiguration::saveToFolder(const QString &id)
318 {
319  Templates t(id);
320 
321  t.setTemplateNewMessage(strOrBlank(textEdit_new->toPlainText()));
322  t.setTemplateReply(strOrBlank(textEdit_reply->toPlainText()));
323  t.setTemplateReplyAll(strOrBlank(textEdit_reply_all->toPlainText()));
324  t.setTemplateForward(strOrBlank(textEdit_forward->toPlainText()));
325  t.setQuoteString(lineEdit_quote->text());
326  t.save();
327 }
328 
329 QPlainTextEdit *TemplatesConfiguration::currentTextEdit() const
330 {
331  QPlainTextEdit *edit = nullptr;
332 
333  const int toolboxCurrentIndex(toolBox1->currentIndex());
334  if (toolBox1->widget(toolboxCurrentIndex) == page_new) {
335  edit = textEdit_new->editor();
336  } else if (toolBox1->widget(toolboxCurrentIndex) == page_reply) {
337  edit = textEdit_reply->editor();
338  } else if (toolBox1->widget(toolboxCurrentIndex) == page_reply_all) {
339  edit = textEdit_reply_all->editor();
340  } else if (toolBox1->widget(toolboxCurrentIndex) == page_forward) {
341  edit = textEdit_forward->editor();
342  } else {
343  qCDebug(TEMPLATEPARSER_LOG) << "Unknown current page in TemplatesConfiguration!";
344  edit = nullptr;
345  }
346  return edit;
347 }
348 
349 void TemplatesConfiguration::slotInsertCommand(const QString &cmd, int adjustCursor)
350 {
351  QPlainTextEdit *edit = currentTextEdit();
352  if (!edit) {
353  return;
354  }
355 
356  // qCDebug(TEMPLATEPARSER_LOG) << "Insert command:" << cmd;
357  const QString editText(edit->toPlainText());
358  if ((editText.contains(QLatin1String("%FORCEDPLAIN")) && (cmd == QLatin1String("%FORCEDHTML")))
359  || (editText.contains(QLatin1String("%FORCEDHTML")) && (cmd == QLatin1String("%FORCEDPLAIN")))) {
360  KMessageBox::error(this,
361  i18n("Use of \"Reply using plain text\" and \"Reply using HTML text\" in pairs"
362  " is not correct. Use only one of the aforementioned commands with \" Reply as"
363  " Quoted Message command\" as per your need\n"
364  "(a)Reply using plain text for quotes to be strictly in plain text\n"
365  "(b)Reply using HTML text for quotes being in HTML format if present"));
366  } else {
367  QTextCursor cursor = edit->textCursor();
368  cursor.insertText(cmd);
369  cursor.setPosition(cursor.position() + adjustCursor);
370  edit->setTextCursor(cursor);
371  edit->setFocus();
372  }
373 }
374 
375 QString TemplatesConfiguration::strOrBlank(const QString &str)
376 {
377  if (str.trimmed().isEmpty()) {
378  return QStringLiteral("%BLANK");
379  }
380  return str;
381 }
382 
384 {
385  return QStringLiteral("IDENTITY_%1").arg(id);
386 }
387 
388 #include "moc_templatesconfiguration.cpp"
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
void showText(const QPoint &pos, const QString &text, QWidget *w)
Q_EMITQ_EMIT
QString trimmed() const const
void setTextCursor(const QTextCursor &cursor)
NoContextMenu
static QString configIdString(uint id)
Returns the template configuration identifier string for a given identity.
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
void linkActivated(const QString &link)
KGuiItem cancel()
QString toPlainText() const const
QString i18n(const char *text, const TYPE &arg...)
void textChanged(const QString &text)
bool isEmpty() const const
void textChanged()
QPoint pos()
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
ButtonCode questionTwoActionsCancel(QWidget *parent, const QString &text, const QString &title, const KGuiItem &primaryAction, const KGuiItem &secondaryAction, const KGuiItem &cancelAction=KStandardGuiItem::cancel(), const QString &dontAskAgainName=QString(), Options options=Notify)
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
void setObjectName(const QString &name)
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QTextCursor textCursor() const const
void setFocus()
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Sun Dec 3 2023 03:57:08 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.