File indexing completed on 2025-02-16 04:57:43
0001 /* 0002 * SPDX-FileCopyrightText: 2006 Dmitry Morozhnikov <dmiceman@mail.ru> 0003 * SPDX-FileCopyrightText: 2012-2024 Laurent Montel <montel@kde.org> 0004 * 0005 * SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "templatesconfiguration.h" 0009 #include "globalsettings_templateparser.h" 0010 #include "templatesconfiguration_kfg.h" 0011 #include <TextCustomEditor/PlainTextEditor> 0012 0013 #include "templateparser_debug.h" 0014 #include <KLocalizedString> 0015 #include <KMessageBox> 0016 0017 #include <QWhatsThis> 0018 0019 using namespace TemplateParser; 0020 class TemplateParser::TemplatesConfigurationPrivate 0021 { 0022 public: 0023 TemplatesConfigurationPrivate() = default; 0024 0025 QString mHelpString; 0026 }; 0027 0028 TemplatesConfiguration::TemplatesConfiguration(QWidget *parent, const QString &name) 0029 : QWidget(parent) 0030 , d(new TemplateParser::TemplatesConfigurationPrivate) 0031 { 0032 setupUi(this); 0033 setObjectName(name); 0034 0035 setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); 0036 sizeHint(); 0037 0038 connect(textEdit_new->editor(), &QPlainTextEdit::textChanged, this, &TemplatesConfiguration::slotTextChanged); 0039 connect(textEdit_reply->editor(), &QPlainTextEdit::textChanged, this, &TemplatesConfiguration::slotTextChanged); 0040 connect(textEdit_reply_all->editor(), &QPlainTextEdit::textChanged, this, &TemplatesConfiguration::slotTextChanged); 0041 connect(textEdit_forward->editor(), &QPlainTextEdit::textChanged, this, &TemplatesConfiguration::slotTextChanged); 0042 connect(lineEdit_quote, &QLineEdit::textChanged, this, &TemplatesConfiguration::slotTextChanged); 0043 0044 connect(mInsertCommand, 0045 qOverload<const QString &, int>(&TemplateParser::TemplatesInsertCommandPushButton::insertCommand), 0046 this, 0047 &TemplatesConfiguration::slotInsertCommand); 0048 0049 d->mHelpString = i18n( 0050 "<p>Here you can create and manage templates to use when " 0051 "composing new messages, replies or forwarded messages.</p>" 0052 "<p>The message templates support substitution commands, " 0053 "either simply type them or select them from " 0054 "the <i>Insert command</i> menu.</p>"); 0055 const QString templateConfigurationName(name); 0056 if (templateConfigurationName == QLatin1StringView("folder-templates")) { 0057 d->mHelpString += i18n( 0058 "<p>Templates specified here are folder-specific. " 0059 "They override both global templates and per-identity " 0060 "templates.</p>"); 0061 } else if (templateConfigurationName == QLatin1StringView("identity-templates")) { 0062 d->mHelpString += i18n( 0063 "<p>Templates specified here are identity-specific. " 0064 "They override global templates, but can be overridden by " 0065 "per-folder templates if they are specified.</p>"); 0066 } else { 0067 d->mHelpString += i18n( 0068 "<p>These are global (default) templates. They can be overridden " 0069 "by per-identity templates or per-folder templates " 0070 "if they are specified.</p>"); 0071 } 0072 0073 mHelp->setText(i18n("<a href=\"whatsthis\">How does this work?</a>")); 0074 connect(mHelp, &QLabel::linkActivated, this, &TemplatesConfiguration::slotHelpLinkClicked); 0075 mHelp->setContextMenuPolicy(Qt::NoContextMenu); 0076 } 0077 0078 TemplatesConfiguration::~TemplatesConfiguration() 0079 { 0080 disconnect(textEdit_new->editor(), &QPlainTextEdit::textChanged, this, &TemplatesConfiguration::slotTextChanged); 0081 disconnect(textEdit_reply->editor(), &QPlainTextEdit::textChanged, this, &TemplatesConfiguration::slotTextChanged); 0082 disconnect(textEdit_reply_all->editor(), &QPlainTextEdit::textChanged, this, &TemplatesConfiguration::slotTextChanged); 0083 disconnect(textEdit_forward->editor(), &QPlainTextEdit::textChanged, this, &TemplatesConfiguration::slotTextChanged); 0084 disconnect(lineEdit_quote, &QLineEdit::textChanged, this, &TemplatesConfiguration::slotTextChanged); 0085 } 0086 0087 void TemplatesConfiguration::slotHelpLinkClicked(const QString &) 0088 { 0089 QWhatsThis::showText(QCursor::pos(), d->mHelpString); 0090 } 0091 0092 void TemplatesConfiguration::slotTextChanged() 0093 { 0094 Q_EMIT changed(); 0095 } 0096 0097 void TemplatesConfiguration::resetToDefault() 0098 { 0099 const int choice = KMessageBox::questionTwoActionsCancel(nullptr, 0100 i18n("Do you want to reset current template or all templates to default?"), 0101 i18nc("@title:window", "Reset to default"), 0102 KGuiItem(i18n("Reset Current Template")), 0103 KGuiItem(i18n("Reset All Templates")), 0104 KStandardGuiItem::cancel()); 0105 0106 if (choice == KMessageBox::Cancel) { 0107 return; 0108 } else if (choice == KMessageBox::ButtonCode::PrimaryAction) { 0109 const int toolboxCurrentIndex(toolBox1->currentIndex()); 0110 if (toolBox1->widget(toolboxCurrentIndex) == page_new) { 0111 textEdit_new->setPlainText(DefaultTemplates::defaultNewMessage()); 0112 } else if (toolBox1->widget(toolboxCurrentIndex) == page_reply) { 0113 textEdit_reply->setPlainText(DefaultTemplates::defaultReply()); 0114 } else if (toolBox1->widget(toolboxCurrentIndex) == page_reply_all) { 0115 textEdit_reply_all->setPlainText(DefaultTemplates::defaultReplyAll()); 0116 } else if (toolBox1->widget(toolboxCurrentIndex) == page_forward) { 0117 textEdit_forward->setPlainText(DefaultTemplates::defaultForward()); 0118 } else { 0119 qCDebug(TEMPLATEPARSER_LOG) << "Unknown current page in TemplatesConfiguration!"; 0120 } 0121 } else { 0122 textEdit_new->setPlainText(DefaultTemplates::defaultNewMessage()); 0123 textEdit_reply->setPlainText(DefaultTemplates::defaultReply()); 0124 textEdit_reply_all->setPlainText(DefaultTemplates::defaultReplyAll()); 0125 textEdit_forward->setPlainText(DefaultTemplates::defaultForward()); 0126 } 0127 lineEdit_quote->setText(DefaultTemplates::defaultQuoteString()); 0128 } 0129 0130 QLabel *TemplatesConfiguration::helpLabel() const 0131 { 0132 return mHelp; 0133 } 0134 0135 void TemplatesConfiguration::loadFromGlobal() 0136 { 0137 QString str; 0138 str = TemplateParserSettings::self()->templateNewMessage(); 0139 if (str.isEmpty()) { 0140 textEdit_new->setPlainText(DefaultTemplates::defaultNewMessage()); 0141 } else { 0142 textEdit_new->setPlainText(str); 0143 } 0144 str = TemplateParserSettings::self()->templateReply(); 0145 if (str.isEmpty()) { 0146 textEdit_reply->setPlainText(DefaultTemplates::defaultReply()); 0147 } else { 0148 textEdit_reply->setPlainText(str); 0149 } 0150 str = TemplateParserSettings::self()->templateReplyAll(); 0151 if (str.isEmpty()) { 0152 textEdit_reply_all->setPlainText(DefaultTemplates::defaultReplyAll()); 0153 } else { 0154 textEdit_reply_all->setPlainText(str); 0155 } 0156 str = TemplateParserSettings::self()->templateForward(); 0157 if (str.isEmpty()) { 0158 textEdit_forward->setPlainText(DefaultTemplates::defaultForward()); 0159 } else { 0160 textEdit_forward->setPlainText(str); 0161 } 0162 str = TemplateParserSettings::self()->quoteString(); 0163 if (str.isEmpty()) { 0164 lineEdit_quote->setText(DefaultTemplates::defaultQuoteString()); 0165 } else { 0166 lineEdit_quote->setText(str); 0167 } 0168 } 0169 0170 void TemplatesConfiguration::saveToGlobal() 0171 { 0172 TemplateParserSettings::self()->setTemplateNewMessage(strOrBlank(textEdit_new->toPlainText())); 0173 TemplateParserSettings::self()->setTemplateReply(strOrBlank(textEdit_reply->toPlainText())); 0174 TemplateParserSettings::self()->setTemplateReplyAll(strOrBlank(textEdit_reply_all->toPlainText())); 0175 TemplateParserSettings::self()->setTemplateForward(strOrBlank(textEdit_forward->toPlainText())); 0176 TemplateParserSettings::self()->setQuoteString(lineEdit_quote->text()); 0177 TemplateParserSettings::self()->save(); 0178 } 0179 0180 void TemplatesConfiguration::loadFromIdentity(uint id) 0181 { 0182 Templates t(configIdString(id)); 0183 0184 QString str; 0185 0186 str = t.templateNewMessage(); 0187 if (str.isEmpty()) { 0188 str = TemplateParserSettings::self()->templateNewMessage(); 0189 } 0190 if (str.isEmpty()) { 0191 str = DefaultTemplates::defaultNewMessage(); 0192 } 0193 textEdit_new->setPlainText(str); 0194 0195 str = t.templateReply(); 0196 if (str.isEmpty()) { 0197 str = TemplateParserSettings::self()->templateReply(); 0198 } 0199 if (str.isEmpty()) { 0200 str = DefaultTemplates::defaultReply(); 0201 } 0202 textEdit_reply->setPlainText(str); 0203 0204 str = t.templateReplyAll(); 0205 if (str.isEmpty()) { 0206 str = TemplateParserSettings::self()->templateReplyAll(); 0207 } 0208 if (str.isEmpty()) { 0209 str = DefaultTemplates::defaultReplyAll(); 0210 } 0211 textEdit_reply_all->setPlainText(str); 0212 0213 str = t.templateForward(); 0214 if (str.isEmpty()) { 0215 str = TemplateParserSettings::self()->templateForward(); 0216 } 0217 if (str.isEmpty()) { 0218 str = DefaultTemplates::defaultForward(); 0219 } 0220 textEdit_forward->setPlainText(str); 0221 0222 str = t.quoteString(); 0223 if (str.isEmpty()) { 0224 str = TemplateParserSettings::self()->quoteString(); 0225 } 0226 if (str.isEmpty()) { 0227 str = DefaultTemplates::defaultQuoteString(); 0228 } 0229 lineEdit_quote->setText(str); 0230 } 0231 0232 void TemplatesConfiguration::saveToIdentity(uint id) 0233 { 0234 Templates t(configIdString(id)); 0235 t.setTemplateNewMessage(strOrBlank(textEdit_new->toPlainText())); 0236 t.setTemplateReply(strOrBlank(textEdit_reply->toPlainText())); 0237 t.setTemplateReplyAll(strOrBlank(textEdit_reply_all->toPlainText())); 0238 t.setTemplateForward(strOrBlank(textEdit_forward->toPlainText())); 0239 t.setQuoteString(lineEdit_quote->text()); 0240 t.save(); 0241 } 0242 0243 void TemplatesConfiguration::loadFromFolder(const QString &id, uint identity) 0244 { 0245 Templates t(id); 0246 Templates *tid = nullptr; 0247 0248 if (identity) { 0249 tid = new Templates(configIdString(identity)); 0250 } 0251 0252 QString str; 0253 0254 str = t.templateNewMessage(); 0255 if (str.isEmpty() && tid) { 0256 str = tid->templateNewMessage(); 0257 } 0258 if (str.isEmpty()) { 0259 str = TemplateParserSettings::self()->templateNewMessage(); 0260 if (str.isEmpty()) { 0261 str = DefaultTemplates::defaultNewMessage(); 0262 } 0263 } 0264 textEdit_new->setPlainText(str); 0265 0266 str = t.templateReply(); 0267 if (str.isEmpty() && tid) { 0268 str = tid->templateReply(); 0269 } 0270 if (str.isEmpty()) { 0271 str = TemplateParserSettings::self()->templateReply(); 0272 if (str.isEmpty()) { 0273 str = DefaultTemplates::defaultReply(); 0274 } 0275 } 0276 textEdit_reply->setPlainText(str); 0277 0278 str = t.templateReplyAll(); 0279 if (str.isEmpty() && tid) { 0280 str = tid->templateReplyAll(); 0281 if (str.isEmpty()) { 0282 str = TemplateParserSettings::self()->templateReplyAll(); 0283 } 0284 } 0285 if (str.isEmpty()) { 0286 str = DefaultTemplates::defaultReplyAll(); 0287 } 0288 textEdit_reply_all->setPlainText(str); 0289 0290 str = t.templateForward(); 0291 if (str.isEmpty() && tid) { 0292 str = tid->templateForward(); 0293 if (str.isEmpty()) { 0294 str = TemplateParserSettings::self()->templateForward(); 0295 } 0296 } 0297 if (str.isEmpty()) { 0298 str = DefaultTemplates::defaultForward(); 0299 } 0300 textEdit_forward->setPlainText(str); 0301 0302 str = t.quoteString(); 0303 if (str.isEmpty() && tid) { 0304 str = tid->quoteString(); 0305 } 0306 if (str.isEmpty()) { 0307 str = TemplateParserSettings::self()->quoteString(); 0308 if (str.isEmpty()) { 0309 str = DefaultTemplates::defaultQuoteString(); 0310 } 0311 } 0312 lineEdit_quote->setText(str); 0313 0314 delete (tid); 0315 } 0316 0317 void TemplatesConfiguration::saveToFolder(const QString &id) 0318 { 0319 Templates t(id); 0320 0321 t.setTemplateNewMessage(strOrBlank(textEdit_new->toPlainText())); 0322 t.setTemplateReply(strOrBlank(textEdit_reply->toPlainText())); 0323 t.setTemplateReplyAll(strOrBlank(textEdit_reply_all->toPlainText())); 0324 t.setTemplateForward(strOrBlank(textEdit_forward->toPlainText())); 0325 t.setQuoteString(lineEdit_quote->text()); 0326 t.save(); 0327 } 0328 0329 QPlainTextEdit *TemplatesConfiguration::currentTextEdit() const 0330 { 0331 QPlainTextEdit *edit = nullptr; 0332 0333 const int toolboxCurrentIndex(toolBox1->currentIndex()); 0334 if (toolBox1->widget(toolboxCurrentIndex) == page_new) { 0335 edit = textEdit_new->editor(); 0336 } else if (toolBox1->widget(toolboxCurrentIndex) == page_reply) { 0337 edit = textEdit_reply->editor(); 0338 } else if (toolBox1->widget(toolboxCurrentIndex) == page_reply_all) { 0339 edit = textEdit_reply_all->editor(); 0340 } else if (toolBox1->widget(toolboxCurrentIndex) == page_forward) { 0341 edit = textEdit_forward->editor(); 0342 } else { 0343 qCDebug(TEMPLATEPARSER_LOG) << "Unknown current page in TemplatesConfiguration!"; 0344 edit = nullptr; 0345 } 0346 return edit; 0347 } 0348 0349 void TemplatesConfiguration::slotInsertCommand(const QString &cmd, int adjustCursor) 0350 { 0351 QPlainTextEdit *edit = currentTextEdit(); 0352 if (!edit) { 0353 return; 0354 } 0355 0356 // qCDebug(TEMPLATEPARSER_LOG) << "Insert command:" << cmd; 0357 const QString editText(edit->toPlainText()); 0358 if ((editText.contains(QLatin1StringView("%FORCEDPLAIN")) && (cmd == QLatin1StringView("%FORCEDHTML"))) 0359 || (editText.contains(QLatin1StringView("%FORCEDHTML")) && (cmd == QLatin1StringView("%FORCEDPLAIN")))) { 0360 KMessageBox::error(this, 0361 i18n("Use of \"Reply using plain text\" and \"Reply using HTML text\" in pairs" 0362 " is not correct. Use only one of the aforementioned commands with \" Reply as" 0363 " Quoted Message command\" as per your need\n" 0364 "(a)Reply using plain text for quotes to be strictly in plain text\n" 0365 "(b)Reply using HTML text for quotes being in HTML format if present")); 0366 } else { 0367 QTextCursor cursor = edit->textCursor(); 0368 cursor.insertText(cmd); 0369 cursor.setPosition(cursor.position() + adjustCursor); 0370 edit->setTextCursor(cursor); 0371 edit->setFocus(); 0372 } 0373 } 0374 0375 QString TemplatesConfiguration::strOrBlank(const QString &str) 0376 { 0377 if (str.trimmed().isEmpty()) { 0378 return QStringLiteral("%BLANK"); 0379 } 0380 return str; 0381 } 0382 0383 QString TemplatesConfiguration::configIdString(uint id) 0384 { 0385 return QStringLiteral("IDENTITY_%1").arg(id); 0386 } 0387 0388 #include "moc_templatesconfiguration.cpp"