You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdeaccessibility/kmouth/wordcompletion/wordcompletion.cpp

225 lines
6.4 KiB

#include <qregexp.h>
#include <qfile.h>
#include <kapplication.h>
#include <kstandarddirs.h>
#include <kconfig.h>
#include "wordcompletion.h"
class WordCompletion::WordCompletionPrivate {
friend class WordCompletion;
private:
typedef QMap<QString,int> WordMap;
struct DictionaryDetails {
QString filename;
QString language;
};
QString lastText;
QMap<QString,int> map;
QMap<QString,int> addedWords;
QMap<QString,DictionaryDetails> dictDetails;
QStringList dictionaries;
QString current;
bool blockCurrentListSignal;
bool wordsToSave;
};
WordCompletion::WordCompletion() : KCompletion () {
d = new WordCompletionPrivate();
d->blockCurrentListSignal = false;
d->wordsToSave = false;
configure ();
}
WordCompletion::~WordCompletion() {
save ();
delete d;
}
typedef QPair<int,QString> Match;
typedef QValueList<Match> MatchList;
QString WordCompletion::makeCompletion(const QString &text) {
if (d->lastText != text) {
d->lastText = text;
KCompletion::clear();
int border = text.findRev(QRegExp("\\W"));
QString suffix = text.right (text.length() - border - 1).lower();
QString prefix = text.left (border + 1);
if (suffix.length() > 0) {
MatchList matches;
QMap<QString,int>::ConstIterator it;
for (it = d->map.begin(); it != d->map.end(); ++it)
if (it.key().startsWith(suffix))
matches += Match (-it.data(), it.key());
qHeapSort(matches);
MatchList::ConstIterator iter = matches.begin();
for (int count = 0; (iter != matches.end()) && (count < 10); ++iter, ++count) {
int length = (*iter).second.length() + prefix.length() - text.length();
KCompletion::addItem(text + (*iter).second.right(length), -(*iter).first);
}
}
}
// call the KCompletion::makeCompletion(...) method
return KCompletion::makeCompletion (text);
}
QStringList WordCompletion::wordLists() {
return d->dictionaries;
}
QStringList WordCompletion::wordLists(const QString &language) {
QStringList result;
for (QStringList::Iterator it = d->dictionaries.begin();
it != d->dictionaries.end(); ++it)
if (d->dictDetails[*it].language == language)
result += *it;
return result;
}
QString WordCompletion::languageOfWordList(const QString &wordlist) {
if (d->dictDetails.contains(wordlist))
return d->dictDetails[wordlist].language;
else
return QString::null;
}
QString WordCompletion::currentWordList() {
return d->current;
}
bool WordCompletion::isConfigured() {
KConfig *config = new KConfig("kmouthrc");
bool result = config->hasGroup("Dictionary 0");
delete config;
return result;
}
void WordCompletion::configure() {
if (d->wordsToSave)
save ();
d->wordsToSave = false;
d->dictionaries.clear();
d->dictDetails.clear();
KConfig *config = new KConfig("kmouthrc");
QStringList groups = config->groupList();
for (QStringList::Iterator it = groups.begin(); it != groups.end(); ++it)
if ((*it).startsWith ("Dictionary ")) {
config->setGroup(*it);
WordCompletionPrivate::DictionaryDetails details;
details.filename = config->readEntry("Filename");
details.language = config->readEntry("Language");
QString name = config->readEntry("Name");
d->dictDetails[name] = details;
d->dictionaries += name;
}
delete config;
d->blockCurrentListSignal = true;
setWordList(d->current);
d->blockCurrentListSignal = false;
emit wordListsChanged (wordLists());
emit currentListChanged (d->current);
}
bool WordCompletion::setWordList(const QString &wordlist) {
if (d->wordsToSave)
save ();
d->wordsToSave = false;
d->map.clear();
bool result = d->dictDetails.contains (wordlist);
if (result)
d->current = wordlist;
else
d->current = d->dictionaries[0];
QString filename = d->dictDetails[d->current].filename;
QString dictionaryFile = KApplication::kApplication()->dirs()->findResource("appdata", filename);
QFile file(dictionaryFile);
if (file.exists() && file.open(IO_ReadOnly)) {
QTextStream stream(&file);
stream.setEncoding (QTextStream::UnicodeUTF8);
if (!stream.atEnd()) {
if (stream.readLine() == "WPDictFile") {
while (!stream.atEnd()) {
QString s = stream.readLine();
if (!(s.isNull() || s.isEmpty())) {
QStringList list = QStringList::split("\t", s);
bool ok;
int weight = list[1].toInt(&ok);
if (ok && (weight > 0))
d->map [list[0]] = weight;
}
}
}
}
file.close();
}
if (!d->blockCurrentListSignal)
emit currentListChanged (d->current);
d->lastText = "";
d->wordsToSave = false;
return result;
}
void WordCompletion::addSentence (const QString &sentence) {
QStringList words = QStringList::split(QRegExp("\\W"), sentence);
QStringList::ConstIterator it;
for (it = words.begin(); it != words.end(); ++it) {
if (!(*it).contains(QRegExp("\\d|_"))) {
QString key = (*it).lower();
if (d->map.contains(key))
d->map[key] += 1;
else
d->map[key] = 1;
if (d->addedWords.contains(key))
d->addedWords[key] += 1;
else
d->addedWords[key] = 1;
}
}
d->wordsToSave = true;
}
void WordCompletion::save () {
if (d->wordsToSave) {
QString filename = d->dictDetails[d->current].filename;
QString dictionaryFile = KApplication::kApplication()->dirs()->findResource("appdata", filename);
QFile file(dictionaryFile);
if (!file.exists())
return;
if (!file.open(IO_WriteOnly))
return;
QTextStream stream(&file);
stream.setEncoding (QTextStream::UnicodeUTF8);
stream << "WPDictFile\n";
QMap<QString,int>::ConstIterator it;
for (it = d->map.begin(); it != d->map.end(); ++it) {
if (d->addedWords.contains(it.key())) {
stream << it.key() << "\t" << d->addedWords[it.key()] << "\t1\n";
stream << it.key() << "\t" << it.data() - d->addedWords[it.key()] << "\t2\n";
}
else
stream << it.key() << "\t" << it.data() << "\t2\n";
}
file.close();
d->wordsToSave = false;
}
}
#include "wordcompletion.moc"