2
Copyright (c) 2012 Montel Laurent <montel@kde.org>
4
This program is free software; you can redistribute it and/or modify it
5
under the terms of the GNU General Public License, version 2, as
6
published by the Free Software Foundation.
8
This program is distributed in the hope that it will be useful, but
9
WITHOUT ANY WARRANTY; without even the implied warranty of
10
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
General Public License for more details.
13
You should have received a copy of the GNU General Public License along
14
with this program; if not, write to the Free Software Foundation, Inc.,
15
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
#include "composerautocorrectionwidget.h"
19
#include "composerautocorrection.h"
20
#include "ui_composerautocorrectionwidget.h"
21
#include "import/importlibreofficeautocorrection.h"
22
#include "import/importkmailautocorrection.h"
23
#include "import/importabstractautocorrection.h"
25
#include "messagecomposersettings.h"
26
#include "selectspecialchar.h"
28
#include <KFileDialog>
29
#include <KCharSelect>
30
#include <KMessageBox>
32
#include <QTreeWidgetItem>
35
using namespace MessageComposer;
37
Q_DECLARE_METATYPE(ComposerAutoCorrectionWidget::ImportFileType)
39
ComposerAutoCorrectionWidget::ComposerAutoCorrectionWidget(QWidget *parent) :
41
ui(new Ui::ComposerAutoCorrectionWidget),
47
ui->treeWidget->setSortingEnabled(true);
48
ui->treeWidget->sortByColumn(0, Qt::AscendingOrder);
50
ui->add1->setEnabled(false);
51
ui->add2->setEnabled(false);
53
connect(ui->autoChangeFormat,SIGNAL(clicked()),SIGNAL(changed()));
54
connect(ui->autoFormatUrl,SIGNAL(clicked()),SIGNAL(changed()));
55
connect(ui->upperCase,SIGNAL(clicked()),SIGNAL(changed()));
56
connect(ui->upperUpper,SIGNAL(clicked()),SIGNAL(changed()));
57
connect(ui->ignoreDoubleSpace,SIGNAL(clicked()),SIGNAL(changed()));
58
connect(ui->autoReplaceNumber,SIGNAL(clicked()),SIGNAL(changed()));
59
connect(ui->capitalizeDaysName,SIGNAL(clicked()),SIGNAL(changed()));
60
connect(ui->advancedAutocorrection,SIGNAL(clicked()),SIGNAL(changed()));
61
connect(ui->enabledAutocorrection,SIGNAL(clicked()),SIGNAL(changed()));
62
connect(ui->typographicSingleQuotes, SIGNAL(clicked(bool)), this, SLOT(enableSingleQuotes(bool)));
63
connect(ui->typographicDoubleQuotes, SIGNAL(clicked(bool)), this, SLOT(enableDoubleQuotes(bool)));
64
connect(ui->autoSuperScript,SIGNAL(clicked()),SIGNAL(changed()));
65
connect(ui->singleQuote1, SIGNAL(clicked()), this, SLOT(selectSingleQuoteCharOpen()));
66
connect(ui->singleQuote2, SIGNAL(clicked()), this, SLOT(selectSingleQuoteCharClose()));
67
connect(ui->singleDefault, SIGNAL(clicked()), this, SLOT(setDefaultSingleQuotes()));
68
connect(ui->doubleQuote1, SIGNAL(clicked()), this, SLOT(selectDoubleQuoteCharOpen()));
69
connect(ui->doubleQuote2, SIGNAL(clicked()), this, SLOT(selectDoubleQuoteCharClose()));
70
connect(ui->doubleDefault, SIGNAL(clicked()), this, SLOT(setDefaultDoubleQuotes()));
71
connect(ui->advancedAutocorrection, SIGNAL(clicked(bool)), this, SLOT(enableAdvAutocorrection(bool)));
72
connect(ui->addButton, SIGNAL(clicked()), this, SLOT(addAutocorrectEntry()));
73
connect(ui->removeButton, SIGNAL(clicked()), this, SLOT(removeAutocorrectEntry()));
74
connect(ui->treeWidget, SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, SLOT(setFindReplaceText(QTreeWidgetItem*,int)));
75
connect(ui->treeWidget,SIGNAL(deleteSelectedItems()),SLOT(removeAutocorrectEntry()));
76
connect(ui->find, SIGNAL(textChanged(QString)), this, SLOT(enableAddRemoveButton()));
77
connect(ui->replace, SIGNAL(textChanged(QString)), this, SLOT(enableAddRemoveButton()));
78
connect(ui->abbreviation, SIGNAL(textChanged(QString)), this, SLOT(abbreviationChanged(QString)));
79
connect(ui->twoUpperLetter, SIGNAL(textChanged(QString)), this, SLOT(twoUpperLetterChanged(QString)));
80
connect(ui->add1, SIGNAL(clicked()), this, SLOT(addAbbreviationEntry()));
81
connect(ui->remove1, SIGNAL(clicked()), this, SLOT(removeAbbreviationEntry()));
82
connect(ui->add2, SIGNAL(clicked()), this, SLOT(addTwoUpperLetterEntry()));
83
connect(ui->remove2, SIGNAL(clicked()), this, SLOT(removeTwoUpperLetterEntry()));
84
connect(ui->typographicDoubleQuotes,SIGNAL(clicked()),SIGNAL(changed()));
85
connect(ui->typographicSingleQuotes,SIGNAL(clicked()),SIGNAL(changed()));
86
connect(ui->abbreviationList,SIGNAL(itemClicked(QListWidgetItem*)),SLOT(slotEnableDisableAbreviationList()));
87
connect(ui->abbreviationList,SIGNAL(deleteSelectedItems()),SLOT(removeAbbreviationEntry()));
88
connect(ui->twoUpperLetterList,SIGNAL(itemClicked(QListWidgetItem*)),SLOT(slotEnableDisableTwoUpperEntry()));
89
connect(ui->twoUpperLetterList,SIGNAL(deleteSelectedItems()),SLOT(removeTwoUpperLetterEntry()));
90
connect(ui->autocorrectionLanguage,SIGNAL(activated(int)),SLOT(changeLanguage(int)));
91
slotEnableDisableAbreviationList();
92
slotEnableDisableTwoUpperEntry();
94
QMenu *menu = new QMenu();
95
ui->importAutoCorrection->setMenu( menu );
97
QAction *act = new QAction( i18n( "LibreOffice Autocorrection" ), this );
98
act->setData( QVariant::fromValue( ComposerAutoCorrectionWidget::LibreOffice ) );
99
menu->addAction( act );
101
act = new QAction( i18n( "KMail/Calligra Autocorrection" ), this );
102
act->setData( QVariant::fromValue( ComposerAutoCorrectionWidget::KMail ) );
103
menu->addAction( act );
105
connect( menu, SIGNAL(triggered(QAction*)), SLOT(slotImportAutoCorrection(QAction*)) );
109
ComposerAutoCorrectionWidget::~ComposerAutoCorrectionWidget()
114
void ComposerAutoCorrectionWidget::setAutoCorrection(ComposerAutoCorrection * autoCorrect)
116
mAutoCorrection = autoCorrect;
119
void ComposerAutoCorrectionWidget::loadConfig()
124
ui->autoChangeFormat->setChecked(mAutoCorrection->isAutoBoldUnderline());
125
ui->autoFormatUrl->setChecked(mAutoCorrection->isAutoFormatUrl());
126
ui->enabledAutocorrection->setChecked(mAutoCorrection->isEnabledAutoCorrection());
127
ui->upperCase->setChecked(mAutoCorrection->isUppercaseFirstCharOfSentence());
128
ui->upperUpper->setChecked(mAutoCorrection->isFixTwoUppercaseChars());
129
ui->ignoreDoubleSpace->setChecked(mAutoCorrection->isSingleSpaces());
130
ui->autoReplaceNumber->setChecked(mAutoCorrection->isAutoFractions());
131
ui->capitalizeDaysName->setChecked(mAutoCorrection->isCapitalizeWeekDays());
132
ui->advancedAutocorrection->setChecked(mAutoCorrection->isAdvancedAutocorrect());
133
ui->autoSuperScript->setChecked(mAutoCorrection->isSuperScript());
134
loadAutoCorrectionAndException();
138
void ComposerAutoCorrectionWidget::loadAutoCorrectionAndException()
140
/* tab 2 - Custom Quotes */
141
ui->typographicDoubleQuotes->setChecked(mAutoCorrection->isReplaceDoubleQuotes());
142
ui->typographicSingleQuotes->setChecked(mAutoCorrection->isReplaceSingleQuotes());
143
m_singleQuotes = mAutoCorrection->typographicSingleQuotes();
144
ui->singleQuote1->setText(m_singleQuotes.begin);
145
ui->singleQuote2->setText(m_singleQuotes.end);
146
m_doubleQuotes = mAutoCorrection->typographicDoubleQuotes();
147
ui->doubleQuote1->setText(m_doubleQuotes.begin);
148
ui->doubleQuote2->setText(m_doubleQuotes.end);
149
enableSingleQuotes(ui->typographicSingleQuotes->isChecked());
150
enableDoubleQuotes(ui->typographicDoubleQuotes->isChecked());
152
/* tab 3 - Advanced Autocorrection */
153
m_autocorrectEntries = mAutoCorrection->autocorrectEntries();
154
addAutoCorrectEntries();
156
enableAdvAutocorrection(ui->advancedAutocorrection->isChecked());
157
/* tab 4 - Exceptions */
158
m_upperCaseExceptions = mAutoCorrection->upperCaseExceptions();
159
m_twoUpperLetterExceptions = mAutoCorrection->twoUpperLetterExceptions();
161
ui->twoUpperLetterList->clear();
162
ui->twoUpperLetterList->addItems(m_twoUpperLetterExceptions.toList());
164
ui->abbreviationList->clear();
165
ui->abbreviationList->addItems(m_upperCaseExceptions.toList());
169
void ComposerAutoCorrectionWidget::addAutoCorrectEntries()
171
ui->treeWidget->clear();
172
QHash<QString, QString>::const_iterator i = m_autocorrectEntries.constBegin();
173
QTreeWidgetItem * item = 0;
174
while (i != m_autocorrectEntries.constEnd()) {
175
item = new QTreeWidgetItem( ui->treeWidget, item );
176
item->setText( 0, i.key() );
177
item->setText( 1, i.value() );
180
ui->treeWidget->setSortingEnabled(true);
181
ui->treeWidget->sortByColumn(0, Qt::AscendingOrder);
184
void ComposerAutoCorrectionWidget::writeConfig()
188
mAutoCorrection->setAutoBoldUnderline(ui->autoChangeFormat->isChecked());
189
mAutoCorrection->setAutoFormatUrl(ui->autoFormatUrl->isChecked());
190
mAutoCorrection->setEnabledAutoCorrection(ui->enabledAutocorrection->isChecked());
191
mAutoCorrection->setUppercaseFirstCharOfSentence(ui->upperCase->isChecked());
192
mAutoCorrection->setFixTwoUppercaseChars(ui->upperUpper->isChecked());
193
mAutoCorrection->setSingleSpaces(ui->ignoreDoubleSpace->isChecked());
194
mAutoCorrection->setCapitalizeWeekDays(ui->capitalizeDaysName->isChecked());
195
mAutoCorrection->setAdvancedAutocorrect(ui->advancedAutocorrection->isChecked());
196
mAutoCorrection->setSuperScript(ui->autoSuperScript->isChecked());
198
mAutoCorrection->setAutoFractions(ui->autoReplaceNumber->isChecked());
200
mAutoCorrection->setAutocorrectEntries(m_autocorrectEntries);
201
mAutoCorrection->setUpperCaseExceptions(m_upperCaseExceptions);
202
mAutoCorrection->setTwoUpperLetterExceptions(m_twoUpperLetterExceptions);
204
mAutoCorrection->setReplaceDoubleQuotes(ui->typographicDoubleQuotes->isChecked());
205
mAutoCorrection->setReplaceSingleQuotes(ui->typographicSingleQuotes->isChecked());
206
mAutoCorrection->setTypographicSingleQuotes(m_singleQuotes);
207
mAutoCorrection->setTypographicDoubleQuotes(m_doubleQuotes);
208
mAutoCorrection->writeConfig();
212
void ComposerAutoCorrectionWidget::resetToDefault()
214
ui->autoChangeFormat->setChecked(false);
215
ui->autoFormatUrl->setChecked(false);
216
ui->upperCase->setChecked(false);
217
ui->upperUpper->setChecked(false);
218
ui->ignoreDoubleSpace->setChecked(false);
219
ui->capitalizeDaysName->setChecked(false);
220
ui->advancedAutocorrection->setChecked(false);
221
ui->typographicDoubleQuotes->setChecked(false);
222
ui->typographicSingleQuotes->setChecked(false);
223
ui->autoSuperScript->setChecked(false);
224
ui->autoReplaceNumber->setChecked(false);
226
loadGlobalAutoCorrectionAndException();
230
void ComposerAutoCorrectionWidget::enableSingleQuotes(bool state)
232
ui->singleQuote1->setEnabled(state);
233
ui->singleQuote2->setEnabled(state);
234
ui->singleDefault->setEnabled(state);
237
void ComposerAutoCorrectionWidget::enableDoubleQuotes(bool state)
239
ui->doubleQuote1->setEnabled(state);
240
ui->doubleQuote2->setEnabled(state);
241
ui->doubleDefault->setEnabled(state);
244
void ComposerAutoCorrectionWidget::selectSingleQuoteCharOpen()
246
SelectSpecialChar dlg(this);
247
dlg.setCurrentChar(m_singleQuotes.begin);
248
dlg.showSelectButton(false);
250
m_singleQuotes.begin = dlg.currentChar();
251
ui->singleQuote1->setText(m_singleQuotes.begin);
256
void ComposerAutoCorrectionWidget::selectSingleQuoteCharClose()
258
SelectSpecialChar dlg(this);
259
dlg.showSelectButton(false);
260
dlg.setCurrentChar(m_singleQuotes.end);
262
m_singleQuotes.end = dlg.currentChar();
263
ui->singleQuote2->setText(m_singleQuotes.end);
268
void ComposerAutoCorrectionWidget::setDefaultSingleQuotes()
270
m_singleQuotes = mAutoCorrection->typographicDefaultSingleQuotes();
271
ui->singleQuote1->setText(m_singleQuotes.begin);
272
ui->singleQuote2->setText(m_singleQuotes.end);
275
void ComposerAutoCorrectionWidget::selectDoubleQuoteCharOpen()
277
SelectSpecialChar dlg(this);
278
dlg.showSelectButton(false);
279
dlg.setCurrentChar(m_doubleQuotes.begin);
281
m_doubleQuotes.begin = dlg.currentChar();
282
ui->doubleQuote1->setText(m_doubleQuotes.begin);
287
void ComposerAutoCorrectionWidget::selectDoubleQuoteCharClose()
289
SelectSpecialChar dlg(this);
290
dlg.showSelectButton(false);
291
dlg.setCurrentChar(m_doubleQuotes.end);
293
m_doubleQuotes.end = dlg.currentChar();
294
ui->doubleQuote2->setText(m_doubleQuotes.end);
299
void ComposerAutoCorrectionWidget::setDefaultDoubleQuotes()
301
m_doubleQuotes = mAutoCorrection->typographicDefaultDoubleQuotes();
302
ui->doubleQuote1->setText(m_doubleQuotes.begin);
303
ui->doubleQuote2->setText(m_doubleQuotes.end);
306
void ComposerAutoCorrectionWidget::enableAdvAutocorrection(bool state)
308
ui->findLabel->setEnabled(state);
309
ui->find->setEnabled(state);
310
ui->replaceLabel->setEnabled(state);
311
ui->replace->setEnabled(state);
313
const QString find = ui->find->text();
314
const QString replace = ui->replace->text();
316
ui->addButton->setEnabled(state && !find.isEmpty() && !replace.isEmpty());
317
ui->removeButton->setEnabled(state && ui->treeWidget->currentItem ());
318
ui->treeWidget->setEnabled(state);
322
void ComposerAutoCorrectionWidget::addAutocorrectEntry()
324
QTreeWidgetItem *item = ui->treeWidget->currentItem ();
325
QString find = ui->find->text();
328
// Modify actually, not add, so we want to remove item from hash
329
if (item && (find == item->text(0))) {
330
m_autocorrectEntries.remove(find);
334
m_autocorrectEntries.insert(find, ui->replace->text());
335
ui->treeWidget->setSortingEnabled(false);
337
item->setText(0,find);
338
item->setText(1,ui->replace->text());
340
item = new QTreeWidgetItem( ui->treeWidget, item );
341
item->setText( 0, find );
342
item->setText( 1, ui->replace->text() );
345
ui->treeWidget->setSortingEnabled(true);
346
ui->treeWidget->setCurrentItem(item);
350
void ComposerAutoCorrectionWidget::removeAutocorrectEntry()
352
QList<QTreeWidgetItem *> listItems = ui->treeWidget->selectedItems ();
353
if(listItems.isEmpty())
355
Q_FOREACH(QTreeWidgetItem *item, listItems) {
356
QTreeWidgetItem *below = ui->treeWidget->itemBelow( item );
360
//kDebug() << "below";
361
findStr = item->text(0);
364
} else if ( ui->treeWidget->topLevelItemCount() > 0 ) {
365
findStr = item->text(0);
369
if(!findStr.isEmpty())
370
m_autocorrectEntries.remove(findStr);
372
ui->treeWidget->setSortingEnabled(false);
377
void ComposerAutoCorrectionWidget::enableAddRemoveButton()
379
const QString find = ui->find->text();
380
const QString replace = ui->replace->text();
382
QTreeWidgetItem *item = 0;
383
if (m_autocorrectEntries.contains(find)) {
384
item = ui->treeWidget->findItems(find, Qt::MatchCaseSensitive).first();
388
if ( find.isEmpty() || replace.isEmpty()) // disable if no text in find/replace
389
enable = !(find.isEmpty() || replace.isEmpty());
390
else if (item && find == item->text(0)) {
391
// We disable add / remove button if no text for the replacement
392
enable = !item->text(1).isEmpty();
393
ui->addButton->setText(i18n("&Modify"));
395
else if (!item || !item->text(1).isEmpty()) {
397
ui->addButton->setText(i18n("&Add"));
400
if (item && replace == item->text(1))
401
ui->addButton->setEnabled(false);
403
ui->addButton->setEnabled(enable);
404
ui->removeButton->setEnabled(enable);
408
void ComposerAutoCorrectionWidget::setFindReplaceText(QTreeWidgetItem*item ,int column)
411
ui->find->setText(item->text(0));
412
ui->replace->setText(item->text(1));
416
void ComposerAutoCorrectionWidget::abbreviationChanged(const QString &text)
418
ui->add1->setEnabled(!text.isEmpty());
422
void ComposerAutoCorrectionWidget::twoUpperLetterChanged(const QString &text)
424
ui->add2->setEnabled(!text.isEmpty());
428
void ComposerAutoCorrectionWidget::addAbbreviationEntry()
430
const QString text = ui->abbreviation->text();
433
if (!m_upperCaseExceptions.contains(text)) {
434
m_upperCaseExceptions.insert(text);
435
ui->abbreviationList->addItem(text);
437
ui->abbreviation->clear();
438
slotEnableDisableAbreviationList();
442
void ComposerAutoCorrectionWidget::removeAbbreviationEntry()
444
QList<QListWidgetItem *> listItem = ui->abbreviationList->selectedItems ();
445
if(listItem.isEmpty())
447
Q_FOREACH( QListWidgetItem *item, listItem ) {
448
m_upperCaseExceptions.remove(item->text());
451
slotEnableDisableAbreviationList();
455
void ComposerAutoCorrectionWidget::addTwoUpperLetterEntry()
457
const QString text = ui->twoUpperLetter->text();
460
if (!m_twoUpperLetterExceptions.contains(text)) {
461
m_twoUpperLetterExceptions.insert(text);
462
ui->twoUpperLetterList->addItem(text);
465
slotEnableDisableTwoUpperEntry();
466
ui->twoUpperLetter->clear();
470
void ComposerAutoCorrectionWidget::removeTwoUpperLetterEntry()
472
QList<QListWidgetItem *> listItem = ui->twoUpperLetterList->selectedItems ();
473
if(listItem.isEmpty())
475
Q_FOREACH( QListWidgetItem *item, listItem ) {
476
m_twoUpperLetterExceptions.remove(item->text());
479
slotEnableDisableTwoUpperEntry();
484
void ComposerAutoCorrectionWidget::slotEnableDisableAbreviationList()
486
const bool enable = (!ui->abbreviationList->selectedItems ().isEmpty());
487
ui->add1->setEnabled(!ui->abbreviation->text().isEmpty());
488
ui->remove1->setEnabled(enable);
491
void ComposerAutoCorrectionWidget::slotEnableDisableTwoUpperEntry()
493
const bool enable = (!ui->twoUpperLetterList->selectedItems ().isEmpty());
494
ui->add2->setEnabled( !ui->twoUpperLetter->text().isEmpty());
495
ui->remove2->setEnabled(enable);
498
void ComposerAutoCorrectionWidget::slotImportAutoCorrection(QAction* act)
501
ComposerAutoCorrectionWidget::ImportFileType type = act->data().value<ComposerAutoCorrectionWidget::ImportFileType>();
505
case ComposerAutoCorrectionWidget::LibreOffice:
506
title = i18n("Import LibreOffice Autocorrection");
508
case ComposerAutoCorrectionWidget::KMail:
509
title = i18n("Import KMail Autocorrection");
510
filter = QLatin1String("*.xml");
513
const QString fileName = KFileDialog::getOpenFileName( QString(), filter, this, title );
514
if ( !fileName.isEmpty() ) {
515
MessageComposer::ImportAbstractAutocorrection *importAutoCorrection = 0;
517
case ComposerAutoCorrectionWidget::LibreOffice:
518
importAutoCorrection = new MessageComposer::ImportLibreOfficeAutocorrection(this);
520
case ComposerAutoCorrectionWidget::KMail:
521
importAutoCorrection = new MessageComposer::ImportKMailAutocorrection(this);
526
if(importAutoCorrection->import(fileName,ImportAbstractAutocorrection::All))
528
m_autocorrectEntries = importAutoCorrection->autocorrectEntries();
529
addAutoCorrectEntries();
531
enableAdvAutocorrection(ui->advancedAutocorrection->isChecked());
533
m_upperCaseExceptions = importAutoCorrection->upperCaseExceptions();
534
m_twoUpperLetterExceptions = importAutoCorrection->twoUpperLetterExceptions();
536
ui->twoUpperLetterList->clear();
537
ui->twoUpperLetterList->addItems(m_twoUpperLetterExceptions.toList());
539
ui->abbreviationList->clear();
540
ui->abbreviationList->addItems(m_upperCaseExceptions.toList());
542
delete importAutoCorrection;
547
void ComposerAutoCorrectionWidget::changeLanguage(int index)
552
const int rc = KMessageBox::warningYesNo( this,i18n("Language was changed, do you want to save config for previous language?"),i18n( "Save config" ) );
553
if ( rc == KMessageBox::Yes ) {
557
const QString lang = ui->autocorrectionLanguage->itemData (index).toString();
558
mAutoCorrection->setLanguage(lang);
559
loadAutoCorrectionAndException();
563
void ComposerAutoCorrectionWidget::emitChanged()
569
void ComposerAutoCorrectionWidget::loadGlobalAutoCorrectionAndException()
571
const QString lang = ui->autocorrectionLanguage->itemData (ui->autocorrectionLanguage->currentIndex()).toString();
572
mAutoCorrection->setLanguage(lang,true);
573
loadAutoCorrectionAndException();
578
#include "composerautocorrectionwidget.moc"