File indexing completed on 2025-03-09 04:54:44

0001 /*
0002  *
0003  *  This file is part of KMail, the KDE mail client.
0004  *
0005  *  SPDX-FileCopyrightText: 2002-2003 Carsten Pfeiffer <pfeiffer@kde.org>
0006  *  SPDX-FileCopyrightText: 2003 Zack Rusin <zack@kde.org>
0007  *
0008  *  SPDX-License-Identifier: GPL-2.0-or-later
0009  */
0010 
0011 #include "mailsourceviewtextbrowserwidget.h"
0012 #include "findbar/findbarsourceview.h"
0013 #include "messageviewer/messageviewerutil.h"
0014 #include "messageviewer_debug.h"
0015 #include <TextAddonsWidgets/SlideContainer>
0016 #ifdef HAVE_KTEXTADDONS_TEXT_TO_SPEECH_SUPPORT
0017 #include <TextEditTextToSpeech/TextToSpeechContainerWidget>
0018 #endif
0019 #include <PimCommon/PimUtil>
0020 
0021 #include <KSyntaxHighlighting/Definition>
0022 #include <KSyntaxHighlighting/SyntaxHighlighter>
0023 #include <KSyntaxHighlighting/Theme>
0024 
0025 #include <KLocalizedString>
0026 #include <KStandardAction>
0027 #include <QAction>
0028 #include <QIcon>
0029 
0030 #include <QContextMenuEvent>
0031 #include <QShortcut>
0032 #include <QVBoxLayout>
0033 
0034 #include <QFontDatabase>
0035 #include <QMenu>
0036 #include <QPushButton>
0037 
0038 using namespace MessageViewer;
0039 MailSourceViewTextBrowserWidget::MailSourceViewTextBrowserWidget(const QString &syntax, QWidget *parent)
0040     : QWidget(parent)
0041     , mSliderContainer(new TextAddonsWidgets::SlideContainer(this))
0042 #ifdef HAVE_KTEXTADDONS_TEXT_TO_SPEECH_SUPPORT
0043     , mTextToSpeechContainerWidget(new TextEditTextToSpeech::TextToSpeechContainerWidget(this))
0044 #endif
0045 {
0046     auto lay = new QVBoxLayout(this);
0047 #ifdef HAVE_KTEXTADDONS_TEXT_TO_SPEECH_SUPPORT
0048     lay->setContentsMargins({});
0049     lay->setSpacing(0);
0050     mTextToSpeechContainerWidget->setObjectName(QLatin1StringView("texttospeech"));
0051     lay->addWidget(mTextToSpeechContainerWidget);
0052     mTextBrowser = new MailSourceViewTextBrowser(mTextToSpeechContainerWidget);
0053 #else
0054     mTextBrowser = new MailSourceViewTextBrowser(this);
0055 #endif
0056     mTextBrowser->setObjectName(QLatin1StringView("textbrowser"));
0057     mTextBrowser->setLineWrapMode(QPlainTextEdit::NoWrap);
0058     mTextBrowser->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard);
0059 
0060     const KSyntaxHighlighting::Definition def = mRepo.definitionForName(syntax);
0061     if (!def.isValid()) {
0062         qCWarning(MESSAGEVIEWER_LOG) << "Invalid definition name";
0063     }
0064 
0065     auto hl = new KSyntaxHighlighting::SyntaxHighlighter(mTextBrowser->document());
0066     hl->setTheme((palette().color(QPalette::Base).lightness() < 128) ? mRepo.defaultTheme(KSyntaxHighlighting::Repository::DarkTheme)
0067                                                                      : mRepo.defaultTheme(KSyntaxHighlighting::Repository::LightTheme));
0068     hl->setDefinition(def);
0069 
0070     connect(mTextBrowser, &MailSourceViewTextBrowser::findText, this, &MailSourceViewTextBrowserWidget::slotFind);
0071     lay->addWidget(mTextBrowser);
0072 
0073     mFindBar = new FindBarSourceView(mTextBrowser, this);
0074     mFindBar->setObjectName(QLatin1StringView("findbar"));
0075     connect(mFindBar, &FindBarSourceView::hideFindBar, mSliderContainer, &TextAddonsWidgets::SlideContainer::slideOut);
0076     mSliderContainer->setContent(mFindBar);
0077 
0078     lay->addWidget(mSliderContainer);
0079     auto shortcut = new QShortcut(this);
0080     shortcut->setKey(Qt::Key_F | Qt::CTRL);
0081     connect(shortcut, &QShortcut::activated, this, &MailSourceViewTextBrowserWidget::slotFind);
0082 }
0083 
0084 void MailSourceViewTextBrowserWidget::slotFind()
0085 {
0086     if (mTextBrowser->textCursor().hasSelection()) {
0087         mFindBar->setText(mTextBrowser->textCursor().selectedText());
0088     }
0089     mSliderContainer->slideIn();
0090     mFindBar->focusAndSetCursor();
0091 }
0092 
0093 void MailSourceViewTextBrowserWidget::setText(const QString &text)
0094 {
0095     mTextBrowser->setPlainText(text);
0096 }
0097 
0098 void MailSourceViewTextBrowserWidget::setPlainText(const QString &text)
0099 {
0100     mTextBrowser->setPlainText(text);
0101 }
0102 
0103 void MailSourceViewTextBrowserWidget::setFixedFont()
0104 {
0105     mTextBrowser->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
0106 }
0107 
0108 MessageViewer::MailSourceViewTextBrowser *MailSourceViewTextBrowserWidget::textBrowser() const
0109 {
0110     return mTextBrowser;
0111 }
0112 #ifdef HAVE_KTEXTADDONS_TEXT_TO_SPEECH_SUPPORT
0113 MailSourceViewTextBrowser::MailSourceViewTextBrowser(TextEditTextToSpeech::TextToSpeechContainerWidget *TextToSpeechContainerWidget, QWidget *parent)
0114     : QPlainTextEdit(parent)
0115     , mTextToSpeechContainerWidget(TextToSpeechContainerWidget)
0116 {
0117 }
0118 #endif
0119 MailSourceViewTextBrowser::MailSourceViewTextBrowser(QWidget *parent)
0120     : QPlainTextEdit(parent)
0121 {
0122 }
0123 
0124 void MailSourceViewTextBrowser::contextMenuEvent(QContextMenuEvent *event)
0125 {
0126     QMenu *popup = createStandardContextMenu();
0127     if (popup) {
0128         popup->addSeparator();
0129         popup->addAction(KStandardAction::find(this, &MailSourceViewTextBrowser::findText, this));
0130 #ifdef HAVE_KTEXTADDONS_TEXT_TO_SPEECH_SUPPORT
0131         popup->addSeparator();
0132         popup->addAction(QIcon::fromTheme(QStringLiteral("preferences-desktop-text-to-speech")),
0133                          i18n("Speak Text"),
0134                          this,
0135                          &MailSourceViewTextBrowser::slotSpeakText);
0136 #endif
0137         popup->addSeparator();
0138         popup->addAction(KStandardAction::saveAs(this, &MailSourceViewTextBrowser::slotSaveAs, this));
0139 
0140         popup->exec(event->globalPos());
0141         delete popup;
0142     }
0143 }
0144 
0145 void MailSourceViewTextBrowser::slotSaveAs()
0146 {
0147     PimCommon::Util::saveTextAs(toPlainText(), QString(), this);
0148 }
0149 
0150 void MailSourceViewTextBrowser::slotSpeakText()
0151 {
0152     QString text;
0153     if (textCursor().hasSelection()) {
0154         text = textCursor().selectedText();
0155     } else {
0156         text = toPlainText();
0157     }
0158 #ifdef HAVE_KTEXTADDONS_TEXT_TO_SPEECH_SUPPORT
0159     mTextToSpeechContainerWidget->say(text);
0160 #endif
0161 }
0162 
0163 #include "moc_mailsourceviewtextbrowserwidget.cpp"