7#include "autocorrectionwidget.h"
8#include "autocorrectionutils.h"
10#include "ui_autocorrectionwidget.h"
11#include <TextAutoCorrectionCore/ImportAbstractAutocorrection>
12#include <TextAutoCorrectionCore/ImportKMailAutocorrection>
13#include <TextAutoCorrectionCore/ImportLibreOfficeAutocorrection>
15#include <KLineEditEventHandler>
16#include <TextAddonsWidgets/SelectSpecialCharDialog>
18#include <KLocalizedString>
24#include <QTreeWidgetItem>
26using namespace TextAutoCorrectionWidgets;
27using namespace TextAutoCorrectionCore;
29Q_DECLARE_METATYPE(AutoCorrectionWidget::ImportFileType)
30class TextAutoCorrectionWidgets::AutoCorrectionWidgetPrivate
33 AutoCorrectionWidgetPrivate()
38 ~AutoCorrectionWidgetPrivate() =
default;
40 TextAutoCorrectionCore::AutoCorrectionUtils::TypographicQuotes m_singleQuotes;
41 TextAutoCorrectionCore::AutoCorrectionUtils::TypographicQuotes m_doubleQuotes;
45 std::unique_ptr<Ui::AutoCorrectionWidget>
const ui;
47 bool mWasChanged =
false;
48 bool mHasHtmlSupport =
true;
51AutoCorrectionWidget::AutoCorrectionWidget(
QWidget *parent)
53 , d(new TextAutoCorrectionWidgets::AutoCorrectionWidgetPrivate)
57 d->ui->treeWidget->setSortingEnabled(
true);
60 d->ui->add1->setEnabled(
false);
61 d->ui->add2->setEnabled(
false);
90 connect(d->ui->treeWidget, &TextAutoCorrectionWidgets::AutoCorrectionTreeWidget::deleteSelectedItems,
this, &AutoCorrectionWidget::removeAutocorrectEntry);
102 connect(d->ui->abbreviationList,
105 &AutoCorrectionWidget::slotEnableDisableAbreviationList);
106 connect(d->ui->abbreviationList,
107 &TextAutoCorrectionWidgets::AutoCorrectionListWidget::deleteSelectedItems,
109 &AutoCorrectionWidget::removeAbbreviationEntry);
110 connect(d->ui->twoUpperLetterList,
113 &AutoCorrectionWidget::slotEnableDisableTwoUpperEntry);
114 connect(d->ui->twoUpperLetterList,
115 &TextAutoCorrectionWidgets::AutoCorrectionListWidget::deleteSelectedItems,
117 &AutoCorrectionWidget::removeTwoUpperLetterEntry);
118 connect(d->ui->autocorrectionLanguage,
121 &AutoCorrectionWidget::changeLanguage);
134 const QString path = QFileDialog::getExistingDirectory(this, i18n(
"Select Custom Writable Path"));
135 d->ui->customWritablePath->setText(path);
139 const QString path = QFileDialog::getExistingDirectory(this, i18n(
"Select Custom System Path"));
140 d->ui->customSystemPath->setText(path);
143 slotEnableDisableAbreviationList();
144 slotEnableDisableTwoUpperEntry();
146 auto menu =
new QMenu(
this);
147 d->ui->importAutoCorrection->setMenu(menu);
149 auto act =
new QAction(
i18nc(
"@action",
"LibreOffice Autocorrection"),
this);
151 menu->addAction(act);
153 act =
new QAction(
i18nc(
"@action",
"KMail/Calligra Autocorrection"),
this);
155 menu->addAction(act);
161 slotChangeComboboxState(d->ui->tabWidget->currentIndex());
163 d->ui->systemPath->setText(TextAutoCorrectionCore::AutoCorrectionUtils::libreOfficeSystemPath());
164 d->ui->writablePath->setText(TextAutoCorrectionCore::AutoCorrectionUtils::libreOfficeWritableLocalAutoCorrectionPath());
167AutoCorrectionWidget::~AutoCorrectionWidget() =
default;
169void AutoCorrectionWidget::slotChangeComboboxState(
int index)
171 d->ui->autocorrectionLanguage->setEnabled(index < 2);
176 d->mAutoCorrection = autoCorrect;
177 setLanguage(d->ui->autocorrectionLanguage->language());
180void AutoCorrectionWidget::setHasHtmlSupport(
bool b)
182 if (d->mHasHtmlSupport != b) {
183 d->mHasHtmlSupport = b;
188void AutoCorrectionWidget::updateHtmlSupport()
190 d->ui->autoFormatUrl->setVisible(d->mHasHtmlSupport);
191 d->ui->autoSuperScript->setVisible(d->mHasHtmlSupport);
192 d->ui->autoChangeFormat->setVisible(d->mHasHtmlSupport);
195void AutoCorrectionWidget::loadConfig()
197 if (!d->mAutoCorrection) {
200 AutoCorrectionSettings *settings = d->mAutoCorrection->autoCorrectionSettings();
201 d->ui->autoChangeFormat->setChecked(settings->isAutoBoldUnderline());
202 d->ui->autoFormatUrl->setChecked(settings->isAutoFormatUrl());
203 d->ui->enabledAutocorrection->setChecked(settings->isEnabledAutoCorrection());
204 d->ui->upperCase->setChecked(settings->isUppercaseFirstCharOfSentence());
205 d->ui->upperUpper->setChecked(settings->isFixTwoUppercaseChars());
206 d->ui->ignoreDoubleSpace->setChecked(settings->isSingleSpaces());
207 d->ui->autoReplaceNumber->setChecked(settings->isAutoFractions());
208 d->ui->capitalizeDaysName->setChecked(settings->isCapitalizeWeekDays());
209 d->ui->advancedAutocorrection->setChecked(settings->isAdvancedAutocorrect());
210 d->ui->autoSuperScript->setChecked(settings->isSuperScript());
211 d->ui->typographicDoubleQuotes->setChecked(settings->isReplaceDoubleQuotes());
212 d->ui->typographicSingleQuotes->setChecked(settings->isReplaceSingleQuotes());
213 d->ui->addNonBreakingSpaceInFrench->setChecked(settings->isAddNonBreakingSpace());
214 d->ui->replaceDoubleQuotesByFrenchQuotes->setChecked(settings->isReplaceDoubleQuotesByFrenchQuotes());
216 d->ui->customWritablePath->setText(settings->customWritablePath());
217 d->ui->customSystemPath->setText(settings->customSystemPath());
219 loadAutoCorrectionAndException();
220 d->mWasChanged =
false;
223void AutoCorrectionWidget::loadAutoCorrectionAndException()
226 AutoCorrectionSettings *settings = d->mAutoCorrection->autoCorrectionSettings();
227 d->m_singleQuotes = settings->typographicSingleQuotes();
228 d->ui->simpleQuoteBeginReplace->setText(d->m_singleQuotes.begin);
229 d->ui->simpleQuoteEndReplace->setText(d->m_singleQuotes.end);
230 d->m_doubleQuotes = settings->typographicDoubleQuotes();
231 d->ui->doubleQuoteBeginReplace->setText(d->m_doubleQuotes.begin);
232 d->ui->doubleQuoteEndReplace->setText(d->m_doubleQuotes.end);
233 enableSingleQuotes(d->ui->typographicSingleQuotes->isChecked());
234 enableDoubleQuotes(d->ui->typographicDoubleQuotes->isChecked());
237 d->m_autocorrectEntries = settings->autocorrectEntries();
238 addAutoCorrectEntries();
240 enableAdvAutocorrection(d->ui->advancedAutocorrection->isChecked());
242 d->m_upperCaseExceptions = settings->upperCaseExceptions();
243 d->m_twoUpperLetterExceptions = settings->twoUpperLetterExceptions();
245 d->ui->twoUpperLetterList->clear();
246 d->ui->twoUpperLetterList->addItems(d->m_twoUpperLetterExceptions.values());
248 d->ui->abbreviationList->clear();
249 d->ui->abbreviationList->addItems(d->m_upperCaseExceptions.values());
252void AutoCorrectionWidget::addAutoCorrectEntries()
254 d->ui->treeWidget->clear();
257 while (i != d->m_autocorrectEntries.constEnd()) {
263 d->ui->treeWidget->setSortingEnabled(
true);
267void AutoCorrectionWidget::writeConfig()
269 if (!d->mAutoCorrection) {
272 AutoCorrectionSettings *settings = d->mAutoCorrection->autoCorrectionSettings();
273 settings->setAutoBoldUnderline(d->ui->autoChangeFormat->isChecked());
274 settings->setAutoFormatUrl(d->ui->autoFormatUrl->isChecked());
275 settings->setEnabledAutoCorrection(d->ui->enabledAutocorrection->isChecked());
276 settings->setUppercaseFirstCharOfSentence(d->ui->upperCase->isChecked());
277 settings->setFixTwoUppercaseChars(d->ui->upperUpper->isChecked());
278 settings->setSingleSpaces(d->ui->ignoreDoubleSpace->isChecked());
279 settings->setCapitalizeWeekDays(d->ui->capitalizeDaysName->isChecked());
280 settings->setAdvancedAutocorrect(d->ui->advancedAutocorrection->isChecked());
281 settings->setSuperScript(d->ui->autoSuperScript->isChecked());
283 settings->setAutoFractions(d->ui->autoReplaceNumber->isChecked());
285 settings->setAutocorrectEntries(d->m_autocorrectEntries);
286 settings->setUpperCaseExceptions(d->m_upperCaseExceptions);
287 settings->setTwoUpperLetterExceptions(d->m_twoUpperLetterExceptions);
289 settings->setReplaceDoubleQuotes(d->ui->typographicDoubleQuotes->isChecked());
290 settings->setReplaceSingleQuotes(d->ui->typographicSingleQuotes->isChecked());
291 settings->setTypographicSingleQuotes(d->m_singleQuotes);
292 settings->setTypographicDoubleQuotes(d->m_doubleQuotes);
293 settings->setAddNonBreakingSpace(d->ui->addNonBreakingSpaceInFrench->isChecked());
294 settings->setReplaceDoubleQuotesByFrenchQuotes(d->ui->replaceDoubleQuotesByFrenchQuotes->isChecked());
296 settings->setCustomWritablePath(d->ui->customWritablePath->text());
297 settings->setCustomSystemPath(d->ui->customSystemPath->text());
299 d->mAutoCorrection->setAutoCorrectionSettings(settings);
300 d->mAutoCorrection->writeConfig();
301 d->mWasChanged =
false;
304void AutoCorrectionWidget::resetToDefault()
306 d->ui->autoChangeFormat->setChecked(
false);
307 d->ui->autoFormatUrl->setChecked(
false);
308 d->ui->upperCase->setChecked(
false);
309 d->ui->upperUpper->setChecked(
false);
310 d->ui->ignoreDoubleSpace->setChecked(
false);
311 d->ui->capitalizeDaysName->setChecked(
false);
312 d->ui->advancedAutocorrection->setChecked(
false);
313 d->ui->typographicDoubleQuotes->setChecked(
false);
314 d->ui->typographicSingleQuotes->setChecked(
false);
315 d->ui->autoSuperScript->setChecked(
false);
316 d->ui->autoReplaceNumber->setChecked(
false);
317 d->ui->typographicDoubleQuotes->setChecked(
false);
318 d->ui->typographicSingleQuotes->setChecked(
false);
319 d->ui->addNonBreakingSpaceInFrench->setChecked(
false);
321 loadGlobalAutoCorrectionAndException();
324void AutoCorrectionWidget::enableSingleQuotes(
bool state)
326 d->ui->singleQuote1->setEnabled(state);
327 d->ui->singleQuote2->setEnabled(state);
328 d->ui->singleDefault->setEnabled(state);
331void AutoCorrectionWidget::enableDoubleQuotes(
bool state)
333 d->ui->doubleQuote1->setEnabled(state);
334 d->ui->doubleQuote2->setEnabled(state);
335 d->ui->doubleDefault->setEnabled(state);
338void AutoCorrectionWidget::selectSingleQuoteCharOpen()
341 dlg->setCurrentChar(d->m_singleQuotes.begin);
342 dlg->showSelectButton(
false);
343 dlg->autoInsertChar();
345 d->m_singleQuotes.begin = dlg->currentChar();
346 d->ui->simpleQuoteBeginReplace->setText(d->m_singleQuotes.begin);
352void AutoCorrectionWidget::selectSingleQuoteCharClose()
355 dlg->showSelectButton(
false);
356 dlg->setCurrentChar(d->m_singleQuotes.end);
357 dlg->autoInsertChar();
359 d->m_singleQuotes.end = dlg->currentChar();
360 d->ui->simpleQuoteEndReplace->setText(d->m_singleQuotes.end);
366void AutoCorrectionWidget::setDefaultSingleQuotes()
368 d->m_singleQuotes = TextAutoCorrectionCore::AutoCorrectionUtils::typographicDefaultSingleQuotes();
369 d->ui->simpleQuoteBeginReplace->setText(d->m_singleQuotes.begin);
370 d->ui->simpleQuoteEndReplace->setText(d->m_singleQuotes.end);
374void AutoCorrectionWidget::selectDoubleQuoteCharOpen()
377 dlg->showSelectButton(
false);
378 dlg->setCurrentChar(d->m_doubleQuotes.begin);
379 dlg->autoInsertChar();
381 d->m_doubleQuotes.begin = dlg->currentChar();
382 d->ui->doubleQuoteBeginReplace->setText(d->m_doubleQuotes.begin);
388void AutoCorrectionWidget::selectDoubleQuoteCharClose()
391 dlg->showSelectButton(
false);
392 dlg->setCurrentChar(d->m_doubleQuotes.end);
393 dlg->autoInsertChar();
395 d->m_doubleQuotes.end = dlg->currentChar();
396 d->ui->doubleQuoteEndReplace->setText(d->m_doubleQuotes.end);
402void AutoCorrectionWidget::setDefaultDoubleQuotes()
404 d->m_doubleQuotes = AutoCorrectionUtils::typographicDefaultDoubleQuotes();
405 d->ui->doubleQuoteBeginReplace->setText(d->m_doubleQuotes.begin);
406 d->ui->doubleQuoteEndReplace->setText(d->m_doubleQuotes.end);
410void AutoCorrectionWidget::enableAdvAutocorrection(
bool state)
412 d->ui->findLabel->setEnabled(state);
413 d->ui->find->setEnabled(state);
414 d->ui->replaceLabel->setEnabled(state);
415 d->ui->replace->setEnabled(state);
420 d->ui->addButton->setEnabled(state && !
find.isEmpty() && !
replace.isEmpty());
421 d->ui->removeButton->setEnabled(state && d->ui->treeWidget->currentItem());
422 d->ui->treeWidget->setEnabled(state);
425void AutoCorrectionWidget::addAutocorrectEntry()
430 if (
find == replace) {
431 KMessageBox::error(
this,
i18n(
"\"Replace\" string is the same as \"Find\" string."),
i18nc(
"@title:window",
"Add Autocorrection Entry"));
438 if (item && (
find == item->
text(0))) {
439 d->m_autocorrectEntries.remove(
find);
443 d->m_autocorrectEntries.insert(
find, replace);
444 d->ui->treeWidget->setSortingEnabled(
false);
454 d->ui->treeWidget->setSortingEnabled(
true);
455 d->ui->treeWidget->setCurrentItem(item);
459void AutoCorrectionWidget::removeAutocorrectEntry()
471 findStr = item->
text(0);
474 }
else if (d->ui->treeWidget->topLevelItemCount() > 0) {
475 findStr = item->
text(0);
480 d->m_autocorrectEntries.remove(findStr);
483 d->ui->treeWidget->setSortingEnabled(
false);
488void AutoCorrectionWidget::updateAddRemoveButton()
491 d->ui->removeButton->setEnabled(!listItems.
isEmpty());
494void AutoCorrectionWidget::enableAddRemoveButton()
500 if (d->m_autocorrectEntries.contains(
find)) {
507 }
else if (item &&
find == item->
text(0)) {
510 d->ui->addButton->setText(
i18n(
"&Modify"));
513 d->ui->addButton->setText(
i18n(
"&Add"));
516 if (item && replace == item->
text(1)) {
517 d->ui->addButton->setEnabled(
false);
519 d->ui->addButton->setEnabled(enable);
521 d->ui->removeButton->setEnabled(enable);
524void AutoCorrectionWidget::setFindReplaceText(
QTreeWidgetItem *item,
int column)
527 d->ui->find->setText(item->
text(0));
528 d->ui->replace->setText(item->
text(1));
531void AutoCorrectionWidget::abbreviationChanged(
const QString &text)
533 d->ui->add1->setEnabled(!text.
isEmpty());
536void AutoCorrectionWidget::twoUpperLetterChanged(
const QString &text)
538 d->ui->add2->setEnabled(!text.
isEmpty());
541void AutoCorrectionWidget::addAbbreviationEntry()
543 const QString text = d->ui->abbreviation->text();
547 if (!d->m_upperCaseExceptions.contains(text)) {
548 d->m_upperCaseExceptions.insert(text);
549 d->ui->abbreviationList->addItem(text);
551 d->ui->abbreviation->clear();
552 slotEnableDisableAbreviationList();
556void AutoCorrectionWidget::removeAbbreviationEntry()
563 d->m_upperCaseExceptions.remove(item->
text());
566 slotEnableDisableAbreviationList();
570void AutoCorrectionWidget::addTwoUpperLetterEntry()
572 const QString text = d->ui->twoUpperLetter->text();
576 if (!d->m_twoUpperLetterExceptions.contains(text)) {
577 d->m_twoUpperLetterExceptions.insert(text);
578 d->ui->twoUpperLetterList->addItem(text);
581 slotEnableDisableTwoUpperEntry();
582 d->ui->twoUpperLetter->clear();
585void AutoCorrectionWidget::removeTwoUpperLetterEntry()
592 d->m_twoUpperLetterExceptions.remove(item->
text());
595 slotEnableDisableTwoUpperEntry();
599void AutoCorrectionWidget::slotEnableDisableAbreviationList()
601 const bool enable = (!d->ui->abbreviationList->selectedItems().isEmpty());
602 d->ui->add1->setEnabled(!d->ui->abbreviation->text().isEmpty());
603 d->ui->remove1->setEnabled(enable);
606void AutoCorrectionWidget::slotEnableDisableTwoUpperEntry()
608 const bool enable = (!d->ui->twoUpperLetterList->selectedItems().isEmpty());
609 d->ui->add2->setEnabled(!d->ui->twoUpperLetter->text().isEmpty());
610 d->ui->remove2->setEnabled(enable);
613void AutoCorrectionWidget::slotImportAutoCorrection(
QAction *act)
616 const auto type = act->
data().
value<AutoCorrectionWidget::ImportFileType>();
620 case AutoCorrectionWidget::LibreOffice:
621 title =
i18n(
"Import LibreOffice Autocorrection");
622 filter =
i18n(
"LibreOffice Autocorrection File (*.dat)");
624 case AutoCorrectionWidget::KMail:
625 title =
i18n(
"Import KMail Autocorrection");
626 filter =
i18n(
"KMail Autocorrection File (*.xml)");
631 TextAutoCorrectionCore::ImportAbstractAutocorrection *importAutoCorrection =
nullptr;
633 case AutoCorrectionWidget::LibreOffice:
634 importAutoCorrection =
new TextAutoCorrectionCore::ImportLibreOfficeAutocorrection;
636 case AutoCorrectionWidget::KMail:
637 importAutoCorrection =
new TextAutoCorrectionCore::ImportKMailAutocorrection;
643 if (importAutoCorrection->import(fileName, messageError, ImportAbstractAutocorrection::All)) {
644 d->m_autocorrectEntries = importAutoCorrection->autocorrectEntries();
645 addAutoCorrectEntries();
647 enableAdvAutocorrection(d->ui->advancedAutocorrection->isChecked());
649 d->m_upperCaseExceptions = importAutoCorrection->upperCaseExceptions();
650 d->m_twoUpperLetterExceptions = importAutoCorrection->twoUpperLetterExceptions();
652 d->ui->twoUpperLetterList->clear();
653 d->ui->twoUpperLetterList->addItems(d->m_twoUpperLetterExceptions.values());
655 d->ui->abbreviationList->clear();
656 d->ui->abbreviationList->addItems(d->m_upperCaseExceptions.values());
660 delete importAutoCorrection;
665void AutoCorrectionWidget::setLanguage(
const QString &lang)
667 TextAutoCorrectionCore::AutoCorrectionSettings *settings = d->mAutoCorrection->autoCorrectionSettings();
668 settings->setLanguage(lang);
669 d->mAutoCorrection->setAutoCorrectionSettings(settings);
670 loadAutoCorrectionAndException();
671 d->mWasChanged =
false;
674void AutoCorrectionWidget::changeLanguage()
676 const QString lang = d->ui->autocorrectionLanguage->language();
680 if (d->mWasChanged) {
682 i18n(
"Language was changed, do you want to save config for previous language?"),
683 i18nc(
"@title:window",
"Save config"),
686 if (rc == KMessageBox::ButtonCode::PrimaryAction) {
691 TextAutoCorrectionCore::AutoCorrectionSettings *settings = d->mAutoCorrection->autoCorrectionSettings();
692 settings->setLanguage(lang);
693 d->mAutoCorrection->setAutoCorrectionSettings(settings);
694 loadAutoCorrectionAndException();
695 d->mWasChanged =
false;
698void AutoCorrectionWidget::emitChanged()
700 d->mWasChanged =
true;
704void AutoCorrectionWidget::loadGlobalAutoCorrectionAndException()
706 const QString lang = d->ui->autocorrectionLanguage->language();
707 TextAutoCorrectionCore::AutoCorrectionSettings *settings = d->mAutoCorrection->autoCorrectionSettings();
708 settings->setLanguage(lang,
true);
709 d->mAutoCorrection->setAutoCorrectionSettings(settings);
710 loadAutoCorrectionAndException();
711 d->mWasChanged =
true;
715void AutoCorrectionWidget::slotExportAutoCorrection()
717 if (d->mWasChanged) {
718 KMessageBox::error(
this,
i18n(
"Please save changes before exporting settings."),
i18nc(
"@title:window",
"Export Autocorrection File"));
725 d->mAutoCorrection->writeAutoCorrectionXmlFile(saveUrl);
728#include "moc_autocorrectionwidget.cpp"
The SelectSpecialCharDialog class.
The AutoCorrection class.
The AutoCorrectionWidget class.
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
Type type(const QSqlDatabase &db)
void catchReturnKey(QObject *lineEdit)
ButtonCode warningTwoActions(QWidget *parent, const QString &text, const QString &title, const KGuiItem &primaryAction, const KGuiItem &secondaryAction, const QString &dontAskAgainName=QString(), Options options=Options(Notify|Dangerous))
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
const QList< QKeySequence > & replace()
QVariant data() const const
void currentIndexChanged(int index)
QString getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, Options options)
QString getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, Options options)
void textChanged(const QString &text)
bool isEmpty() const const
bool isEmpty() const const
QFuture< void > filter(QThreadPool *pool, Sequence &sequence, KeepFunctor &&filterFunction)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
void setText(int column, const QString &text)
QString text(int column) const const
QVariant fromValue(T &&value)