init
[qstardict] / plugins / multitran / multitran.cpp
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 {
64     compare_names(const std::string& from,const std::string& to):
65         from_(from),
66         to_(to)
67     {}
68     bool operator()(const mt::lang_pair& lng1,const mt::lang_pair& lng2)
69     {
70         return distance(lng1) < distance(lng2);
71     }
72     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
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 {
95     show(std::string& r_, bool& found_): r(r_),found(found_) {}
96     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
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
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
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
174 QStringList Multitran::availableDicts() const
175 {
176     return QStringList("Multitran");
177 }
178
179 void Multitran::setLoadedDicts(const QStringList &loadedDicts)
180 {
181 }
182
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
195 bool Multitran::isTranslatable(const QString &dict, const QString &word)
196 {
197     return true;
198 }
199
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
237 QStringList Multitran::findSimilarWords(const QString &dict, const QString &word)
238 {
239     return QStringList();
240 }
241
242 int Multitran::execSettingsDialog(QWidget *parent)
243 {
244     //::SettingsDialog dialog(this, parent);
245     //return dialog.exec();
246     return 0;
247 }
248
249
250 Q_EXPORT_PLUGIN2(multitran, Multitran)
251
252 // vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab cindent textwidth=120 formatoptions=tc