Refactor spellchecker language listing
This commit is contained in:
parent
dbf5af1d49
commit
f95f2dcd25
1 changed files with 32 additions and 52 deletions
|
@ -33,6 +33,7 @@
|
||||||
#include <libaegisub/path.h>
|
#include <libaegisub/path.h>
|
||||||
|
|
||||||
#include <boost/format.hpp>
|
#include <boost/format.hpp>
|
||||||
|
#include <boost/range/algorithm.hpp>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <hunspell/hunspell.hxx>
|
#include <hunspell/hunspell.hxx>
|
||||||
|
|
||||||
|
@ -154,79 +155,58 @@ std::vector<std::string> HunspellSpellChecker::GetSuggestions(std::string const&
|
||||||
return suggestions;
|
return suggestions;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> HunspellSpellChecker::GetLanguageList() {
|
static std::vector<std::string> langs(const char *filter) {
|
||||||
if (!languages.empty()) return languages;
|
std::vector<std::string> paths;
|
||||||
|
auto data_path = config::path->Decode("?data/dictionaries/");
|
||||||
|
auto user_path = config::path->Decode(OPT_GET("Path/Dictionary")->GetString());
|
||||||
|
|
||||||
std::vector<std::string> dic, aff;
|
agi::fs::DirectoryIterator(data_path, filter).GetAll(paths);
|
||||||
|
agi::fs::DirectoryIterator(user_path, filter).GetAll(paths);
|
||||||
// Get list of dictionaries
|
|
||||||
auto path = config::path->Decode("?data/dictionaries/");
|
|
||||||
agi::fs::DirectoryIterator(path, "*.dic").GetAll(dic);
|
|
||||||
agi::fs::DirectoryIterator(path, "*.aff").GetAll(aff);
|
|
||||||
|
|
||||||
path = config::path->Decode(OPT_GET("Path/Dictionary")->GetString());
|
|
||||||
agi::fs::DirectoryIterator(path, "*.dic").GetAll(dic);
|
|
||||||
agi::fs::DirectoryIterator(path, "*.aff").GetAll(aff);
|
|
||||||
|
|
||||||
if (dic.empty() || aff.empty()) return languages;
|
|
||||||
|
|
||||||
sort(begin(dic), end(dic));
|
|
||||||
sort(begin(aff), end(aff));
|
|
||||||
|
|
||||||
// Drop extensions
|
// Drop extensions
|
||||||
for (auto& elem : dic) elem.resize(elem.size() - 4);
|
for (auto& fn : paths) fn.resize(fn.size() - 4);
|
||||||
for (auto& elem : aff) elem.resize(elem.size() - 4);
|
|
||||||
|
|
||||||
// Verify that each aff has a dic
|
boost::sort(paths);
|
||||||
for (size_t i = 0, j = 0; i < dic.size() && j < aff.size(); ) {
|
paths.erase(unique(begin(paths), end(paths)), end(paths));
|
||||||
int cmp = dic[i].compare(aff[j]);
|
|
||||||
if (cmp < 0) ++i;
|
return paths;
|
||||||
else if (cmp > 0) ++j;
|
}
|
||||||
else {
|
|
||||||
// Don't insert a language twice if it's in both the user dir and
|
std::vector<std::string> HunspellSpellChecker::GetLanguageList() {
|
||||||
// the app's dir
|
if (languages.empty())
|
||||||
if (languages.empty() || aff[j] != languages.back())
|
boost::set_intersection(langs("*.dic"), langs("*.aff"), back_inserter(languages));
|
||||||
languages.push_back(aff[j]);
|
|
||||||
++i;
|
|
||||||
++j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return languages;
|
return languages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool check_path(agi::fs::path const& path, std::string const& language, agi::fs::path& aff, agi::fs::path& dic) {
|
||||||
|
aff = path/str(boost::format("%s.aff") % language);
|
||||||
|
dic = path/str(boost::format("%s.dic") % language);
|
||||||
|
return agi::fs::FileExists(aff) && agi::fs::FileExists(dic);
|
||||||
|
}
|
||||||
|
|
||||||
void HunspellSpellChecker::OnLanguageChanged() {
|
void HunspellSpellChecker::OnLanguageChanged() {
|
||||||
hunspell.reset();
|
hunspell.reset();
|
||||||
|
|
||||||
auto language = OPT_GET("Tool/Spell Checker/Language")->GetString();
|
auto language = OPT_GET("Tool/Spell Checker/Language")->GetString();
|
||||||
if (language.empty()) return;
|
if (language.empty()) return;
|
||||||
|
|
||||||
auto custDicRoot = config::path->Decode(OPT_GET("Path/Dictionary")->GetString());
|
agi::fs::path aff, dic;
|
||||||
auto dataDicRoot = config::path->Decode("?data/dictionaries");
|
auto path = config::path->Decode(OPT_GET("Path/Dictionary")->GetString() + "/");
|
||||||
|
if (!check_path(path, language, aff, dic)) {
|
||||||
// If the user has a dic/aff pair in their dictionary path for this language
|
path = config::path->Decode("?data/dictionaries/");
|
||||||
// use that; otherwise use the one from Aegisub's install dir, adding words
|
if (!check_path(path, language, aff, dic))
|
||||||
// from the dic in the user's dictionary path if it exists
|
return;
|
||||||
auto affPath = custDicRoot/(language + ".aff");
|
|
||||||
auto dicPath = custDicRoot/(language + ".dic");
|
|
||||||
userDicPath = config::path->Decode("?user/dictionaries")/str(boost::format("user_%s.dic") % language);
|
|
||||||
if (!agi::fs::FileExists(affPath) || !agi::fs::FileExists(dicPath)) {
|
|
||||||
affPath = dataDicRoot/(language + ".aff");
|
|
||||||
dicPath = dataDicRoot/(language + ".dic");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_I("dictionary/file") << dicPath;
|
LOG_I("dictionary/file") << dic;
|
||||||
|
|
||||||
if (!agi::fs::FileExists(affPath) || !agi::fs::FileExists(dicPath)) {
|
hunspell.reset(new Hunspell(agi::fs::ShortName(aff).c_str(), agi::fs::ShortName(dic).c_str()));
|
||||||
LOG_D("dictionary/file") << "Dictionary not found";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
hunspell.reset(new Hunspell(agi::fs::ShortName(affPath).c_str(), agi::fs::ShortName(dicPath).c_str()));
|
|
||||||
if (!hunspell) return;
|
if (!hunspell) return;
|
||||||
|
|
||||||
conv.reset(new agi::charset::IconvWrapper("utf-8", hunspell->get_dic_encoding()));
|
conv.reset(new agi::charset::IconvWrapper("utf-8", hunspell->get_dic_encoding()));
|
||||||
rconv.reset(new agi::charset::IconvWrapper(hunspell->get_dic_encoding(), "utf-8"));
|
rconv.reset(new agi::charset::IconvWrapper(hunspell->get_dic_encoding(), "utf-8"));
|
||||||
|
|
||||||
|
userDicPath = config::path->Decode("?user/dictionaries")/str(boost::format("user_%s.dic") % language);
|
||||||
ReadUserDictionary();
|
ReadUserDictionary();
|
||||||
|
|
||||||
for (auto const& word : customWords) {
|
for (auto const& word : customWords) {
|
||||||
|
|
Loading…
Reference in a new issue