diff --git a/src/engine/libengine/Database.cpp b/src/engine/libengine/Database.cpp index df5aee38..4a062049 100644 --- a/src/engine/libengine/Database.cpp +++ b/src/engine/libengine/Database.cpp @@ -10,8 +10,6 @@ #include #include #include "Database.h" -#include "regexparser.h" -#include "log.h" Database::Database() { QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); @@ -98,10 +96,8 @@ void Database::loadSuffixTableFromDatabase(QSqlDatabase dbase) { QStringList Database::find(QString word) { if(word != "") { - RegexParser rgx; - QStringList tablelist; QStringList suggestions; - char lmc = word.toStdString().at(0); // Left Most Character + QChar lmc = word.at(0); // Left Most Character QRegularExpression regex(rgx.parse(word)); @@ -113,6 +109,7 @@ QStringList Database::find(QString word) { } } } + suggestions.removeDuplicates(); return suggestions; } else { return {""}; diff --git a/src/engine/libengine/Database.h b/src/engine/libengine/Database.h index 010a04d2..885cf438 100644 --- a/src/engine/libengine/Database.h +++ b/src/engine/libengine/Database.h @@ -13,11 +13,13 @@ #include #include #include +#include "regexparser.h" class Database { QMap> word_table; QMap suffix_table; - QMap prefixTableMap; + QMap prefixTableMap; + RegexParser rgx; public: Database(); ~Database(); diff --git a/src/engine/libengine/MethodPhonetic.cpp b/src/engine/libengine/MethodPhonetic.cpp index 7ded8466..302fd89d 100644 --- a/src/engine/libengine/MethodPhonetic.cpp +++ b/src/engine/libengine/MethodPhonetic.cpp @@ -24,7 +24,7 @@ void MethodPhonetic::setLayout(QJsonObject lay) { suggest.setLayout(lay); } -std::vector MethodPhonetic::toStdVector(QVector vec) { +std::vector MethodPhonetic::toStdVector(QStringList vec) { std::vector v; for(auto& str : vec) { v.push_back(str.toStdString()); @@ -42,7 +42,7 @@ Suggestion MethodPhonetic::createSuggestion() { changedCandidateSelection = false; // Build the suggestions - list = suggest.Suggest(EnglishT).toVector(); + list = suggest.Suggest(EnglishT); prevSelected = 0; diff --git a/src/engine/libengine/MethodPhonetic.h b/src/engine/libengine/MethodPhonetic.h index 536fb508..c5960cb4 100644 --- a/src/engine/libengine/MethodPhonetic.h +++ b/src/engine/libengine/MethodPhonetic.h @@ -28,12 +28,12 @@ class MethodPhonetic : public LayoutMth { bool changedCandidateSelection = false; int prevSelected; PhoneticSuggestion suggest; - QVector list; + QStringList list; QString EnglishT; Suggestion suggested; Suggestion createSuggestion(); - std::vector toStdVector(QVector vec); + std::vector toStdVector(QStringList vec); public: // Functions inherited from class LayoutMth void setLayout(QJsonObject lay); diff --git a/src/engine/libengine/PhoneticSuggestion.cpp b/src/engine/libengine/PhoneticSuggestion.cpp index 1ca26df4..80abaacb 100644 --- a/src/engine/libengine/PhoneticSuggestion.cpp +++ b/src/engine/libengine/PhoneticSuggestion.cpp @@ -19,16 +19,24 @@ #include "Settings.h" #include "qlevenshtein.hpp" -PhoneticSuggestion::PhoneticSuggestion() {} +PhoneticSuggestion::PhoneticSuggestion() { + // Set patterns and optimize them + rgxPadding.setPattern("(^(?::`|\\.`|[-\\]\\\\~!@#&*()_=+\\[{}'\";<>/?|.,])*?(?=(?:,{2,}))|^(?::`|\\.`|[-\\]\\\\~!@#&*()_=+\\[{}'\";<>/?|.,])*)(.*?(?:,,)*)((?::`|\\.`|[-\\]\\\\~!@#&*()_=+\\[{}'\";<>/?|.,])*$)"); + rgxKar.setPattern("^[\u09be\u09bf\u09c0\u09c1\u09c2\u09c3\u09c7\u09c8\u09cb\u09cc\u09c4]$"); + rgxVowel.setPattern("^[\u0985\u0986\u0987\u0988\u0989\u098a\u098b\u098f\u0990\u0993\u0994\u098c\u09e1\u09be\u09bf\u09c0\u09c1\u09c2\u09c3\u09c7\u09c8\u09cb\u09cc]$"); + rgxPadding.optimize(); + rgxKar.optimize(); + rgxVowel.optimize(); +} void PhoneticSuggestion::setLayout(QJsonObject lay) { parser.setLayout(lay); } -QStringList PhoneticSuggestion::getDictionarySuggestion(QMap splitWord) { +QStringList PhoneticSuggestion::getDictionarySuggestion() { QStringList words; - QString key = splitWord["middle"].toLower(); + QString key = padMiddle.toLower(); if (phoneticCache.contains(key)) { words = phoneticCache[key]; @@ -39,7 +47,7 @@ QStringList PhoneticSuggestion::getDictionarySuggestion(QMap s return words; } -QString PhoneticSuggestion::getAutocorrect(QString word, QMap splitWord) { +QString PhoneticSuggestion::getAutocorrect(QString word) { QString corrected; QString autoCorrect = autodict.getCorrected(parser.fixString(word)); @@ -51,7 +59,7 @@ QString PhoneticSuggestion::getAutocorrect(QString word, QMap corrected = parser.parse(autoCorrect); } } else { - QString withCorrection = autodict.getCorrected(splitWord["middle"]); + QString withCorrection = autodict.getCorrected(padMiddle); if (withCorrection != "") { corrected = parser.parse(withCorrection); } @@ -60,32 +68,13 @@ QString PhoneticSuggestion::getAutocorrect(QString word, QMap return corrected; } -QMap PhoneticSuggestion::separatePadding(QString word) { - QMap cutted; - QRegularExpression rgx("(^(?::`|\\.`|[-\\]\\\\~!@#&*()_=+\\[{}'\";<>/?|.,])*?(?=(?:,{2,}))|^(?::`|\\.`|[-\\]\\\\~!@#&*()_=+\\[{}'\";<>/?|.,])*)(.*?(?:,,)*)((?::`|\\.`|[-\\]\\\\~!@#&*()_=+\\[{}'\";<>/?|.,])*$)"); - QRegularExpressionMatch match = rgx.match(word); +void PhoneticSuggestion::separatePadding(QString word) { + QRegularExpressionMatch match = rgxPadding.match(word); if(match.hasMatch()) { - cutted["begin"] = match.captured(1); - cutted["middle"] = match.captured(2); - cutted["end"] = match.captured(3); + padBegin = match.captured(1); + padMiddle = match.captured(2); + padEnd = match.captured(3); } - return cutted; -} - -QStringList PhoneticSuggestion::sortByPhoneticRelevance(QString phonetic, QStringList dictSuggestion) { - std::sort(dictSuggestion.begin(), dictSuggestion.end(), [&] (QString i, QString j) { - int dist1 = levenshtein_distance(phonetic, i); - int dist2 = levenshtein_distance(phonetic, j); - if(dist1 < dist2) { - return true; - } else if(dist1 > dist2) { - return false; - } else { - return true; - } - }); - - return dictSuggestion; } bool PhoneticSuggestion::isKar(QString word) { @@ -93,7 +82,7 @@ bool PhoneticSuggestion::isKar(QString word) { return false; } - return word.left(1).contains(QRegularExpression("^[\u09be\u09bf\u09c0\u09c1\u09c2\u09c3\u09c7\u09c8\u09cb\u09cc\u09c4]$")); + return word.left(1).contains(rgxKar); } bool PhoneticSuggestion::isVowel(QString word) { @@ -101,7 +90,7 @@ bool PhoneticSuggestion::isVowel(QString word) { return false; } - return word.left(1).contains(QRegularExpression("^[\u0985\u0986\u0987\u0988\u0989\u098a\u098b\u098f\u0990\u0993\u0994\u098c\u09e1\u09be\u09bf\u09c0\u09c1\u09c2\u09c3\u09c7\u09c8\u09cb\u09cc]$")); + return word.left(1).contains(rgxVowel); } void PhoneticSuggestion::appendIfNotContains(QStringList &array, QString item) { @@ -116,10 +105,10 @@ void PhoneticSuggestion::addToTempCache(QString full, QString base, QString eng) } } -QStringList PhoneticSuggestion::addSuffix(QMap splitWord) { +QStringList PhoneticSuggestion::addSuffix() { QStringList tempList; QString fullWord; - QString dictKey = splitWord["middle"].toLower(); + QString dictKey = padMiddle.toLower(); int len = dictKey.length(); QStringList rList; @@ -171,7 +160,7 @@ QStringList PhoneticSuggestion::addSuffix(QMap splitWord) { QString PhoneticSuggestion::getPrevSelected() { QString selected; - QString word = PadMap["middle"]; + QString word = padMiddle; int len = word.length(); if (cacheMan.getCandidateSelection(word) != "") { @@ -210,33 +199,44 @@ QString PhoneticSuggestion::getPrevSelected() { } } - return PadMap["begin"] + selected + PadMap["end"]; + return padBegin + selected + padEnd; } -QStringList PhoneticSuggestion::joinSuggestion(QString writtenWord, QString autoCorrect, QStringList dictSuggestion, QString phonetic, QMap splitWord) { +QStringList PhoneticSuggestion::joinSuggestion(QString writtenWord, QString autoCorrect, QStringList dictSuggestion, QString phonetic) { QStringList words; + // Sort dictionary suggestion + std::sort(dictSuggestion.begin(), dictSuggestion.end(), [&] (QString i, QString j) { + int dist1 = levenshtein_distance(phonetic, i); + int dist2 = levenshtein_distance(phonetic, j); + if(dist1 < dist2) { + return true; + } else if(dist1 > dist2) { + return false; + } else { + return true; + } + }); + if (autoCorrect != "") { words.append(autoCorrect); if (autoCorrect != writtenWord) { - dictSuggestion.append(autoCorrect); + dictSuggestion.prepend(autoCorrect); } } - if (phoneticCache[splitWord["middle"].toLower()].isEmpty()) { + if (phoneticCache[padMiddle.toLower()].isEmpty()) { if (!dictSuggestion.isEmpty()) { - phoneticCache[splitWord["middle"].toLower()] = dictSuggestion; + phoneticCache[padMiddle.toLower()] = dictSuggestion; } } - QStringList dictSuggestionWithSuffix = addSuffix(splitWord); + QStringList dictSuggestionWithSuffix = addSuffix(); for (auto& word : dictSuggestionWithSuffix) { appendIfNotContains(words, word); } - words = sortByPhoneticRelevance(phonetic, words); - appendIfNotContains(words, phonetic); prevSuggestion << words; @@ -245,10 +245,10 @@ QStringList PhoneticSuggestion::joinSuggestion(QString writtenWord, QString auto // smiley rule if (autoCorrect == writtenWord) { if (autoCorrect != word) { - word = splitWord["begin"] + word + splitWord["end"]; + word = padBegin + word + padEnd; } } else { - word = splitWord["begin"] + word + splitWord["end"]; + word = padBegin + word + padEnd; } } @@ -256,29 +256,27 @@ QStringList PhoneticSuggestion::joinSuggestion(QString writtenWord, QString auto } void PhoneticSuggestion::saveSelection(int index) { - cacheMan.writeCandidateSelection(PadMap["middle"], prevSuggestion[index]); + cacheMan.writeCandidateSelection(padMiddle, prevSuggestion[index]); } QStringList PhoneticSuggestion::Suggest(QString word) { QStringList suggestion; - QMap splitWord = separatePadding(word); + separatePadding(word); prevSuggestion.clear(); - splitWord["begin"] = parser.parse(splitWord["begin"]); - splitWord["end"] = parser.parse(splitWord["end"]); - - PadMap = splitWord; + padBegin = parser.parse(padBegin); + padEnd = parser.parse(padEnd); - QString phonetic = parser.parse(splitWord["middle"]); + QString phonetic = parser.parse(padMiddle); if(!gSettings->getShowCWPhonetic()) { // Return only phonetic suggestion - suggestion.append(splitWord["begin"] + phonetic + splitWord["end"]); + suggestion.append(padBegin + phonetic + padEnd); } else { - QStringList dictSuggestion = getDictionarySuggestion(splitWord); - QString autoCorrect = getAutocorrect(word, splitWord); + QStringList dictSuggestion = getDictionarySuggestion(); + QString autoCorrect = getAutocorrect(word); - suggestion = joinSuggestion(word, autoCorrect, dictSuggestion, phonetic, splitWord); + suggestion = joinSuggestion(word, autoCorrect, dictSuggestion, phonetic); } return suggestion; diff --git a/src/engine/libengine/PhoneticSuggestion.h b/src/engine/libengine/PhoneticSuggestion.h index 763b0016..39a884a8 100644 --- a/src/engine/libengine/PhoneticSuggestion.h +++ b/src/engine/libengine/PhoneticSuggestion.h @@ -30,20 +30,23 @@ class PhoneticSuggestion { Database db; CacheManager cacheMan; - QMap PadMap; + QRegularExpression rgxPadding; + QRegularExpression rgxKar; + QRegularExpression rgxVowel; + + QString padBegin, padMiddle, padEnd; QMap phoneticCache; QMap tempCache; QStringList prevSuggestion; - QMap separatePadding(QString word); + void separatePadding(QString word); bool isKar(QString word); bool isVowel(QString word); - QStringList joinSuggestion(QString writtenWord, QString autoCorrect, QStringList dictSuggestion, QString phonetic, QMap splitWord); + QStringList joinSuggestion(QString writtenWord, QString autoCorrect, QStringList dictSuggestion, QString phonetic); void appendIfNotContains(QStringList &array, QString item); - QStringList sortByPhoneticRelevance(QString phonetic, QStringList dictSuggestion); - QStringList getDictionarySuggestion(QMap splitWord); - QString getAutocorrect(QString word, QMap splitWord); - QStringList addSuffix(QMap splitWord); + QStringList getDictionarySuggestion(); + QString getAutocorrect(QString word); + QStringList addSuffix(); void addToTempCache(QString full, QString base, QString eng); public: