KDEUI
dialog.cpp
Go to the documentation of this file.
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 //to initially disable sorting in the suggestions listview 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;//used when text is distributed across several qtextedits, eg in KAider 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 00107 setDefaultButton(User1); 00108 d->checker = checker; 00109 00110 d->canceled = false; 00111 d->showCompletionMessageBox = false; 00112 d->spellCheckContinuedAfterReplacement = true; 00113 d->progressDialogTimeout = -1; 00114 d->progressDialog = NULL; 00115 00116 initGui(); 00117 initConnections(); 00118 setMainWidget(d->wdg); 00119 setHelp(QString(),"sonnet"); 00120 } 00121 00122 Dialog::~Dialog() 00123 { 00124 delete d; 00125 } 00126 00127 void Dialog::initConnections() 00128 { 00129 connect( d->ui.m_addBtn, SIGNAL(clicked()), 00130 SLOT(slotAddWord()) ); 00131 connect( d->ui.m_replaceBtn, SIGNAL(clicked()), 00132 SLOT(slotReplaceWord()) ); 00133 connect( d->ui.m_replaceAllBtn, SIGNAL(clicked()), 00134 SLOT(slotReplaceAll()) ); 00135 connect( d->ui.m_skipBtn, SIGNAL(clicked()), 00136 SLOT(slotSkip()) ); 00137 connect( d->ui.m_skipAllBtn, SIGNAL(clicked()), 00138 SLOT(slotSkipAll()) ); 00139 connect( d->ui.m_suggestBtn, SIGNAL(clicked()), 00140 SLOT(slotSuggest()) ); 00141 connect( d->ui.m_language, SIGNAL(activated(const QString&)), 00142 SLOT(slotChangeLanguage(const QString&)) ); 00143 connect( d->ui.m_suggestions, SIGNAL(clicked(QModelIndex)), 00144 SLOT(slotSelectionChanged(QModelIndex)) ); 00145 connect( d->checker, SIGNAL(misspelling(const QString&, int)), 00146 SLOT(slotMisspelling(const QString&, int)) ); 00147 connect( d->checker, SIGNAL(done()), 00148 SLOT(slotDone()) ); 00149 connect( d->ui.m_suggestions, SIGNAL(doubleClicked(QModelIndex)), 00150 SLOT( slotReplaceWord() ) ); 00151 connect( this, SIGNAL(user1Clicked()), this, SLOT(slotFinished()) ); 00152 connect( this, SIGNAL(cancelClicked()),this, SLOT(slotCancel()) ); 00153 connect( d->ui.m_replacement, SIGNAL(returnPressed()), this, SLOT(slotReplaceWord()) ); 00154 connect( d->ui.m_autoCorrect, SIGNAL(clicked()), 00155 SLOT(slotAutocorrect()) ); 00156 // button use by kword/kpresenter 00157 // hide by default 00158 d->ui.m_autoCorrect->hide(); 00159 } 00160 00161 void Dialog::initGui() 00162 { 00163 d->wdg = new QWidget(this); 00164 d->ui.setupUi(d->wdg); 00165 setGuiEnabled(false); 00166 00167 //d->ui.m_suggestions->setSorting( NONSORTINGCOLUMN ); 00168 updateDictionaryComboBox(); 00169 d->restart = false; 00170 00171 d->suggestionsModel=new ReadOnlyStringListModel(this); 00172 d->ui.m_suggestions->setModel(d->suggestionsModel); 00173 } 00174 00175 void Dialog::activeAutoCorrect( bool _active ) 00176 { 00177 if ( _active ) 00178 d->ui.m_autoCorrect->show(); 00179 else 00180 d->ui.m_autoCorrect->hide(); 00181 } 00182 00183 void Dialog::showProgressDialog(int timeout) 00184 { 00185 d->progressDialogTimeout = timeout; 00186 } 00187 00188 void Dialog::showSpellCheckCompletionMessage( bool b ) 00189 { 00190 d->showCompletionMessageBox = b; 00191 } 00192 00193 void Dialog::setSpellCheckContinuedAfterReplacement( bool b ) 00194 { 00195 d->spellCheckContinuedAfterReplacement = b; 00196 } 00197 00198 void Dialog::slotAutocorrect() 00199 { 00200 setGuiEnabled(false); 00201 setProgressDialogVisible(true); 00202 kDebug(); 00203 emit autoCorrect(d->currentWord.word, d->ui.m_replacement->text() ); 00204 slotReplaceWord(); 00205 } 00206 00207 void Dialog::setGuiEnabled(bool b) 00208 { 00209 d->wdg->setEnabled(b); 00210 } 00211 00212 void Dialog::setProgressDialogVisible(bool b) 00213 { 00214 if (!b) 00215 { 00216 d->deleteProgressDialog(true); 00217 } 00218 else if(d->progressDialogTimeout >= 0) 00219 { 00220 if (d->progressDialog) 00221 { 00222 return; 00223 } 00224 d->progressDialog = new KProgressDialog(this, i18nc("@title:window", "Check Spelling"), 00225 i18nc("progress label", "Spell checking in progress...")); 00226 d->progressDialog->setModal(true); 00227 d->progressDialog->setAutoClose(false); 00228 d->progressDialog->setAutoReset(false); 00229 // create an 'indefinite' progress box as we currently cannot get progress feedback from 00230 // the speller 00231 d->progressDialog->progressBar()->reset(); 00232 d->progressDialog->progressBar()->setRange(0, 0); 00233 d->progressDialog->progressBar()->setValue(0); 00234 connect(d->progressDialog, SIGNAL(cancelClicked()), this, SLOT(slotCancel())); 00235 d->progressDialog->setMinimumDuration(d->progressDialogTimeout); 00236 } 00237 } 00238 00239 void Dialog::slotFinished() 00240 { 00241 kDebug(); 00242 setProgressDialogVisible(false); 00243 emit stop(); 00244 //FIXME: should we emit done here? 00245 emit done(d->checker->text()); 00246 emit spellCheckStatus(i18n("Spell check stopped.")); 00247 accept(); 00248 } 00249 00250 void Dialog::slotCancel() 00251 { 00252 kDebug(); 00253 d->canceled = true; 00254 d->deleteProgressDialog(false); // this method can be called in response to 00255 // pressing 'Cancel' on the dialog 00256 emit cancel(); 00257 emit spellCheckStatus(i18n("Spell check canceled.")); 00258 reject(); 00259 } 00260 00261 QString Dialog::originalBuffer() const 00262 { 00263 return d->originalBuffer; 00264 } 00265 00266 QString Dialog::buffer() const 00267 { 00268 return d->checker->text(); 00269 } 00270 00271 void Dialog::setBuffer(const QString &buf) 00272 { 00273 d->originalBuffer = buf; 00274 //it is possible to change buffer inside slot connected to done() signal 00275 d->restart = true; 00276 } 00277 00278 void Dialog::updateDictionaryComboBox() 00279 { 00280 d->ui.m_language->clear(); 00281 Speller speller = d->checker->speller(); 00282 d->dictsMap = speller.availableDictionaries(); 00283 QStringList langs = d->dictsMap.keys(); 00284 d->ui.m_language->insertItems(0, langs); 00285 d->ui.m_language->setCurrentIndex(d->dictsMap.values().indexOf( 00286 speller.language())); 00287 } 00288 00289 void Dialog::updateDialog( const QString& word ) 00290 { 00291 d->ui.m_unknownWord->setText( word ); 00292 d->ui.m_contextLabel->setText( d->checker->currentContext() ); 00293 const QStringList suggs = d->checker->suggest( word ); 00294 00295 if (suggs.isEmpty()) 00296 d->ui.m_replacement->clear(); 00297 else 00298 d->ui.m_replacement->setText( suggs.first() ); 00299 fillSuggestions( suggs ); 00300 } 00301 00302 void Dialog::show() 00303 { 00304 kDebug()<<"Showing dialog"; 00305 d->canceled = false; 00306 updateDictionaryComboBox(); 00307 if (d->originalBuffer.isEmpty()) 00308 { 00309 d->checker->start(); 00310 } 00311 else 00312 { 00313 d->checker->setText(d->originalBuffer); 00314 } 00315 setProgressDialogVisible(true); 00316 } 00317 00318 void Dialog::slotAddWord() 00319 { 00320 setGuiEnabled(false); 00321 setProgressDialogVisible(true); 00322 d->checker->addWordToPersonal(d->currentWord.word); 00323 d->checker->continueChecking(); 00324 } 00325 00326 void Dialog::slotReplaceWord() 00327 { 00328 setGuiEnabled(false); 00329 setProgressDialogVisible(true); 00330 QString replacementText = d->ui.m_replacement->text(); 00331 emit replace( d->currentWord.word, d->currentWord.start, 00332 replacementText ); 00333 00334 if( d->spellCheckContinuedAfterReplacement ) { 00335 d->checker->replace(d->currentWord.start, 00336 d->currentWord.word, 00337 replacementText); 00338 d->checker->continueChecking(); 00339 } 00340 else { 00341 d->checker->stop(); 00342 } 00343 } 00344 00345 void Dialog::slotReplaceAll() 00346 { 00347 setGuiEnabled(false); 00348 setProgressDialogVisible(true); 00349 d->replaceAllMap.insert( d->currentWord.word, 00350 d->ui.m_replacement->text() ); 00351 slotReplaceWord(); 00352 } 00353 00354 void Dialog::slotSkip() 00355 { 00356 setGuiEnabled(false); 00357 setProgressDialogVisible(true); 00358 d->checker->continueChecking(); 00359 } 00360 00361 void Dialog::slotSkipAll() 00362 { 00363 setGuiEnabled(false); 00364 setProgressDialogVisible(true); 00365 //### do we want that or should we have a d->ignoreAll list? 00366 Speller speller = d->checker->speller(); 00367 speller.addToPersonal(d->currentWord.word); 00368 d->checker->setSpeller(speller); 00369 d->checker->continueChecking(); 00370 } 00371 00372 void Dialog::slotSuggest() 00373 { 00374 QStringList suggs = d->checker->suggest( d->ui.m_replacement->text() ); 00375 fillSuggestions( suggs ); 00376 } 00377 00378 void Dialog::slotChangeLanguage(const QString &lang) 00379 { 00380 Speller speller = d->checker->speller(); 00381 QString languageCode = d->dictsMap[lang]; 00382 if (!languageCode.isEmpty()) { 00383 d->checker->changeLanguage(languageCode); 00384 slotSuggest(); 00385 emit languageChanged(languageCode); 00386 } 00387 } 00388 00389 void Dialog::slotSelectionChanged(const QModelIndex &item) 00390 { 00391 d->ui.m_replacement->setText( item.data().toString() ); 00392 } 00393 00394 void Dialog::fillSuggestions( const QStringList& suggs ) 00395 { 00396 d->suggestionsModel->setStringList(suggs); 00397 } 00398 00399 void Dialog::slotMisspelling(const QString& word, int start) 00400 { 00401 setGuiEnabled(true); 00402 setProgressDialogVisible(false); 00403 emit misspelling(word, start); 00404 //NOTE this is HACK I had to introduce because BackgroundChecker lacks 'virtual' marks on methods 00405 //this dramatically reduces spellchecking time in Lokalize 00406 //as this doesn't fetch suggestions for words that are present in msgid 00407 if (!updatesEnabled()) 00408 return; 00409 00410 kDebug()<<"Dialog misspelling!!"; 00411 d->currentWord = Word( word, start ); 00412 if ( d->replaceAllMap.contains( word ) ) { 00413 d->ui.m_replacement->setText( d->replaceAllMap[ word ] ); 00414 slotReplaceWord(); 00415 } else { 00416 updateDialog( word ); 00417 } 00418 KDialog::show(); 00419 } 00420 00421 void Dialog::slotDone() 00422 { 00423 d->restart=false; 00424 QString currentLanguage = d->checker->speller().language(); 00425 emit done(d->checker->text()); 00426 if (d->restart) 00427 { 00428 if (currentLanguage != d->checker->speller().language()) 00429 { 00430 updateDictionaryComboBox(); 00431 } 00432 d->checker->setText(d->originalBuffer); 00433 d->restart=false; 00434 } 00435 else 00436 { 00437 setProgressDialogVisible(false); 00438 kDebug()<<"Dialog done!"; 00439 emit spellCheckStatus(i18n("Spell check complete.")); 00440 accept(); 00441 if(!d->canceled && d->showCompletionMessageBox) 00442 { 00443 KMessageBox::information(this, i18n("Spell check complete."), i18nc("@title:window", "Check Spelling")); 00444 } 00445 } 00446 } 00447 00448 } 00449 00450 #include "dialog.moc"
KDE 4.6 API Reference