File indexing completed on 2025-02-16 04:57:42

0001 /*
0002    SPDX-FileCopyrightText: 2018-2024 Laurent Montel <montel@kde.org>
0003 
0004    SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "templatescommandmenu.h"
0008 
0009 #include "templateparser_debug.h"
0010 #include <KActionMenu>
0011 #include <KLazyLocalizedString>
0012 #include <KLocalizedString>
0013 #include <QAction>
0014 #include <QMenu>
0015 
0016 using namespace TemplateParser;
0017 
0018 struct InsertCommand {
0019     const KLazyLocalizedString name;
0020     const TemplatesCommandMenu::Command command;
0021 
0022     [[nodiscard]] QString getLocalizedDisplayName() const
0023     {
0024         return KLocalizedString(name).toString();
0025     }
0026 };
0027 
0028 static const InsertCommand originalCommands[] = {{kli18n("Quoted Message Text"), TemplatesCommandMenu::CQuote},
0029 
0030                                                  {kli18n("Message Text as Is"), TemplatesCommandMenu::CText},
0031 
0032                                                  {kli18n("Message Id"), TemplatesCommandMenu::COMsgId},
0033 
0034                                                  {kli18n("Date"), TemplatesCommandMenu::CODate},
0035 
0036                                                  {kli18n("Date in Short Format"), TemplatesCommandMenu::CODateShort},
0037 
0038                                                  {kli18n("Date in C Locale"), TemplatesCommandMenu::CODateEn},
0039 
0040                                                  {kli18n("Day of Week"), TemplatesCommandMenu::CODow},
0041 
0042                                                  {kli18n("Time"), TemplatesCommandMenu::COTime},
0043 
0044                                                  {kli18n("Time in Long Format"), TemplatesCommandMenu::COTimeLong},
0045 
0046                                                  {kli18n("Time in C Locale"), TemplatesCommandMenu::COTimeLongEn},
0047 
0048                                                  {kli18n("To Field Address"), TemplatesCommandMenu::COToAddr},
0049 
0050                                                  {kli18n("To Field Name"), TemplatesCommandMenu::COToName},
0051 
0052                                                  {kli18n("To Field First Name"), TemplatesCommandMenu::COToFName},
0053 
0054                                                  {kli18n("To Field Last Name"), TemplatesCommandMenu::COToLName},
0055 
0056                                                  {kli18n("CC Field Address"), TemplatesCommandMenu::COCCAddr},
0057 
0058                                                  {kli18n("CC Field Name"), TemplatesCommandMenu::COCCName},
0059 
0060                                                  {kli18n("CC Field First Name"), TemplatesCommandMenu::COCCFName},
0061 
0062                                                  {kli18n("CC Field Last Name"), TemplatesCommandMenu::COCCLName},
0063 
0064                                                  {kli18n("From Field Address"), TemplatesCommandMenu::COFromAddr},
0065 
0066                                                  {kli18n("From Field Name"), TemplatesCommandMenu::COFromName},
0067 
0068                                                  {kli18n("From Field First Name"), TemplatesCommandMenu::COFromFName},
0069 
0070                                                  {kli18n("From Field Last Name"), TemplatesCommandMenu::COFromLName},
0071 
0072                                                  {kli18n("Addresses of all recipients"), TemplatesCommandMenu::COAddresseesAddr},
0073 
0074                                                  {kli18nc("Template value for subject of the message", "Subject"), TemplatesCommandMenu::COFullSubject},
0075 
0076                                                  {kli18n("Quoted Headers"), TemplatesCommandMenu::CQHeaders},
0077 
0078                                                  {kli18n("Headers as Is"), TemplatesCommandMenu::CHeaders},
0079 
0080                                                  {kli18n("Header Content"), TemplatesCommandMenu::COHeader},
0081 
0082                                                  {kli18n("Reply as Quoted Plain Text"), TemplatesCommandMenu::CQuotePlain},
0083 
0084                                                  {kli18n("Reply as Quoted HTML Text"), TemplatesCommandMenu::CQuoteHtml}};
0085 static const int originalCommandsCount = sizeof(originalCommands) / sizeof(*originalCommands);
0086 
0087 static const InsertCommand currentCommands[] = {{kli18n("Date"), TemplatesCommandMenu::CDate},
0088 
0089                                                 {kli18n("Date in Short Format"), TemplatesCommandMenu::CDateShort},
0090 
0091                                                 {kli18n("Date in C Locale"), TemplatesCommandMenu::CDateEn},
0092 
0093                                                 {kli18n("Day of Week"), TemplatesCommandMenu::CDow},
0094 
0095                                                 {kli18n("Time"), TemplatesCommandMenu::CTime},
0096 
0097                                                 {kli18n("Time in Long Format"), TemplatesCommandMenu::CTimeLong},
0098 
0099                                                 {kli18n("Time in C Locale"), TemplatesCommandMenu::CTimeLongEn},
0100                                                 {kli18n("To Field Address"), TemplatesCommandMenu::CToAddr},
0101 
0102                                                 {kli18n("To Field Name"), TemplatesCommandMenu::CToName},
0103 
0104                                                 {kli18n("To Field First Name"), TemplatesCommandMenu::CToFName},
0105 
0106                                                 {kli18n("To Field Last Name"), TemplatesCommandMenu::CToLName},
0107 
0108                                                 {kli18n("CC Field Address"), TemplatesCommandMenu::CCCAddr},
0109 
0110                                                 {kli18n("CC Field Name"), TemplatesCommandMenu::CCCName},
0111 
0112                                                 {kli18n("CC Field First Name"), TemplatesCommandMenu::CCCFName},
0113 
0114                                                 {kli18n("CC Field Last Name"), TemplatesCommandMenu::CCCLName},
0115 
0116                                                 {kli18n("From Field Address"), TemplatesCommandMenu::CFromAddr},
0117 
0118                                                 {kli18n("From field Name"), TemplatesCommandMenu::CFromName},
0119 
0120                                                 {kli18n("From Field First Name"), TemplatesCommandMenu::CFromFName},
0121 
0122                                                 {kli18n("From Field Last Name"), TemplatesCommandMenu::CFromLName},
0123 
0124                                                 {kli18nc("Template subject command.", "Subject"), TemplatesCommandMenu::CFullSubject},
0125 
0126                                                 {kli18n("Header Content"), TemplatesCommandMenu::CHeader}};
0127 static const int currentCommandsCount = sizeof(currentCommands) / sizeof(*currentCommands);
0128 
0129 static const InsertCommand extCommands[] = {{kli18n("Pipe Original Message Body and Insert Result as Quoted Text"), TemplatesCommandMenu::CQuotePipe},
0130 
0131                                             {kli18n("Pipe Original Message Body and Insert Result as Is"), TemplatesCommandMenu::CTextPipe},
0132 
0133                                             {kli18n("Pipe Original Message with Headers and Insert Result as Is"), TemplatesCommandMenu::CMsgPipe},
0134 
0135                                             {kli18n("Pipe Current Message Body and Insert Result as Is"), TemplatesCommandMenu::CBodyPipe},
0136 
0137                                             {kli18n("Pipe Current Message Body and Replace with Result"), TemplatesCommandMenu::CClearPipe}};
0138 
0139 static const int extCommandsCount = sizeof(extCommands) / sizeof(*extCommands);
0140 
0141 static const InsertCommand miscCommands[] = {
0142     {kli18nc("Inserts user signature, also known as footer, into message", "Signature"), TemplatesCommandMenu::CSignature},
0143 
0144     {kli18n("Insert File Content"), TemplatesCommandMenu::CInsert},
0145 
0146     {kli18nc("All characters, up to and including the next newline, "
0147              "are discarded without performing any macro expansion",
0148              "Discard to Next Line"),
0149      TemplatesCommandMenu::CDnl},
0150 
0151     {kli18n("Template Comment"), TemplatesCommandMenu::CRem},
0152 
0153     {kli18n("No Operation"), TemplatesCommandMenu::CNop},
0154 
0155     {kli18n("Clear Generated Message"), TemplatesCommandMenu::CClear},
0156     {kli18n("Cursor position"), TemplatesCommandMenu::CCursor},
0157 
0158     {kli18n("Blank text"), TemplatesCommandMenu::CBlank},
0159 
0160     {kli18n("Dictionary Language"), TemplatesCommandMenu::CDictionaryLanguage},
0161     {kli18n("Language"), TemplatesCommandMenu::CLanguage},
0162     // TODO add support for custom variable. %CUSTOM="???" ?
0163 };
0164 static const int miscCommandsCount = sizeof(miscCommands) / sizeof(*miscCommands);
0165 
0166 static const InsertCommand debugCommands[] = {{kli18n("Turn Debug On"), TemplatesCommandMenu::CDebug},
0167 
0168                                               {kli18n("Turn Debug Off"), TemplatesCommandMenu::CDebugOff}};
0169 static const int debugCommandsCount = sizeof(debugCommands) / sizeof(*debugCommands);
0170 
0171 void TemplatesCommandMenu::fillMenuFromActionMap(const QMap<QString, TemplatesCommandMenu::Command> &map, KActionMenu *menu)
0172 {
0173     QMap<QString, TemplatesCommandMenu::Command>::const_iterator it = map.constBegin();
0174     QMap<QString, TemplatesCommandMenu::Command>::const_iterator end = map.constEnd();
0175 
0176     while (it != end) {
0177         auto action = new QAction(it.key(), menu); // krazy:exclude=tipsandthis
0178         const TemplatesCommandMenu::Command cmd = it.value();
0179         connect(action, &QAction::triggered, this, [this, cmd] {
0180             slotInsertCommand(cmd);
0181         });
0182         menu->addAction(action);
0183         ++it;
0184     }
0185 }
0186 
0187 TemplatesCommandMenu::TemplatesCommandMenu(QObject *parent)
0188     : QObject(parent)
0189 {
0190 }
0191 
0192 TemplatesCommandMenu::~TemplatesCommandMenu() = default;
0193 
0194 QMenu *TemplatesCommandMenu::menu() const
0195 {
0196     return mMenu->menu();
0197 }
0198 
0199 void TemplatesCommandMenu::fillMenu()
0200 {
0201     mMenu = new KActionMenu(i18n("Insert Command"), this);
0202 }
0203 
0204 void TemplatesCommandMenu::fillSubMenus()
0205 {
0206     if (mWasInitialized) {
0207         return;
0208     }
0209     mWasInitialized = true;
0210     QMap<QString, Command> commandMap;
0211     KActionMenu *menu = nullptr;
0212     // ******************************************************
0213     if (mType & ReplyForwardMessage) {
0214         menu = new KActionMenu(i18n("Original Message"), mMenu);
0215         mMenu->addAction(menu);
0216 
0217         // Map sorts commands
0218         for (int i = 0; i < originalCommandsCount; ++i) {
0219             commandMap.insert(originalCommands[i].getLocalizedDisplayName(), originalCommands[i].command);
0220         }
0221 
0222         fillMenuFromActionMap(commandMap, menu);
0223         commandMap.clear();
0224     }
0225 
0226     // ******************************************************
0227     if (mType & CurrentMessage) {
0228         menu = new KActionMenu(i18n("Current Message"), mMenu);
0229         mMenu->addAction(menu);
0230 
0231         for (int i = 0; i < currentCommandsCount; ++i) {
0232             commandMap.insert(currentCommands[i].getLocalizedDisplayName(), currentCommands[i].command);
0233         }
0234 
0235         fillMenuFromActionMap(commandMap, menu);
0236         commandMap.clear();
0237     }
0238 
0239     // ******************************************************
0240     if (mType & External) {
0241         menu = new KActionMenu(i18n("Process with External Programs"), mMenu);
0242         mMenu->addAction(menu);
0243 
0244         for (int i = 0; i < extCommandsCount; ++i) {
0245             commandMap.insert(extCommands[i].getLocalizedDisplayName(), extCommands[i].command);
0246         }
0247 
0248         fillMenuFromActionMap(commandMap, menu);
0249         commandMap.clear();
0250     }
0251 
0252     // ******************************************************
0253     if (mType & Misc) {
0254         menu = new KActionMenu(i18nc("Miscellaneous template commands menu", "Miscellaneous"), mMenu);
0255         mMenu->addAction(menu);
0256 
0257         for (int i = 0; i < miscCommandsCount; ++i) {
0258             commandMap.insert(miscCommands[i].getLocalizedDisplayName(), miscCommands[i].command);
0259         }
0260 
0261         fillMenuFromActionMap(commandMap, menu);
0262         commandMap.clear();
0263     }
0264 
0265     // ******************************************************
0266     if (!qEnvironmentVariableIsEmpty("KDEPIM_DEBUGGING")) {
0267         if (mType & Debug) {
0268             menu = new KActionMenu(i18nc("Debug template commands menu", "Debug"), mMenu);
0269             mMenu->addAction(menu);
0270 
0271             for (int i = 0; i < debugCommandsCount; ++i) {
0272                 commandMap.insert(debugCommands[i].getLocalizedDisplayName(), debugCommands[i].command);
0273             }
0274 
0275             fillMenuFromActionMap(commandMap, menu);
0276         }
0277     }
0278 }
0279 
0280 TemplatesCommandMenu::MenuTypes TemplatesCommandMenu::type() const
0281 {
0282     return mType;
0283 }
0284 
0285 void TemplatesCommandMenu::setType(MenuTypes type)
0286 {
0287     mType = type;
0288     delete mMenu;
0289     mWasInitialized = false;
0290     fillMenu();
0291     fillSubMenus();
0292 }
0293 
0294 void TemplatesCommandMenu::slotInsertCommand(TemplatesCommandMenu::Command cmd)
0295 {
0296     Q_EMIT insertCommand(cmd);
0297 
0298     switch (cmd) {
0299     case TemplatesCommandMenu::CBlank:
0300         Q_EMIT insertCommand(QStringLiteral("%BLANK"));
0301         return;
0302     case TemplatesCommandMenu::CQuote:
0303         Q_EMIT insertCommand(QStringLiteral("%QUOTE"));
0304         return;
0305     case TemplatesCommandMenu::CText:
0306         Q_EMIT insertCommand(QStringLiteral("%TEXT"));
0307         return;
0308     case TemplatesCommandMenu::COMsgId:
0309         Q_EMIT insertCommand(QStringLiteral("%OMSGID"));
0310         return;
0311     case TemplatesCommandMenu::CODate:
0312         Q_EMIT insertCommand(QStringLiteral("%ODATE"));
0313         return;
0314     case TemplatesCommandMenu::CODateShort:
0315         Q_EMIT insertCommand(QStringLiteral("%ODATESHORT"));
0316         return;
0317     case TemplatesCommandMenu::CODateEn:
0318         Q_EMIT insertCommand(QStringLiteral("%ODATEEN"));
0319         return;
0320     case TemplatesCommandMenu::CODow:
0321         Q_EMIT insertCommand(QStringLiteral("%ODOW"));
0322         return;
0323     case TemplatesCommandMenu::COTime:
0324         Q_EMIT insertCommand(QStringLiteral("%OTIME"));
0325         return;
0326     case TemplatesCommandMenu::COTimeLong:
0327         Q_EMIT insertCommand(QStringLiteral("%OTIMELONG"));
0328         return;
0329     case TemplatesCommandMenu::COTimeLongEn:
0330         Q_EMIT insertCommand(QStringLiteral("%OTIMELONGEN"));
0331         return;
0332     case TemplatesCommandMenu::COToAddr:
0333         Q_EMIT insertCommand(QStringLiteral("%OTOADDR"));
0334         return;
0335     case TemplatesCommandMenu::COToName:
0336         Q_EMIT insertCommand(QStringLiteral("%OTONAME"));
0337         return;
0338     case TemplatesCommandMenu::COToFName:
0339         Q_EMIT insertCommand(QStringLiteral("%OTOFNAME"));
0340         return;
0341     case TemplatesCommandMenu::COToLName:
0342         Q_EMIT insertCommand(QStringLiteral("%OTOLNAME"));
0343         return;
0344     case TemplatesCommandMenu::COCCAddr:
0345         Q_EMIT insertCommand(QStringLiteral("%OCCADDR"));
0346         return;
0347     case TemplatesCommandMenu::COCCName:
0348         Q_EMIT insertCommand(QStringLiteral("%OCCNAME"));
0349         return;
0350     case TemplatesCommandMenu::COCCFName:
0351         Q_EMIT insertCommand(QStringLiteral("%OCCFNAME"));
0352         return;
0353     case TemplatesCommandMenu::COCCLName:
0354         Q_EMIT insertCommand(QStringLiteral("%OCCLNAME"));
0355         return;
0356     case TemplatesCommandMenu::COFromAddr:
0357         Q_EMIT insertCommand(QStringLiteral("%OFROMADDR"));
0358         return;
0359     case TemplatesCommandMenu::COFromName:
0360         Q_EMIT insertCommand(QStringLiteral("%OFROMNAME"));
0361         return;
0362     case TemplatesCommandMenu::COFromFName:
0363         Q_EMIT insertCommand(QStringLiteral("%OFROMFNAME"));
0364         return;
0365     case TemplatesCommandMenu::COFromLName:
0366         Q_EMIT insertCommand(QStringLiteral("%OFROMLNAME"));
0367         return;
0368     case TemplatesCommandMenu::COFullSubject:
0369         Q_EMIT insertCommand(QStringLiteral("%OFULLSUBJECT"));
0370         return;
0371     case TemplatesCommandMenu::CQHeaders:
0372         Q_EMIT insertCommand(QStringLiteral("%QHEADERS"));
0373         return;
0374     case TemplatesCommandMenu::CHeaders:
0375         Q_EMIT insertCommand(QStringLiteral("%HEADERS"));
0376         return;
0377     case TemplatesCommandMenu::COHeader:
0378         Q_EMIT insertCommand(QStringLiteral("%OHEADER=\"\""), -1);
0379         return;
0380     case TemplatesCommandMenu::CMsgId:
0381         Q_EMIT insertCommand(QStringLiteral("%MSGID"));
0382         return;
0383     case TemplatesCommandMenu::CDate:
0384         Q_EMIT insertCommand(QStringLiteral("%DATE"));
0385         return;
0386     case TemplatesCommandMenu::CDateShort:
0387         Q_EMIT insertCommand(QStringLiteral("%DATESHORT"));
0388         return;
0389     case TemplatesCommandMenu::CDateEn:
0390         Q_EMIT insertCommand(QStringLiteral("%DATEEN"));
0391         return;
0392     case TemplatesCommandMenu::CDow:
0393         Q_EMIT insertCommand(QStringLiteral("%DOW"));
0394         return;
0395     case TemplatesCommandMenu::CTime:
0396         Q_EMIT insertCommand(QStringLiteral("%TIME"));
0397         return;
0398     case TemplatesCommandMenu::CTimeLong:
0399         Q_EMIT insertCommand(QStringLiteral("%TIMELONG"));
0400         return;
0401     case TemplatesCommandMenu::CTimeLongEn:
0402         Q_EMIT insertCommand(QStringLiteral("%TIMELONGEN"));
0403         return;
0404     case TemplatesCommandMenu::COAddresseesAddr:
0405         Q_EMIT insertCommand(QStringLiteral("%OADDRESSEESADDR"));
0406         return;
0407     case TemplatesCommandMenu::CToAddr:
0408         Q_EMIT insertCommand(QStringLiteral("%TOADDR"));
0409         return;
0410     case TemplatesCommandMenu::CToName:
0411         Q_EMIT insertCommand(QStringLiteral("%TONAME"));
0412         return;
0413     case TemplatesCommandMenu::CToFName:
0414         Q_EMIT insertCommand(QStringLiteral("%TOFNAME"));
0415         return;
0416     case TemplatesCommandMenu::CToLName:
0417         Q_EMIT insertCommand(QStringLiteral("%TOLNAME"));
0418         return;
0419     case TemplatesCommandMenu::CCCAddr:
0420         Q_EMIT insertCommand(QStringLiteral("%CCADDR"));
0421         return;
0422     case TemplatesCommandMenu::CCCName:
0423         Q_EMIT insertCommand(QStringLiteral("%CCNAME"));
0424         return;
0425     case TemplatesCommandMenu::CCCFName:
0426         Q_EMIT insertCommand(QStringLiteral("%CCFNAME"));
0427         return;
0428     case TemplatesCommandMenu::CCCLName:
0429         Q_EMIT insertCommand(QStringLiteral("%CCLNAME"));
0430         return;
0431     case TemplatesCommandMenu::CFromAddr:
0432         Q_EMIT insertCommand(QStringLiteral("%FROMADDR"));
0433         return;
0434     case TemplatesCommandMenu::CFromName:
0435         Q_EMIT insertCommand(QStringLiteral("%FROMNAME"));
0436         return;
0437     case TemplatesCommandMenu::CFromFName:
0438         Q_EMIT insertCommand(QStringLiteral("%FROMFNAME"));
0439         return;
0440     case TemplatesCommandMenu::CFromLName:
0441         Q_EMIT insertCommand(QStringLiteral("%FROMLNAME"));
0442         return;
0443     case TemplatesCommandMenu::CFullSubject:
0444         Q_EMIT insertCommand(QStringLiteral("%FULLSUBJECT"));
0445         return;
0446     case TemplatesCommandMenu::CHeader:
0447         Q_EMIT insertCommand(QStringLiteral("%HEADER=\"\""), -1);
0448         return;
0449     case TemplatesCommandMenu::CSystem:
0450         Q_EMIT insertCommand(QStringLiteral("%SYSTEM=\"\""), -1);
0451         return;
0452     case TemplatesCommandMenu::CQuotePipe:
0453         Q_EMIT insertCommand(QStringLiteral("%QUOTEPIPE=\"\""), -1);
0454         return;
0455     case TemplatesCommandMenu::CTextPipe:
0456         Q_EMIT insertCommand(QStringLiteral("%TEXTPIPE=\"\""), -1);
0457         return;
0458     case TemplatesCommandMenu::CMsgPipe:
0459         Q_EMIT insertCommand(QStringLiteral("%MSGPIPE=\"\""), -1);
0460         return;
0461     case TemplatesCommandMenu::CBodyPipe:
0462         Q_EMIT insertCommand(QStringLiteral("%BODYPIPE=\"\""), -1);
0463         return;
0464     case TemplatesCommandMenu::CClearPipe:
0465         Q_EMIT insertCommand(QStringLiteral("%CLEARPIPE=\"\""), -1);
0466         return;
0467     case TemplatesCommandMenu::CCursor:
0468         Q_EMIT insertCommand(QStringLiteral("%CURSOR"));
0469         return;
0470     case TemplatesCommandMenu::CSignature:
0471         Q_EMIT insertCommand(QStringLiteral("%SIGNATURE"));
0472         return;
0473     case TemplatesCommandMenu::CInsert:
0474         Q_EMIT insertCommand(QStringLiteral("%INSERT=\"\""), -1);
0475         return;
0476     case TemplatesCommandMenu::CDnl:
0477         Q_EMIT insertCommand(QStringLiteral("%-"));
0478         return;
0479     case TemplatesCommandMenu::CRem:
0480         Q_EMIT insertCommand(QStringLiteral("%REM=\"\""), -1);
0481         return;
0482     case TemplatesCommandMenu::CNop:
0483         Q_EMIT insertCommand(QStringLiteral("%NOP"));
0484         return;
0485     case TemplatesCommandMenu::CClear:
0486         Q_EMIT insertCommand(QStringLiteral("%CLEAR"));
0487         return;
0488     case TemplatesCommandMenu::CDebug:
0489         Q_EMIT insertCommand(QStringLiteral("%DEBUG"));
0490         return;
0491     case TemplatesCommandMenu::CDebugOff:
0492         Q_EMIT insertCommand(QStringLiteral("%DEBUGOFF"));
0493         return;
0494     case TemplatesCommandMenu::CQuotePlain:
0495         Q_EMIT insertCommand(QStringLiteral("%FORCEDPLAIN"));
0496         return;
0497     case TemplatesCommandMenu::CQuoteHtml:
0498         Q_EMIT insertCommand(QStringLiteral("%FORCEDHTML"));
0499         return;
0500     case TemplatesCommandMenu::CDictionaryLanguage:
0501         Q_EMIT insertCommand(QStringLiteral("%DICTIONARYLANGUAGE=\"\""), -1);
0502         return;
0503     case TemplatesCommandMenu::CLanguage:
0504         Q_EMIT insertCommand(QStringLiteral("%LANGUAGE=\"\""), -1);
0505         return;
0506     }
0507     qCDebug(TEMPLATEPARSER_LOG) << "Unknown template command index:" << cmd;
0508 }
0509 
0510 #include "moc_templatescommandmenu.cpp"