void SpellCheckerCore::futureFinished() { /* Get the watcher from the sender() of the signal that invoked this slot. * reinterpret_cast is used since qobject_cast is not valid of template * classes since the template class does not have the Q_OBJECT macro. */ QFutureWatcher<WordList>* watcher = reinterpret_cast<QFutureWatcher<WordList>*>( sender() ); if( watcher == nullptr ) { return; } if( d->shuttingDown == true ) { /* Application shutting down, should not try something */ return; } if( watcher->isCanceled() == true ) { /* Application is shutting down */ return; } /* Get the list of words with spelling mistakes from the future. */ WordList checkedWords = watcher->result(); QMutexLocker locker( &d->futureMutex ); /* Recheck again after getting the lock. */ if( d->shuttingDown == true ) { return; } /* Get the file name associated with this future and the misspelled * words. */ FutureWatcherMapIter iter = d->futureWatchers.find( watcher ); if( iter == d->futureWatchers.end() ) { return; } QString fileName = iter.value(); /* Remove the watcher from the list of running watchers and the file that * kept track of the file getting spell checked. */ d->futureWatchers.erase( iter ); d->filesInProcess.removeAll( fileName ); /* Check if the file was scheduled for a re-check. As discussed previously, * if a spell check was requested for a file that had a future already in * progress, it was scheduled for a re-check as soon as the in progress one * completes. If it was scheduled, restart it using the normal slot. */ QHash<QString, WordList>::iterator waitingIter = d->filesWaitingForProcess.find( fileName ); if( waitingIter != d->filesWaitingForProcess.end() ) { WordList wordsToSpellCheck = waitingIter.value(); /* remove the file and words from the scheduled list. */ d->filesWaitingForProcess.erase( waitingIter ); locker.unlock(); /* Invoke the method to make sure that it gets called from the main thread. * This will most probably be already in the main thread, but to make sure * it is done like this. */ this->metaObject()->invokeMethod( this , "spellcheckWordsFromParser" , Qt::QueuedConnection , Q_ARG( QString, fileName ) , Q_ARG( SpellChecker::WordList, wordsToSpellCheck ) ); } locker.unlock(); watcher->deleteLater(); /* Add the list of misspelled words to the mistakes model */ addMisspelledWords( fileName, checkedWords ); }
void SpellCheckerCore::cancelFutures() { QMutexLocker lock(&d->futureMutex); /* Iterate the futures and cancel them. */ FutureWatcherMapIter iter = d->futureWatchers.begin(); for(iter = d->futureWatchers.begin(); iter != d->futureWatchers.end(); ++iter) { iter.key()->future().cancel(); } }
void SpellCheckerCore::cancelFutures() { QMutexLocker lock( &d->futureMutex ); /* Iterate the futures and cancel them. */ FutureWatcherMapIter iter = d->futureWatchers.begin(); for( iter = d->futureWatchers.begin(); iter != d->futureWatchers.end(); ++iter ) { iter.key()->future().cancel(); } /* Wait on the futures and delete the futures */ for( iter = d->futureWatchers.begin(); iter != d->futureWatchers.end(); ++iter ) { iter.key()->future().waitForFinished(); delete iter.key(); } d->futureWatchers.clear(); }