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