diff --git a/src/pimcommon/translator/translatorwidget.cpp b/src/pimcommon/translator/translatorwidget.cpp index 8d727f2..d8e164e 100644 --- a/src/pimcommon/translator/translatorwidget.cpp +++ b/src/pimcommon/translator/translatorwidget.cpp @@ -1,469 +1,481 @@ /* Copyright (c) 2012-2020 Laurent Montel This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "translatorwidget.h" #include "translatorutil.h" #include "googletranslator.h" #include "kpimtextedit/plaintexteditorwidget.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace PimCommon; class Q_DECL_HIDDEN TranslatorWidget::TranslatorWidgetPrivate { public: TranslatorWidgetPrivate() { } ~TranslatorWidgetPrivate() { delete abstractTranslator; } void initLanguage(); void fillToCombobox(const QString &lang); QMap > listLanguage; QByteArray data; TranslatorTextEdit *inputText = nullptr; KPIMTextEdit::PlainTextEditorWidget *translatedText = nullptr; TranslatorResultTextEdit *translatorResultTextEdit = nullptr; QComboBox *from = nullptr; QComboBox *to = nullptr; QPushButton *translate = nullptr; QPushButton *clear = nullptr; PimCommon::GoogleTranslator *abstractTranslator = nullptr; KBusyIndicatorWidget *progressIndicator = nullptr; QPushButton *invert = nullptr; QSplitter *splitter = nullptr; bool languageSettingsChanged = false; bool standalone = true; }; void TranslatorWidget::TranslatorWidgetPrivate::fillToCombobox(const QString &lang) { to->clear(); const QMap list = listLanguage.value(lang); QMap::const_iterator i = list.constBegin(); QMap::const_iterator end = list.constEnd(); while (i != end) { to->addItem(i.key(), i.value()); ++i; } } void TranslatorWidget::TranslatorWidgetPrivate::initLanguage() { if (!abstractTranslator) { return; } listLanguage = abstractTranslator->initListLanguage(from); } TranslatorResultTextEdit::TranslatorResultTextEdit(QWidget *parent) : KPIMTextEdit::PlainTextEditor(parent) , mResultFailed(false) { setReadOnly(true); } void TranslatorResultTextEdit::setResultFailed(bool failed) { if (mResultFailed != failed) { mResultFailed = failed; update(); } } void TranslatorResultTextEdit::paintEvent(QPaintEvent *event) { if (mResultFailed) { QPainter p(viewport()); QFont font = p.font(); font.setItalic(true); p.setFont(font); p.setPen(Qt::red); p.drawText(QRect(0, 0, width(), height()), Qt::AlignCenter, i18n("Problem when connecting to the translator web site.")); } else { KPIMTextEdit::PlainTextEditor::paintEvent(event); } } TranslatorTextEdit::TranslatorTextEdit(QWidget *parent) : KPIMTextEdit::PlainTextEditor(parent) { } void TranslatorTextEdit::dropEvent(QDropEvent *event) { if (event->source() != this) { if (event->mimeData()->hasText()) { QTextCursor cursor = textCursor(); cursor.beginEditBlock(); cursor.insertText(event->mimeData()->text()); cursor.endEditBlock(); event->setDropAction(Qt::CopyAction); event->accept(); Q_EMIT translateText(); return; } } KPIMTextEdit::PlainTextEditor::dropEvent(event); } TranslatorWidget::TranslatorWidget(QWidget *parent) : QWidget(parent) , d(new TranslatorWidgetPrivate) { init(); } TranslatorWidget::TranslatorWidget(const QString &text, QWidget *parent) : QWidget(parent) , d(new TranslatorWidgetPrivate) { init(); d->inputText->setPlainText(text); } TranslatorWidget::~TranslatorWidget() { disconnect(d->inputText, &TranslatorTextEdit::textChanged, this, &TranslatorWidget::slotTextChanged); disconnect(d->inputText, &TranslatorTextEdit::translateText, this, &TranslatorWidget::slotTranslate); writeConfig(); delete d; } void TranslatorWidget::writeConfig() { KConfigGroup myGroup(KSharedConfig::openConfig(), "TranslatorWidget"); if (d->languageSettingsChanged) { myGroup.writeEntry(QStringLiteral("FromLanguage"), d->from->itemData(d->from->currentIndex()).toString()); myGroup.writeEntry("ToLanguage", d->to->itemData(d->to->currentIndex()).toString()); } myGroup.writeEntry("mainSplitter", d->splitter->sizes()); myGroup.sync(); } void TranslatorWidget::readConfig() { KConfigGroup myGroup(KSharedConfig::openConfig(), "TranslatorWidget"); const QString from = myGroup.readEntry(QStringLiteral("FromLanguage")); const QString to = myGroup.readEntry(QStringLiteral("ToLanguage")); if (from.isEmpty()) { return; } const int indexFrom = d->from->findData(from); if (indexFrom != -1) { d->from->setCurrentIndex(indexFrom); } const int indexTo = d->to->findData(to); if (indexTo != -1) { d->to->setCurrentIndex(indexTo); } const QList size = {100, 400}; d->splitter->setSizes(myGroup.readEntry("mainSplitter", size)); d->invert->setEnabled(from != QLatin1String("auto")); } void TranslatorWidget::init() { d->abstractTranslator = new GoogleTranslator(); d->abstractTranslator->setParentWidget(this); connect(d->abstractTranslator, &PimCommon::GoogleTranslator::translateDone, this, &TranslatorWidget::slotTranslateDone); connect(d->abstractTranslator, &PimCommon::GoogleTranslator::translateFailed, this, &TranslatorWidget::slotTranslateFailed); QVBoxLayout *layout = new QVBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); QHBoxLayout *hboxLayout = new QHBoxLayout; QToolButton *closeBtn = new QToolButton(this); closeBtn->setObjectName(QStringLiteral("close-button")); closeBtn->setIcon(QIcon::fromTheme(QStringLiteral("dialog-close"))); closeBtn->setIconSize(QSize(16, 16)); closeBtn->setToolTip(i18n("Close")); #ifndef QT_NO_ACCESSIBILITY closeBtn->setAccessibleName(i18n("Close")); #endif closeBtn->setAutoRaise(true); hboxLayout->addWidget(closeBtn); connect(closeBtn, &QToolButton::clicked, this, &TranslatorWidget::slotCloseWidget); QLabel *label = new QLabel(i18nc("Translate from language", "From:")); hboxLayout->addWidget(label); d->from = new QComboBox; d->from->setMinimumWidth(50); d->from->setObjectName(QStringLiteral("from")); hboxLayout->addWidget(d->from); label = new QLabel(i18nc("Translate to language", "To:")); hboxLayout->addWidget(label); d->to = new QComboBox; d->to->setMinimumWidth(50); d->to->setObjectName(QStringLiteral("to")); hboxLayout->addWidget(d->to); KSeparator *separator = new KSeparator; separator->setOrientation(Qt::Vertical); hboxLayout->addWidget(separator); d->invert = new QPushButton( i18nc("Invert language choices so that from becomes to and to becomes from", "Invert"), this); d->invert->setObjectName(QStringLiteral("invert-button")); connect(d->invert, &QPushButton::clicked, this, &TranslatorWidget::slotInvertLanguage); hboxLayout->addWidget(d->invert); d->clear = new QPushButton(i18n("Clear"), this); d->clear->setObjectName(QStringLiteral("clear-button")); #ifndef QT_NO_ACCESSIBILITY d->clear->setAccessibleName(i18n("Clear")); #endif connect(d->clear, &QPushButton::clicked, this, &TranslatorWidget::slotClear); hboxLayout->addWidget(d->clear); d->translate = new QPushButton(i18n("Translate")); d->translate->setObjectName(QStringLiteral("translate-button")); #ifndef QT_NO_ACCESSIBILITY d->translate->setAccessibleName(i18n("Translate")); #endif hboxLayout->addWidget(d->translate); connect(d->translate, &QPushButton::clicked, this, &TranslatorWidget::slotTranslate); if (!qEnvironmentVariableIsEmpty("KDEPIM_DEBUGGING")) { QPushButton *debugButton = new QPushButton(i18n("Debug")); hboxLayout->addWidget(debugButton); connect(debugButton, &QPushButton::clicked, this, &TranslatorWidget::slotDebug); } d->progressIndicator = new KBusyIndicatorWidget(this); hboxLayout->addWidget(d->progressIndicator); hboxLayout->addItem(new QSpacerItem(5, 5, QSizePolicy::MinimumExpanding, QSizePolicy::Minimum)); layout->addLayout(hboxLayout); d->splitter = new QSplitter; d->splitter->setChildrenCollapsible(false); d->inputText = new TranslatorTextEdit(this); KPIMTextEdit::PlainTextEditorWidget *editorWidget = new KPIMTextEdit::PlainTextEditorWidget(d->inputText); d->inputText->setObjectName(QStringLiteral("inputtext")); d->inputText->setPlaceholderText(i18n("Drag text that you want to translate. (Be careful text will be send to Google Server).")); connect(d->inputText, &TranslatorTextEdit::textChanged, this, &TranslatorWidget::slotTextChanged); connect(d->inputText, &TranslatorTextEdit::translateText, this, &TranslatorWidget::slotTranslate); d->splitter->addWidget(editorWidget); d->translatorResultTextEdit = new TranslatorResultTextEdit; d->translatedText = new KPIMTextEdit::PlainTextEditorWidget(d->translatorResultTextEdit, this); d->translatedText->setObjectName(QStringLiteral("translatedtext")); d->translatedText->setReadOnly(true); d->splitter->addWidget(d->translatedText); layout->addWidget(d->splitter); d->initLanguage(); d->from->setCurrentIndex(0); //Fill "to" combobox slotFromLanguageChanged(0, true); slotTextChanged(); readConfig(); +#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) connect(d->from, QOverload::of(&QComboBox::currentIndexChanged), this, [this](int val) { slotFromLanguageChanged(val, false); + slotConfigChanged(); }); - connect(d->from, QOverload::of(&QComboBox::currentIndexChanged), this, &TranslatorWidget::slotConfigChanged); - - connect(d->to, QOverload::of(&QComboBox::currentIndexChanged), this, &TranslatorWidget::slotConfigChanged); - connect(d->to, QOverload::of(&QComboBox::currentIndexChanged), this, &TranslatorWidget::slotTranslate); + connect(d->to, QOverload::of(&QComboBox::currentIndexChanged), this, [this]() { + slotConfigChanged(); + slotTranslate(); + }); +#else + connect(d->from, QOverload::of(&QComboBox::currentIndexChanged), this, [this](int val) { + slotFromLanguageChanged(val, false); + slotConfigChanged(); + }); + connect(d->to, QOverload::of(&QComboBox::currentIndexChanged), this, [this]() { + slotConfigChanged(); + slotTranslate(); + }); +#endif hide(); setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed)); d->languageSettingsChanged = false; } void TranslatorWidget::slotConfigChanged() { d->languageSettingsChanged = true; } void TranslatorWidget::slotTextChanged() { d->translate->setEnabled(!d->inputText->document()->isEmpty()); d->clear->setEnabled(!d->inputText->document()->isEmpty()); } void TranslatorWidget::slotFromLanguageChanged(int index, bool initialize) { const QString lang = d->from->itemData(index).toString(); d->invert->setEnabled(lang != QLatin1String("auto")); const QString to = d->to->itemData(d->to->currentIndex()).toString(); d->to->blockSignals(true); d->fillToCombobox(lang); d->to->blockSignals(false); const int indexTo = d->to->findData(to); if (indexTo != -1) { d->to->setCurrentIndex(indexTo); } if (!initialize) { slotTranslate(); } } void TranslatorWidget::setTextToTranslate(const QString &text) { d->inputText->setPlainText(text); slotTranslate(); } void TranslatorWidget::slotTranslate() { if (!PimCommon::NetworkManager::self()->networkConfigureManager()->isOnline()) { KMessageBox::information(this, i18n("No network connection detected, we cannot translate text."), i18n("No network")); return; } const QString textToTranslate = d->inputText->toPlainText(); if (textToTranslate.trimmed().isEmpty()) { return; } d->translatorResultTextEdit->clear(); const QString from = d->from->itemData(d->from->currentIndex()).toString(); const QString to = d->to->itemData(d->to->currentIndex()).toString(); d->translate->setEnabled(false); d->progressIndicator->show(); d->abstractTranslator->setFrom(from); d->abstractTranslator->setTo(to); d->abstractTranslator->setInputText(d->inputText->toPlainText()); d->abstractTranslator->translate(); } void TranslatorWidget::slotTranslateDone() { d->translate->setEnabled(true); d->progressIndicator->hide(); d->translatorResultTextEdit->setResultFailed(false); d->translatorResultTextEdit->setPlainText(d->abstractTranslator->resultTranslate()); } void TranslatorWidget::slotTranslateFailed(bool signalFailed, const QString &message) { d->translate->setEnabled(true); d->progressIndicator->hide(); d->translatorResultTextEdit->setResultFailed(signalFailed); d->translatorResultTextEdit->clear(); if (!message.isEmpty()) { KMessageBox::error(this, message, i18n("Translate error")); } } void TranslatorWidget::slotInvertLanguage() { const QString fromLanguage = d->from->itemData(d->from->currentIndex()).toString(); // don't invert when fromLanguage == auto if (fromLanguage == QLatin1String("auto")) { return; } const QString toLanguage = d->to->itemData(d->to->currentIndex()).toString(); const int indexFrom = d->from->findData(toLanguage); if (indexFrom != -1) { d->from->setCurrentIndex(indexFrom); } const int indexTo = d->to->findData(fromLanguage); if (indexTo != -1) { d->to->setCurrentIndex(indexTo); } slotTranslate(); } void TranslatorWidget::setStandalone(bool b) { d->standalone = b; } void TranslatorWidget::slotCloseWidget() { if (isHidden()) { return; } d->inputText->clear(); d->translatorResultTextEdit->clear(); d->progressIndicator->hide(); if (d->standalone) { hide(); } Q_EMIT toolsWasClosed(); } bool TranslatorWidget::event(QEvent *e) { // Close the bar when pressing Escape. // Not using a QShortcut for this because it could conflict with // window-global actions (e.g. Emil Sedgh binds Esc to "close tab"). // With a shortcut override we can catch this before it gets to kactions. if (e->type() == QEvent::ShortcutOverride || e->type() == QEvent::KeyPress) { QKeyEvent *kev = static_cast(e); if (kev->key() == Qt::Key_Escape) { e->accept(); slotCloseWidget(); return true; } } return QWidget::event(e); } void TranslatorWidget::slotClear() { d->inputText->clear(); d->translatorResultTextEdit->clear(); d->translate->setEnabled(false); d->abstractTranslator->clear(); } void TranslatorWidget::slotDebug() { d->abstractTranslator->debug(); } diff --git a/src/pimcommonakonadi/collectionpage/incidencesforwidget.cpp b/src/pimcommonakonadi/collectionpage/incidencesforwidget.cpp index 7f1e623..61c7526 100644 --- a/src/pimcommonakonadi/collectionpage/incidencesforwidget.cpp +++ b/src/pimcommonakonadi/collectionpage/incidencesforwidget.cpp @@ -1,88 +1,92 @@ /* Copyright (c) 2014-2020 Laurent Montel This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "incidencesforwidget.h" #include #include #include #include using namespace PimCommon; class PimCommon::IncidencesForWidgetPrivate { public: IncidencesForWidgetPrivate() { } QComboBox *mIncidencesForComboBox = nullptr; }; IncidencesForWidget::IncidencesForWidget(QWidget *parent) : QWidget(parent) , d(new PimCommon::IncidencesForWidgetPrivate) { QHBoxLayout *hbox = new QHBoxLayout(this); hbox->setContentsMargins(0, 0, 0, 0); QLabel *label = new QLabel(i18n("Generate free/&busy and activate alarms for:"), this); label->setObjectName(QStringLiteral("contentstypelabel")); hbox->addWidget(label); d->mIncidencesForComboBox = new QComboBox(this); label->setBuddy(d->mIncidencesForComboBox); hbox->addWidget(d->mIncidencesForComboBox); d->mIncidencesForComboBox->addItem(i18n("Nobody")); d->mIncidencesForComboBox->addItem(i18n("Admins of This Folder")); d->mIncidencesForComboBox->addItem(i18n("All Readers of This Folder")); const QString whatsThisForMyOwnFolders = i18n("This setting defines which users sharing " "this folder should get \"busy\" periods in their freebusy lists " "and should see the alarms for the events or tasks in this folder. " "The setting applies to Calendar and Task folders only " "(for tasks, this setting is only used for alarms).\n\n" "Example use cases: if the boss shares a folder with his secretary, " "only the boss should be marked as busy for his meetings, so he should " "select \"Admins\", since the secretary has no admin rights on the folder.\n" "On the other hand if a working group shares a Calendar for " "group meetings, all readers of the folders should be marked " "as busy for meetings.\n" "A company-wide folder with optional events in it would use \"Nobody\" " "since it is not known who will go to those events."); d->mIncidencesForComboBox->setObjectName(QStringLiteral("contentstypecombobox")); d->mIncidencesForComboBox->setWhatsThis(whatsThisForMyOwnFolders); +#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) connect(d->mIncidencesForComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &IncidencesForWidget::currentIndexChanged); +#else + connect(d->mIncidencesForComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, &IncidencesForWidget::currentIndexChanged); +#endif } IncidencesForWidget::~IncidencesForWidget() { delete d; } int IncidencesForWidget::currentIndex() const { return d->mIncidencesForComboBox->currentIndex(); } void IncidencesForWidget::setCurrentIndex(int index) { d->mIncidencesForComboBox->setCurrentIndex(index); }