00001
00022 #include "dialog.h"
00023 #include "ui_sonnetui.h"
00024
00025 #include "backgroundchecker.h"
00026 #include "speller.h"
00027 #include "filter_p.h"
00028 #include "settings_p.h"
00029
00030 #include <kconfig.h>
00031 #include <kguiitem.h>
00032 #include <klocale.h>
00033 #include <kmessagebox.h>
00034 #include <kprogressdialog.h>
00035 #include <kdebug.h>
00036
00037 #include <QtGui/QListView>
00038 #include <QtGui/QStringListModel>
00039 #include <QtGui/QPushButton>
00040 #include <QtGui/QComboBox>
00041 #include <QtGui/QLabel>
00042 #include <QtCore/QTimer>
00043
00044
00045 namespace Sonnet
00046 {
00047
00048
00049 #define NONSORTINGCOLUMN 2
00050
00051 class ReadOnlyStringListModel: public QStringListModel
00052 {
00053 public:
00054 ReadOnlyStringListModel(QObject* parent):QStringListModel(parent){}
00055 Qt::ItemFlags flags(const QModelIndex& index) const {Q_UNUSED(index); return Qt::ItemIsEnabled | Qt::ItemIsSelectable;}
00056 };
00057
00058 class Dialog::Private
00059 {
00060 public:
00061 Ui_SonnetUi ui;
00062 ReadOnlyStringListModel *suggestionsModel;
00063 QWidget *wdg;
00064 KProgressDialog *progressDialog;
00065 QString originalBuffer;
00066 BackgroundChecker *checker;
00067
00068 Word currentWord;
00069 QMap<QString, QString> replaceAllMap;
00070 bool restart;
00071
00072 QMap<QString, QString> dictsMap;
00073
00074 int progressDialogTimeout;
00075 bool showCompletionMessageBox;
00076 bool spellCheckContinuedAfterReplacement;
00077 bool canceled;
00078
00079 void deleteProgressDialog(bool directly)
00080 {
00081 if (progressDialog)
00082 {
00083 progressDialog->hide();
00084 if (directly)
00085 {
00086 delete progressDialog;
00087 }
00088 else
00089 {
00090 progressDialog->deleteLater();
00091 }
00092 progressDialog = NULL;
00093 }
00094 }
00095 };
00096
00097 Dialog::Dialog(BackgroundChecker *checker,
00098 QWidget *parent)
00099 : KDialog(parent),
00100 d(new Private)
00101 {
00102 setModal(true);
00103 setCaption(i18nc("@title:window", "Check Spelling"));
00104 setButtons(Help | Cancel | User1);
00105 setButtonGuiItem(User1, KGuiItem(i18nc("@action:button", "&Finished")));
00106 showButtonSeparator(true);
00107
00108 setDefaultButton(User1);
00109 d->checker = checker;
00110
00111 d->canceled = false;
00112 d->showCompletionMessageBox = false;
00113 d->spellCheckContinuedAfterReplacement = true;
00114 d->progressDialogTimeout = -1;
00115 d->progressDialog = NULL;
00116
00117 initGui();
00118 initConnections();
00119 setMainWidget(d->wdg);
00120 setHelp(QString(),"sonnet");
00121 }
00122
00123 Dialog::~Dialog()
00124 {
00125 delete d;
00126 }
00127
00128 void Dialog::initConnections()
00129 {
00130 connect( d->ui.m_addBtn, SIGNAL(clicked()),
00131 SLOT(slotAddWord()) );
00132 connect( d->ui.m_replaceBtn, SIGNAL(clicked()),
00133 SLOT(slotReplaceWord()) );
00134 connect( d->ui.m_replaceAllBtn, SIGNAL(clicked()),
00135 SLOT(slotReplaceAll()) );
00136 connect( d->ui.m_skipBtn, SIGNAL(clicked()),
00137 SLOT(slotSkip()) );
00138 connect( d->ui.m_skipAllBtn, SIGNAL(clicked()),
00139 SLOT(slotSkipAll()) );
00140 connect( d->ui.m_suggestBtn, SIGNAL(clicked()),
00141 SLOT(slotSuggest()) );
00142 connect( d->ui.m_language, SIGNAL(activated(const QString&)),
00143 SLOT(slotChangeLanguage(const QString&)) );
00144 connect( d->ui.m_suggestions, SIGNAL(clicked(QModelIndex)),
00145 SLOT(slotSelectionChanged(QModelIndex)) );
00146 connect( d->checker, SIGNAL(misspelling(const QString&, int)),
00147 SLOT(slotMisspelling(const QString&, int)) );
00148 connect( d->checker, SIGNAL(done()),
00149 SLOT(slotDone()) );
00150 connect( d->ui.m_suggestions, SIGNAL(doubleClicked(QModelIndex)),
00151 SLOT( slotReplaceWord() ) );
00152 connect( this, SIGNAL(user1Clicked()), this, SLOT(slotFinished()) );
00153 connect( this, SIGNAL(cancelClicked()),this, SLOT(slotCancel()) );
00154 connect( d->ui.m_replacement, SIGNAL(returnPressed()), this, SLOT(slotReplaceWord()) );
00155 connect( d->ui.m_autoCorrect, SIGNAL(clicked()),
00156 SLOT(slotAutocorrect()) );
00157
00158
00159 d->ui.m_autoCorrect->hide();
00160 }
00161
00162 void Dialog::initGui()
00163 {
00164 d->wdg = new QWidget(this);
00165 d->ui.setupUi(d->wdg);
00166 setGuiEnabled(false);
00167
00168
00169 updateDictionaryComboBox();
00170 d->restart = false;
00171
00172 d->suggestionsModel=new ReadOnlyStringListModel(this);
00173 d->ui.m_suggestions->setModel(d->suggestionsModel);
00174 }
00175
00176 void Dialog::activeAutoCorrect( bool _active )
00177 {
00178 if ( _active )
00179 d->ui.m_autoCorrect->show();
00180 else
00181 d->ui.m_autoCorrect->hide();
00182 }
00183
00184 void Dialog::showProgressDialog(int timeout)
00185 {
00186 d->progressDialogTimeout = timeout;
00187 }
00188
00189 void Dialog::showSpellCheckCompletionMessage( bool b )
00190 {
00191 d->showCompletionMessageBox = b;
00192 }
00193
00194 void Dialog::setSpellCheckContinuedAfterReplacement( bool b )
00195 {
00196 d->spellCheckContinuedAfterReplacement = b;
00197 }
00198
00199 void Dialog::slotAutocorrect()
00200 {
00201 setGuiEnabled(false);
00202 setProgressDialogVisible(true);
00203 kDebug();
00204 emit autoCorrect(d->currentWord.word, d->ui.m_replacement->text() );
00205 slotReplaceWord();
00206 }
00207
00208 void Dialog::setGuiEnabled(bool b)
00209 {
00210 d->wdg->setEnabled(b);
00211 }
00212
00213 void Dialog::setProgressDialogVisible(bool b)
00214 {
00215 if (!b)
00216 {
00217 d->deleteProgressDialog(true);
00218 }
00219 else if(d->progressDialogTimeout >= 0)
00220 {
00221 if (d->progressDialog)
00222 {
00223 return;
00224 }
00225 d->progressDialog = new KProgressDialog(this, i18nc("@title:window", "Check Spelling"),
00226 i18nc("progress label", "Spell checking in progress..."));
00227 d->progressDialog->setModal(true);
00228 d->progressDialog->setAutoClose(false);
00229 d->progressDialog->setAutoReset(false);
00230
00231
00232 d->progressDialog->progressBar()->reset();
00233 d->progressDialog->progressBar()->setRange(0, 0);
00234 d->progressDialog->progressBar()->setValue(0);
00235 connect(d->progressDialog, SIGNAL(cancelClicked()), this, SLOT(slotCancel()));
00236 d->progressDialog->setMinimumDuration(d->progressDialogTimeout);
00237 }
00238 }
00239
00240 void Dialog::slotFinished()
00241 {
00242 kDebug();
00243 setProgressDialogVisible(false);
00244 emit stop();
00245
00246 emit done(d->checker->text());
00247 emit spellCheckStatus(i18n("Spell check stopped."));
00248 accept();
00249 }
00250
00251 void Dialog::slotCancel()
00252 {
00253 kDebug();
00254 d->canceled = true;
00255 d->deleteProgressDialog(false);
00256
00257 emit cancel();
00258 emit spellCheckStatus(i18n("Spell check canceled."));
00259 reject();
00260 }
00261
00262 QString Dialog::originalBuffer() const
00263 {
00264 return d->originalBuffer;
00265 }
00266
00267 QString Dialog::buffer() const
00268 {
00269 return d->checker->text();
00270 }
00271
00272 void Dialog::setBuffer(const QString &buf)
00273 {
00274 d->originalBuffer = buf;
00275
00276 d->restart = true;
00277 }
00278
00279 void Dialog::updateDictionaryComboBox()
00280 {
00281 d->ui.m_language->clear();
00282 Speller speller = d->checker->speller();
00283 d->dictsMap = speller.availableDictionaries();
00284 QStringList langs = d->dictsMap.keys();
00285 d->ui.m_language->insertItems(0, langs);
00286 d->ui.m_language->setCurrentIndex(d->dictsMap.values().indexOf(
00287 speller.language()));
00288 }
00289
00290 void Dialog::updateDialog( const QString& word )
00291 {
00292 d->ui.m_unknownWord->setText( word );
00293 d->ui.m_contextLabel->setText( d->checker->currentContext() );
00294 const QStringList suggs = d->checker->suggest( word );
00295
00296 if (suggs.isEmpty())
00297 d->ui.m_replacement->clear();
00298 else
00299 d->ui.m_replacement->setText( suggs.first() );
00300 fillSuggestions( suggs );
00301 }
00302
00303 void Dialog::show()
00304 {
00305 kDebug()<<"Showing dialog";
00306 d->canceled = false;
00307 updateDictionaryComboBox();
00308 if (d->originalBuffer.isEmpty())
00309 {
00310 d->checker->start();
00311 }
00312 else
00313 {
00314 d->checker->setText(d->originalBuffer);
00315 }
00316 setProgressDialogVisible(true);
00317 }
00318
00319 void Dialog::slotAddWord()
00320 {
00321 setGuiEnabled(false);
00322 setProgressDialogVisible(true);
00323 d->checker->addWordToPersonal(d->currentWord.word);
00324 d->checker->continueChecking();
00325 }
00326
00327 void Dialog::slotReplaceWord()
00328 {
00329 setGuiEnabled(false);
00330 setProgressDialogVisible(true);
00331 QString replacementText = d->ui.m_replacement->text();
00332 emit replace( d->currentWord.word, d->currentWord.start,
00333 replacementText );
00334
00335 if( d->spellCheckContinuedAfterReplacement ) {
00336 d->checker->replace(d->currentWord.start,
00337 d->currentWord.word,
00338 replacementText);
00339 d->checker->continueChecking();
00340 }
00341 else {
00342 d->checker->stop();
00343 }
00344 }
00345
00346 void Dialog::slotReplaceAll()
00347 {
00348 setGuiEnabled(false);
00349 setProgressDialogVisible(true);
00350 d->replaceAllMap.insert( d->currentWord.word,
00351 d->ui.m_replacement->text() );
00352 slotReplaceWord();
00353 }
00354
00355 void Dialog::slotSkip()
00356 {
00357 setGuiEnabled(false);
00358 setProgressDialogVisible(true);
00359 d->checker->continueChecking();
00360 }
00361
00362 void Dialog::slotSkipAll()
00363 {
00364 setGuiEnabled(false);
00365 setProgressDialogVisible(true);
00366
00367 Speller speller = d->checker->speller();
00368 speller.addToPersonal(d->currentWord.word);
00369 d->checker->setSpeller(speller);
00370 d->checker->continueChecking();
00371 }
00372
00373 void Dialog::slotSuggest()
00374 {
00375 QStringList suggs = d->checker->suggest( d->ui.m_replacement->text() );
00376 fillSuggestions( suggs );
00377 }
00378
00379 void Dialog::slotChangeLanguage(const QString &lang)
00380 {
00381 Speller speller = d->checker->speller();
00382 QString languageCode = d->dictsMap[lang];
00383 if (!languageCode.isEmpty()) {
00384 d->checker->changeLanguage(languageCode);
00385 slotSuggest();
00386 emit languageChanged(languageCode);
00387 }
00388 }
00389
00390 void Dialog::slotSelectionChanged(const QModelIndex &item)
00391 {
00392 d->ui.m_replacement->setText( item.data().toString() );
00393 }
00394
00395 void Dialog::fillSuggestions( const QStringList& suggs )
00396 {
00397 d->suggestionsModel->setStringList(suggs);
00398 }
00399
00400 void Dialog::slotMisspelling(const QString& word, int start)
00401 {
00402 setGuiEnabled(true);
00403 setProgressDialogVisible(false);
00404 emit misspelling(word, start);
00405
00406
00407
00408 if (!updatesEnabled())
00409 return;
00410
00411 kDebug()<<"Dialog misspelling!!";
00412 d->currentWord = Word( word, start );
00413 if ( d->replaceAllMap.contains( word ) ) {
00414 d->ui.m_replacement->setText( d->replaceAllMap[ word ] );
00415 slotReplaceWord();
00416 } else {
00417 updateDialog( word );
00418 }
00419 KDialog::show();
00420 }
00421
00422 void Dialog::slotDone()
00423 {
00424 d->restart=false;
00425 QString currentLanguage = d->checker->speller().language();
00426 emit done(d->checker->text());
00427 if (d->restart)
00428 {
00429 if (currentLanguage != d->checker->speller().language())
00430 {
00431 updateDictionaryComboBox();
00432 }
00433 d->checker->setText(d->originalBuffer);
00434 d->restart=false;
00435 }
00436 else
00437 {
00438 setProgressDialogVisible(false);
00439 kDebug()<<"Dialog done!";
00440 emit spellCheckStatus(i18n("Spell check complete."));
00441 accept();
00442 if(!d->canceled && d->showCompletionMessageBox)
00443 {
00444 KMessageBox::information(this, i18n("Spell check complete."), i18nc("@title:window", "Check Spelling"));
00445 }
00446 }
00447 }
00448
00449 }
00450
00451 #include "dialog.moc"