File indexing completed on 2025-01-05 04:49:29

0001 /*
0002    SPDX-FileCopyrightText: 2019-2024 Laurent Montel <montel@kde.org>
0003 
0004    SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "quicktextplugineditorinterface.h"
0008 #include "quicktextmenu.h"
0009 #include <KActionCollection>
0010 #include <KLocalizedString>
0011 #include <MessageComposer/ConvertSnippetVariablesJob>
0012 #include <MessageComposer/PluginComposerInterface>
0013 #include <TextCustomEditor/RichTextEditor>
0014 
0015 #include <QAction>
0016 #include <QDebug>
0017 #include <QMenu>
0018 #include <QPushButton>
0019 #include <QTextBlock>
0020 
0021 QuickTextPluginEditorInterface::QuickTextPluginEditorInterface(QObject *parent)
0022     : MessageComposer::PluginEditorInterface(parent)
0023     , mModel(MailCommon::SnippetsModel::instance())
0024 {
0025     updateSnippetsInfo();
0026 }
0027 
0028 QuickTextPluginEditorInterface::~QuickTextPluginEditorInterface() = default;
0029 
0030 void QuickTextPluginEditorInterface::updateSnippetsInfo()
0031 {
0032     mSnippetsInfo = mModel->snippetsInfo();
0033 }
0034 
0035 void QuickTextPluginEditorInterface::createAction(KActionCollection *ac)
0036 {
0037     auto quickTextMenu = new QuickTextMenu(parentWidget(), this);
0038     quickTextMenu->setPluginComposerInterface(composerInterface());
0039     connect(quickTextMenu, &QuickTextMenu::insertText, this, &QuickTextPluginEditorInterface::insertText);
0040     auto action = new QAction(i18n("Variables"), this);
0041     action->setMenu(quickTextMenu->menu());
0042     ac->addAction(QStringLiteral("insert_variables"), action);
0043     connect(action, &QAction::triggered, this, &QuickTextPluginEditorInterface::slotActivated);
0044     MessageComposer::PluginActionType type(action, MessageComposer::PluginActionType::Insert);
0045     setActionType(type);
0046     auto button = new QPushButton(i18n("Variables"));
0047     button->setFocusPolicy(Qt::NoFocus);
0048     button->setMenu(quickTextMenu->menu());
0049     setStatusBarWidget(button);
0050     setApplyOnFieldTypes(
0051         {MessageComposer::PluginEditorInterface::ApplyOnFieldType::Composer | MessageComposer::PluginEditorInterface::ApplyOnFieldType::SubjectField});
0052 }
0053 
0054 void QuickTextPluginEditorInterface::slotActivated()
0055 {
0056     Q_EMIT emitPluginActivated(this);
0057 }
0058 
0059 void QuickTextPluginEditorInterface::exec()
0060 {
0061 }
0062 
0063 void QuickTextPluginEditorInterface::reloadConfig()
0064 {
0065     updateSnippetsInfo();
0066 }
0067 
0068 bool QuickTextPluginEditorInterface::processProcessKeyEvent(QKeyEvent *e)
0069 {
0070     if (e->key() == Qt::Key_Tab) {
0071         if (!richTextEditor()->textCursor().hasSelection()) {
0072             // const QTextCharFormat initialTextFormat = richTextEditor()->textCursor().charFormat();
0073             const int position = richTextEditor()->textCursor().position();
0074             QTextCursor cur = richTextEditor()->textCursor();
0075             selectPreviousWord(cur, position);
0076             const QString selectedWord = cur.selectedText();
0077             if (selectedWord.isEmpty()) {
0078                 return false;
0079             }
0080             // qDebug() << "selected " << selectedWord;
0081             for (const MailCommon::SnippetsInfo &info : std::as_const(mSnippetsInfo)) {
0082                 // qDebug() << " info.keyword" << info.keyword;
0083                 QString infoKeyword = info.keyword;
0084                 if (!infoKeyword.startsWith(QLatin1Char('\\'))) {
0085                     infoKeyword = QLatin1Char('\\') + infoKeyword;
0086                 }
0087                 if (infoKeyword == selectedWord) {
0088                     qDebug() << "found snippetsinfo " << info.keyword;
0089                     cur.insertText(composerInterface()->convertText(info.text));
0090                     // TODO change pos cur.setPosition(position);
0091                     return true;
0092                 }
0093             }
0094         }
0095     }
0096 
0097     return false;
0098 }
0099 
0100 void QuickTextPluginEditorInterface::selectPreviousWord(QTextCursor &cursor, int cursorPosition)
0101 {
0102     cursor.setPosition(cursorPosition);
0103     QTextBlock block = cursor.block();
0104     cursor.setPosition(block.position());
0105     cursorPosition -= block.position();
0106     QString string = block.text();
0107     int pos = 0;
0108     bool space = false;
0109     QString::Iterator iter = string.begin();
0110     while (iter != string.end()) {
0111         if (iter->isSpace()) {
0112             if (space) {
0113                 // double spaces belong to the previous word
0114             } else if (pos < cursorPosition) {
0115                 cursor.setPosition(pos + block.position() + 1); // +1 because we don't want to set it on the space itself
0116             } else {
0117                 space = true;
0118             }
0119         } else if (space) {
0120             break;
0121         }
0122         ++pos;
0123         ++iter;
0124     }
0125     cursor.setPosition(pos + block.position(), QTextCursor::KeepAnchor);
0126 }
0127 
0128 #include "moc_quicktextplugineditorinterface.cpp"