File indexing completed on 2025-04-20 12:50:02
0001 /* 0002 SPDX-FileCopyrightText: 2014-2023 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "texttospeechwidget.h" 0008 #include "texttospeechactions.h" 0009 #include "texttospeechconfigdialog.h" 0010 #include "texttospeechinterface.h" 0011 #include "texttospeechsliderwidget.h" 0012 #include <KLocalizedString> 0013 #include <KMessageBox> 0014 #include <QHBoxLayout> 0015 #include <QLabel> 0016 #include <QPointer> 0017 #include <QTimer> 0018 #include <QToolButton> 0019 0020 using namespace std::chrono_literals; 0021 #include <chrono> 0022 0023 using namespace TextEditTextToSpeech; 0024 0025 class Q_DECL_HIDDEN TextEditTextToSpeech::TextToSpeechWidgetPrivate 0026 { 0027 public: 0028 TextToSpeechWidgetPrivate() = default; 0029 0030 QPointer<TextEditTextToSpeech::TextToSpeechConfigDialog> mConfigDialog; 0031 QToolButton *mStopButton = nullptr; 0032 QToolButton *mPlayPauseButton = nullptr; 0033 QToolButton *mConfigureButton = nullptr; 0034 TextToSpeechInterface *mTextToSpeechInterface = nullptr; 0035 TextToSpeechActions *mTextToSpeechActions = nullptr; 0036 TextToSpeechSliderWidget *mVolume = nullptr; 0037 bool mNeedToHide = false; 0038 }; 0039 0040 TextToSpeechWidget::TextToSpeechWidget(QWidget *parent) 0041 : QWidget(parent) 0042 , d(new TextEditTextToSpeech::TextToSpeechWidgetPrivate) 0043 { 0044 auto hbox = new QHBoxLayout(this); 0045 hbox->setObjectName(QStringLiteral("hbox")); 0046 hbox->setContentsMargins(QMargins{}); 0047 0048 d->mTextToSpeechActions = new TextToSpeechActions(this); 0049 connect(d->mTextToSpeechActions, &TextToSpeechActions::stateChanged, this, &TextToSpeechWidget::stateChanged); 0050 0051 auto close = new QToolButton(this); 0052 close->setObjectName(QStringLiteral("close-button")); 0053 close->setIcon(QIcon::fromTheme(QStringLiteral("dialog-close"))); 0054 close->setToolTip(i18n("Close")); 0055 connect(close, &QToolButton::clicked, this, &TextToSpeechWidget::slotCloseTextToSpeechWidget); 0056 hbox->addWidget(close); 0057 hbox->addStretch(0); 0058 0059 auto volume = new QLabel(i18n("Volume:"), this); 0060 hbox->addWidget(volume); 0061 d->mVolume = new TextToSpeechSliderWidget(QStringLiteral("%1 %"), this); 0062 d->mVolume->setMinimumWidth(100); 0063 d->mVolume->setObjectName(QStringLiteral("volumeslider")); 0064 d->mVolume->setRange(0, 100); 0065 connect(d->mVolume, &TextToSpeechSliderWidget::valueChanged, this, &TextToSpeechWidget::slotVolumeChanged); 0066 hbox->addWidget(d->mVolume); 0067 0068 d->mStopButton = new QToolButton(this); 0069 d->mStopButton->setObjectName(QStringLiteral("stopbutton")); 0070 d->mStopButton->setDefaultAction(d->mTextToSpeechActions->stopAction()); 0071 hbox->addWidget(d->mStopButton); 0072 0073 d->mPlayPauseButton = new QToolButton(this); 0074 d->mPlayPauseButton->setObjectName(QStringLiteral("playpausebutton")); 0075 d->mPlayPauseButton->setDefaultAction(d->mTextToSpeechActions->playPauseAction()); 0076 hbox->addWidget(d->mPlayPauseButton); 0077 0078 d->mConfigureButton = new QToolButton(this); 0079 d->mConfigureButton->setIcon(QIcon::fromTheme(QStringLiteral("configure"))); 0080 d->mConfigureButton->setToolTip(i18n("Configure...")); 0081 d->mConfigureButton->setObjectName(QStringLiteral("configurebutton")); 0082 connect(d->mConfigureButton, &QToolButton::clicked, this, &TextToSpeechWidget::slotConfigure); 0083 hbox->addWidget(d->mConfigureButton); 0084 0085 d->mTextToSpeechInterface = new TextToSpeechInterface(this, this); 0086 applyVolume(); 0087 setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed)); 0088 hideWidget(); 0089 } 0090 0091 TextToSpeechWidget::~TextToSpeechWidget() = default; 0092 0093 void TextToSpeechWidget::slotCloseTextToSpeechWidget() 0094 { 0095 d->mTextToSpeechActions->slotStop(); 0096 hideWidget(); 0097 } 0098 0099 void TextToSpeechWidget::slotConfigure() 0100 { 0101 if (!d->mConfigDialog.data()) { 0102 d->mNeedToHide = false; 0103 d->mConfigDialog = new TextToSpeechConfigDialog(this); 0104 if (d->mConfigDialog->exec()) { 0105 d->mTextToSpeechInterface->reloadSettings(); 0106 applyVolume(); 0107 } 0108 delete d->mConfigDialog; 0109 if (d->mNeedToHide) { 0110 hideWidget(); 0111 d->mNeedToHide = false; 0112 } 0113 } 0114 } 0115 0116 void TextToSpeechWidget::slotVolumeChanged(int value) 0117 { 0118 d->mTextToSpeechInterface->setVolume(value / 100.0); 0119 } 0120 0121 bool TextToSpeechWidget::isReady() const 0122 { 0123 return d->mTextToSpeechInterface->isReady(); 0124 } 0125 0126 void TextToSpeechWidget::say(const QString &text) 0127 { 0128 if (!text.isEmpty()) { 0129 if (d->mTextToSpeechInterface->isReady()) { 0130 d->mTextToSpeechInterface->say(text); 0131 } else { 0132 KMessageBox::error(this, i18n("Engine has a problem."), i18n("Text To Speech")); 0133 } 0134 } 0135 } 0136 0137 TextToSpeechWidget::State TextToSpeechWidget::state() const 0138 { 0139 return d->mTextToSpeechActions->state(); 0140 } 0141 0142 void TextToSpeechWidget::slotStateChanged(TextEditTextToSpeech::TextToSpeech::State state) 0143 { 0144 switch (state) { 0145 case TextEditTextToSpeech::TextToSpeech::Ready: 0146 if (state == TextEditTextToSpeech::TextToSpeech::Ready) { 0147 d->mTextToSpeechActions->setState(TextToSpeechWidget::Stop); 0148 if (d->mConfigDialog) { 0149 d->mNeedToHide = true; 0150 } else { 0151 QTimer::singleShot(2s, this, &TextToSpeechWidget::hideWidget); 0152 } 0153 } 0154 break; 0155 default: 0156 // TODO 0157 break; 0158 } 0159 } 0160 0161 void TextToSpeechWidget::showWidget() 0162 { 0163 show(); 0164 Q_EMIT changeVisibility(true); 0165 } 0166 0167 void TextToSpeechWidget::hideWidget() 0168 { 0169 hide(); 0170 Q_EMIT changeVisibility(false); 0171 } 0172 0173 void TextToSpeechWidget::setState(TextToSpeechWidget::State state) 0174 { 0175 d->mTextToSpeechActions->setState(state); 0176 } 0177 0178 void TextToSpeechWidget::setTextToSpeechInterface(TextToSpeechInterface *interface) 0179 { 0180 delete d->mTextToSpeechInterface; 0181 d->mTextToSpeechInterface = interface; 0182 // Update volume value 0183 if (d->mTextToSpeechInterface) { 0184 d->mTextToSpeechInterface->reloadSettings(); 0185 applyVolume(); 0186 } 0187 } 0188 0189 void TextToSpeechWidget::applyVolume() 0190 { 0191 // Api return volume between 0.0 -> 1.0 0192 // We want display between 0 -> 100 0193 d->mVolume->setValue(d->mTextToSpeechInterface->volume() * 100); 0194 } 0195 0196 #include "moc_texttospeechwidget.cpp"