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 fillDictionaryComboBox(); 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::fillDictionaryComboBox() 00279 { 00280 Speller speller = d->checker->speller(); 00281 d->dictsMap = speller.availableDictionaries(); 00282 QStringList langs = d->dictsMap.keys(); 00283 d->ui.m_language->clear(); 00284 d->ui.m_language->addItems(langs); 00285 updateDictionaryComboBox(); 00286 } 00287 00288 void Dialog::updateDictionaryComboBox() 00289 { 00290 Speller speller = d->checker->speller(); 00291 d->ui.m_language->setCurrentIndex(d->dictsMap.values().indexOf(speller.language())); 00292 } 00293 00294 void Dialog::updateDialog( const QString& word ) 00295 { 00296 d->ui.m_unknownWord->setText( word ); 00297 d->ui.m_contextLabel->setText( d->checker->currentContext() ); 00298 const QStringList suggs = d->checker->suggest( word ); 00299 00300 if (suggs.isEmpty()) 00301 d->ui.m_replacement->clear(); 00302 else 00303 d->ui.m_replacement->setText( suggs.first() ); 00304 fillSuggestions( suggs ); 00305 } 00306 00307 void Dialog::show() 00308 { 00309 kDebug()<<"Showing dialog"; 00310 d->canceled = false; 00311 fillDictionaryComboBox(); 00312 updateDictionaryComboBox(); 00313 if (d->originalBuffer.isEmpty()) 00314 { 00315 d->checker->start(); 00316 } 00317 else 00318 { 00319 d->checker->setText(d->originalBuffer); 00320 } 00321 setProgressDialogVisible(true); 00322 } 00323 00324 void Dialog::slotAddWord() 00325 { 00326 setGuiEnabled(false); 00327 setProgressDialogVisible(true); 00328 d->checker->addWordToPersonal(d->currentWord.word); 00329 d->checker->continueChecking(); 00330 } 00331 00332 void Dialog::slotReplaceWord() 00333 { 00334 setGuiEnabled(false); 00335 setProgressDialogVisible(true); 00336 QString replacementText = d->ui.m_replacement->text(); 00337 emit replace( d->currentWord.word, d->currentWord.start, 00338 replacementText ); 00339 00340 if( d->spellCheckContinuedAfterReplacement ) { 00341 d->checker->replace(d->currentWord.start, 00342 d->currentWord.word, 00343 replacementText); 00344 d->checker->continueChecking(); 00345 } 00346 else { 00347 d->checker->stop(); 00348 } 00349 } 00350 00351 void Dialog::slotReplaceAll() 00352 { 00353 setGuiEnabled(false); 00354 setProgressDialogVisible(true); 00355 d->replaceAllMap.insert( d->currentWord.word, 00356 d->ui.m_replacement->text() ); 00357 slotReplaceWord(); 00358 } 00359 00360 void Dialog::slotSkip() 00361 { 00362 setGuiEnabled(false); 00363 setProgressDialogVisible(true); 00364 d->checker->continueChecking(); 00365 } 00366 00367 void Dialog::slotSkipAll() 00368 { 00369 setGuiEnabled(false); 00370 setProgressDialogVisible(true); 00371 //### do we want that or should we have a d->ignoreAll list? 00372 Speller speller = d->checker->speller(); 00373 speller.addToPersonal(d->currentWord.word); 00374 d->checker->setSpeller(speller); 00375 d->checker->continueChecking(); 00376 } 00377 00378 void Dialog::slotSuggest() 00379 { 00380 QStringList suggs = d->checker->suggest( d->ui.m_replacement->text() ); 00381 fillSuggestions( suggs ); 00382 } 00383 00384 void Dialog::slotChangeLanguage(const QString &lang) 00385 { 00386 Speller speller = d->checker->speller(); 00387 QString languageCode = d->dictsMap[lang]; 00388 if (!languageCode.isEmpty()) { 00389 d->checker->changeLanguage(languageCode); 00390 slotSuggest(); 00391 emit languageChanged(languageCode); 00392 } 00393 } 00394 00395 void Dialog::slotSelectionChanged(const QModelIndex &item) 00396 { 00397 d->ui.m_replacement->setText( item.data().toString() ); 00398 } 00399 00400 void Dialog::fillSuggestions( const QStringList& suggs ) 00401 { 00402 d->suggestionsModel->setStringList(suggs); 00403 } 00404 00405 void Dialog::slotMisspelling(const QString& word, int start) 00406 { 00407 setGuiEnabled(true); 00408 setProgressDialogVisible(false); 00409 emit misspelling(word, start); 00410 //NOTE this is HACK I had to introduce because BackgroundChecker lacks 'virtual' marks on methods 00411 //this dramatically reduces spellchecking time in Lokalize 00412 //as this doesn't fetch suggestions for words that are present in msgid 00413 if (!updatesEnabled()) 00414 return; 00415 00416 kDebug()<<"Dialog misspelling!!"; 00417 d->currentWord = Word( word, start ); 00418 if ( d->replaceAllMap.contains( word ) ) { 00419 d->ui.m_replacement->setText( d->replaceAllMap[ word ] ); 00420 slotReplaceWord(); 00421 } else { 00422 updateDialog( word ); 00423 } 00424 KDialog::show(); 00425 } 00426 00427 void Dialog::slotDone() 00428 { 00429 d->restart=false; 00430 emit done(d->checker->text()); 00431 if (d->restart) 00432 { 00433 updateDictionaryComboBox(); 00434 d->checker->setText(d->originalBuffer); 00435 d->restart=false; 00436 } 00437 else 00438 { 00439 setProgressDialogVisible(false); 00440 kDebug()<<"Dialog done!"; 00441 emit spellCheckStatus(i18n("Spell check complete.")); 00442 accept(); 00443 if(!d->canceled && d->showCompletionMessageBox) 00444 { 00445 KMessageBox::information(this, i18n("Spell check complete."), i18nc("@title:window", "Check Spelling")); 00446 } 00447 } 00448 } 00449 00450 } 00451 00452 #include "dialog.moc"
KDE 4.7 API Reference