1 /*****************************************************************************
2 * This file is a part of QStarDict, a StarDict clone written using Qt *
3 * multitran.cpp - Plugin for multitran-data (multitran.sf.net) *
4 * Copyright (C) 2008 Nick Shaforostoff *
5 * Copyright (C) 2004 Stanislav Ievlev *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License along *
18 * with this program; if not, write to the Free Software Foundation, Inc., *
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
20 *****************************************************************************/
21
22 #include "multitran.h"
23 //#include "settingsdialog.h"
24
25 #include <QCoreApplication>
26 // #include <QSettings>
27 #include <QTextCodec>
28
29
30 /*
31 /usr/include/mt/query
32 /usr/include/btree
33 /usr/include/mt/support
34 /usr/include/facet
35 */
36 #include <facet/identification.hh>
37 #include <facet/alphabet.hh>
38 #include <facet/typographic.hh>
39 #include <mt/query/linguas.hh>
40 #include <mt/query/translation.hh>
41 #include <mt/query/singleton.hh>
42 #include <mt/query/config.hh>
43 #include <mt/query/file_map.hh>
44 #include <mt/support/path.hh>
45 #include <mt/query/lgk.hh>
46 #include <mt/support/str.hh>
47 #include <mt/query/lang_info.hh>
48
49 #include <algorithm>
50 #include <functional>
51 #include <memory>
52
53 #include <iostream>
54 #include <stdexcept>
55 #include <vector>
56 #include <string>
57
58
59
60 typedef mt::singleton_array<mt::file_map> txtdb_type;
61
62 struct compare_names
63 {
compare_namescompare_names64 compare_names(const std::string& from,const std::string& to):
65 from_(from),
66 to_(to)
67 {}
operator ()compare_names68 bool operator()(const mt::lang_pair& lng1,const mt::lang_pair& lng2)
69 {
70 return distance(lng1) < distance(lng2);
71 }
distancecompare_names72 int distance(const mt::lang_pair& lng)
73 {
74 std::string from_name=mt::lang_name(lng.first);
75 std::string to_name=mt::lang_name(lng.second);
76
77 return (!from_.empty() && !from_name.compare(0,from_.size(),from_)) +
78 (!to_.empty() && !to_name.compare(0,to_.size(),to_));
79 }
80 std::string from_,to_;
81 };
82
compare_articles(const mt::article & a1,const mt::article & a2)83 int compare_articles(const mt::article& a1,const mt::article& a2)
84 {
85 if (a1.lgk() != a2.lgk())
86 return a2.lgk() > a1.lgk();
87 else
88 return a2.subject() > a1.subject();
89 }
90
91
92
93 struct show
94 {
showshow95 show(std::string& r_, bool& found_): r(r_),found(found_) {}
operator ()show96 void operator()(mt::article_set as)
97 {
98 mt::file_map& subj = txtdb_type::instance(mt::datapath+mt::path_separator()+"subjects.txt");
99 mt::file_map& spart = txtdb_type::instance(mt::datapath+mt::path_separator()+"speechparts.txt");
100
101 if (!as.articles_.empty())
102 {
103 found=true;
104 std::sort(as.articles_.begin(),as.articles_.end(),compare_articles);
105
106 int prev_lgk = -1;
107 std::string prev_subject = "x";
108 for(size_t i=0;i<as.articles_.size();++i)
109 {
110 const mt::article& a = as.articles_[i];
111 if (prev_lgk != a.lgk())
112 {
113 r+="<tr><td><b>"+a.orig()+","+
114 spart.any_name(mt::to_string<int>(mt::speech_part(a.lgk())))+"</b></td></tr>";
115 prev_lgk = a.lgk();
116 prev_subject = "x";//reset subject
117 }
118 if (prev_subject != a.subject())
119 {
120 r+="<tr><td></td><td><font class=\"explanation\">";
121 r+=subj.any_name(a.subject());
122 r+="</font></td><td>";
123 r+=a.translated();
124 prev_subject = a.subject();
125 }
126 else
127 r+=", "+a.translated();
128 }
129 r+="</td></tr>";
130 }
131 }
132 std::string &r;
133 bool& found;
134 };
135
do_translate(const std::string & text,mt::lang_code from,mt::lang_code to)136 std::string do_translate(const std::string& text,mt::lang_code from,mt::lang_code to)
137 {
138 bool found=false;
139 std::string r="<table>";
140 mt::phrase ph;
141 mt::fill_phrase(ph,text,from);
142 mt::translation tr(ph,from,to);
143 std::for_each(tr.asets().begin(), tr.asets().end(), show(r,found));
144 r+="</table>";
145 if (found)
146 return r;
147 return "";
148 }
149
150
151
152
153
154
155
156
157
158
Multitran(QObject * parent)159 Multitran::Multitran(QObject *parent)
160 : QObject(parent)
161 {
162 // QSettings settings("qstardict","qstardict");
163 // m_dictDirs = settings.value("Multitran/dictDirs", m_dictDirs).toStringList();
164 // m_reformatLists = settings.value("Multitran/reformatLists", true).toBool();
165 }
166
~Multitran()167 Multitran::~Multitran()
168 {
169 // QSettings settings("qstardict","qstardict");
170 // settings.setValue("Multitran/dictDirs", m_dictDirs);
171 // settings.setValue("Multitran/reformatLists", m_reformatLists);
172 }
173
availableDicts() const174 QStringList Multitran::availableDicts() const
175 {
176 return QStringList("Multitran");
177 }
178
setLoadedDicts(const QStringList & loadedDicts)179 void Multitran::setLoadedDicts(const QStringList &loadedDicts)
180 {
181 }
182
dictInfo(const QString & dict)183 Multitran::DictInfo Multitran::dictInfo(const QString &dict)
184 {
185 // ::DictInfo nativeInfo;
186 // nativeInfo.wordcount = 0;
187
188 DictInfo result(name(), dict);
189 result.setAuthor("Multitran.ru");
190 result.setDescription(tr("1 mln words excerpt of multitran.ru"));
191 result.setWordsCount(-1);
192 return result;
193 }
194
isTranslatable(const QString & dict,const QString & word)195 bool Multitran::isTranslatable(const QString &dict, const QString &word)
196 {
197 return true;
198 }
199
translate(const QString & dict,const QString & word)200 Multitran::Translation Multitran::translate(const QString &dict, const QString &word)
201 {
202 QTextCodec* c=QTextCodec::codecForMib(2251);
203 std::string text=c->fromUnicode(word).data();
204 std::string from_lang,to_lang;
205
206 int i=word.size();
207 while(--i>=0)
208 if (word.at(i).unicode()>127)
209 break;
210
211 if (i!=-1)
212 from_lang="russian";
213 else
214 from_lang="english";
215
216 mt::linguas avail_langs;
217 mt::linguas::iterator lang = std::max_element(avail_langs.begin(),
218 avail_langs.end(),
219 compare_names(from_lang,to_lang));
220 if (lang == avail_langs.end() ||
221 (!from_lang.empty() && !to_lang.empty() && (compare_names(from_lang,to_lang).distance(*lang)!=2)))
222 {
223 //std::cerr<<"illegal language names"<<std::endl;
224 return Translation();
225 }
226
227 //"<hr width=50%><center><b>multitran</b><center><hr width=50%>";
228 QString queryResult=c->toUnicode(do_translate(lower_str(lang->first,text),
229 lang->first,lang->second).c_str());
230
231 if (queryResult.isEmpty())
232 return Translation();
233
234 return Translation(word,"Multitran",queryResult);
235 }
236
findSimilarWords(const QString & dict,const QString & word)237 QStringList Multitran::findSimilarWords(const QString &dict, const QString &word)
238 {
239 return QStringList();
240 }
241
execSettingsDialog(QWidget * parent)242 int Multitran::execSettingsDialog(QWidget *parent)
243 {
244 //::SettingsDialog dialog(this, parent);
245 //return dialog.exec();
246 return 0;
247 }
248
249 #if QT_VERSION < 0x050000
250 Q_EXPORT_PLUGIN2(multitran, Multitran)
251 #endif
252
253 // vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab cindent textwidth=120 formatoptions=tc
254