dictcore.cpp 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. /*****************************************************************************
  2. * dictcore.cpp - QStarDict, a StarDict clone written using Qt *
  3. * Copyright (C) 2008 Alexander Rodin *
  4. * *
  5. * This program is free software; you can redistribute it and/or modify *
  6. * it under the terms of the GNU General Public License as published by *
  7. * the Free Software Foundation; either version 2 of the License, or *
  8. * (at your option) any later version. *
  9. * *
  10. * This program is distributed in the hope that it will be useful, *
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  13. * GNU General Public License for more details. *
  14. * *
  15. * You should have received a copy of the GNU General Public License along *
  16. * with this program; if not, write to the Free Software Foundation, Inc., *
  17. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
  18. *****************************************************************************/
  19. #include "dictcore.h"
  20. #include <QApplication>
  21. #include <QFileInfoList>
  22. #include <QFileInfo>
  23. #include <QDir>
  24. #include <QRegExp>
  25. #include <QSettings>
  26. #include <QDebug>
  27. #include <QPluginLoader>
  28. #include "../plugins/dictplugin.h"
  29. namespace QStarDict
  30. {
  31. DictCore::DictCore(QObject *parent)
  32. : QObject(parent)
  33. {
  34. loadSettings();
  35. }
  36. DictCore::~DictCore()
  37. {
  38. saveSettings();
  39. foreach (QPluginLoader *loader, m_plugins)
  40. {
  41. delete loader->instance();
  42. delete loader;
  43. }
  44. }
  45. bool DictCore::isTranslatable(const QString &word)
  46. {
  47. for (QList<Dictionary>::const_iterator i = m_loadedDicts.begin(); i != m_loadedDicts.end(); ++i)
  48. {
  49. if (! m_plugins.contains(i->plugin()))
  50. continue;
  51. if (qobject_cast<DictPlugin*>(m_plugins[i->plugin()]->instance())->isTranslatable(i->name(), word))
  52. return true;
  53. }
  54. return false;
  55. }
  56. QString DictCore::translate(const QString &word)
  57. {
  58. QString simplifiedWord = word.simplified();
  59. QString result;
  60. for (QList<Dictionary>::const_iterator i = m_loadedDicts.begin(); i != m_loadedDicts.end(); ++i)
  61. {
  62. if (! m_plugins.contains(i->plugin()))
  63. continue;
  64. DictPlugin *plugin = qobject_cast<DictPlugin*>(m_plugins[i->plugin()]->instance());
  65. if (! plugin->isTranslatable(i->name(), simplifiedWord))
  66. continue;
  67. DictPlugin::Translation translation = plugin->translate(i->name(), simplifiedWord);
  68. result += "<p>\n"
  69. "<font class=\"dict_name\">" + translation.dictName() + "</font><br>\n"
  70. "<font class=\"title\">" + translation.title() + "</font><br>\n"
  71. + translation.translation() + "</p>\n";
  72. }
  73. return result;
  74. }
  75. QStringList DictCore::findSimilarWords(const QString &word)
  76. {
  77. QString simplifiedWord = word.simplified();
  78. QStringList result;
  79. for (QList<Dictionary>::const_iterator i = m_loadedDicts.begin(); i != m_loadedDicts.end(); ++i)
  80. {
  81. if (! m_plugins.contains(i->plugin()))
  82. continue;
  83. DictPlugin *plugin = qobject_cast<DictPlugin*>(m_plugins[i->plugin()]->instance());
  84. if (! plugin->features().testFlag(DictPlugin::SearchSimilar))
  85. continue;
  86. QStringList similar = plugin->findSimilarWords(i->name(), simplifiedWord);
  87. for (QStringList::const_iterator j = similar.begin(); j != similar.end(); ++j)
  88. if (! result.contains(*j, Qt::CaseSensitive))
  89. result << *j;
  90. }
  91. return result;
  92. }
  93. QStringList DictCore::availablePlugins() const
  94. {
  95. QStringList result;
  96. #ifdef Q_OS_WIN
  97. QFileInfoList files = QDir(QSTARDICT_PLUGINS_DIR).entryInfoList(QStringList("*0.dll"),
  98. QDir::Files | QDir::NoDotAndDotDot);
  99. for (QFileInfoList::const_iterator i = files.begin(); i != files.end(); ++i)
  100. result << i->fileName().left(i->fileName().length() - 5);
  101. #elif defined Q_OS_MAC
  102. QStringList macFilters;
  103. // various Qt versions...
  104. macFilters << "*.dylib" << "*.bundle" << "*.so";
  105. QString binPath = QCoreApplication::applicationDirPath();
  106. // navigate through mac's bundle tree structore
  107. QDir d(binPath + "/../lib/");
  108. QFileInfoList files = d.entryInfoList(macFilters,
  109. QDir::Files | QDir::NoDotAndDotDot);
  110. for (QFileInfoList::const_iterator i = files.begin(); i != files.end(); ++i) {
  111. result << i->fileName();
  112. }
  113. #elif defined Q_OS_UNIX
  114. QFileInfoList files = QDir(QSTARDICT_PLUGINS_DIR).entryInfoList(QStringList("lib*.so"),
  115. QDir::Files | QDir::NoDotAndDotDot);
  116. for (QFileInfoList::const_iterator i = files.begin(); i != files.end(); ++i)
  117. result << i->fileName().mid(3, i->fileName().length() - 6);
  118. #else
  119. #error "Function DictCore::availablePlugins() is not implemented on this platform"
  120. #endif
  121. return result;
  122. }
  123. void DictCore::setLoadedPlugins(const QStringList &loadedPlugins)
  124. {
  125. for (QHash <QString, QPluginLoader*>::iterator i = m_plugins.begin(); i != m_plugins.end(); ++i)
  126. {
  127. delete (*i)->instance();
  128. delete *i;
  129. }
  130. m_plugins.clear();
  131. for (QStringList::const_iterator i = loadedPlugins.begin(); i != loadedPlugins.end(); ++i)
  132. {
  133. #ifdef Q_OS_WIN
  134. QString pluginFilename = static_cast<QString>(QSTARDICT_PLUGINS_DIR) + "/" + *i + "0.dll";
  135. #elif defined Q_OS_MAC
  136. // here we need to follow mac's bundle tree...
  137. QString pluginFilename = QDir(QCoreApplication::applicationDirPath()+"/../lib/"+*i).absolutePath();
  138. #elif defined Q_OS_UNIX
  139. QString pluginFilename = static_cast<QString>(QSTARDICT_PLUGINS_DIR) + "/" "lib" + *i + ".so";
  140. #else
  141. #error "Function DictCore::setLoadedPlugins(const QStringList &loadedPlugins) is not available on this platform"
  142. #endif
  143. QPluginLoader *plugin = new QPluginLoader(pluginFilename);
  144. if (! plugin->load())
  145. {
  146. qWarning() << plugin->errorString();
  147. delete plugin;
  148. continue;
  149. }
  150. m_plugins[*i] = plugin;
  151. }
  152. }
  153. QList<DictCore::Dictionary> DictCore::availableDicts() const
  154. {
  155. QList<Dictionary> result;
  156. for (QHash<QString, QPluginLoader*>::const_iterator i = m_plugins.begin(); i != m_plugins.end(); ++i)
  157. {
  158. DictPlugin *plugin = qobject_cast<DictPlugin*>((*i)->instance());
  159. QStringList dicts = plugin->availableDicts();
  160. for (QStringList::const_iterator j = dicts.begin(); j != dicts.end(); ++j)
  161. result << Dictionary(i.key(), *j);
  162. }
  163. return result;
  164. }
  165. void DictCore::setLoadedDicts(const QList<Dictionary> &loadedDicts)
  166. {
  167. QHash<QString, QStringList> dicts;
  168. for (QList<Dictionary>::const_iterator i = loadedDicts.begin(); i != loadedDicts.end(); ++i)
  169. dicts[i->plugin()] << i->name();
  170. for (QHash<QString, QStringList>::const_iterator i = dicts.begin(); i != dicts.end(); ++i)
  171. {
  172. if (! m_plugins.contains(i.key()))
  173. continue;
  174. DictPlugin *plugin = qobject_cast<DictPlugin*>(m_plugins[i.key()]->instance());
  175. plugin->setLoadedDicts(*i);
  176. dicts[i.key()] = plugin->loadedDicts();
  177. }
  178. m_loadedDicts.clear();
  179. for (QList<Dictionary>::const_iterator i = loadedDicts.begin(); i != loadedDicts.end(); ++i)
  180. if (dicts.contains(i->plugin()) && dicts[i->plugin()].contains(i->name()))
  181. m_loadedDicts << *i;
  182. }
  183. void DictCore::saveSettings()
  184. {
  185. QSettings config;
  186. config.setValue("DictCore/loadedPlugins", loadedPlugins());
  187. QStringList rawDictsList;
  188. for (QList<Dictionary>::const_iterator i = m_loadedDicts.begin(); i != m_loadedDicts.end(); ++i)
  189. rawDictsList << i->plugin() << i->name();
  190. config.setValue("DictCore/loadedDicts", rawDictsList);
  191. }
  192. void DictCore::loadSettings()
  193. {
  194. QSettings config;
  195. setLoadedPlugins(config.value("DictCore/loadedPlugins", availablePlugins()).toStringList());
  196. QStringList rawDictsList = config.value("DictCore/loadedDicts").toStringList();
  197. if (rawDictsList.isEmpty())
  198. setLoadedDicts(availableDicts());
  199. else
  200. {
  201. QList<Dictionary> dicts;
  202. for (QStringList::const_iterator i = rawDictsList.begin(); i != rawDictsList.end(); i += 2)
  203. dicts << Dictionary(*i, *(i + 1));
  204. setLoadedDicts(dicts);
  205. }
  206. }
  207. void DictCore::reloadDicts()
  208. {
  209. QList<Dictionary> loaded;
  210. for (QHash<QString, QPluginLoader*>::const_iterator i = m_plugins.begin(); i != m_plugins.end(); ++i)
  211. {
  212. DictPlugin *plugin = qobject_cast<DictPlugin*>((*i)->instance());
  213. plugin->setLoadedDicts(plugin->loadedDicts());
  214. QStringList loadedNames = plugin->loadedDicts();
  215. for (QStringList::const_iterator j = loadedNames.begin(); j != loadedNames.end(); ++j)
  216. loaded << Dictionary(i.key(), *j);
  217. }
  218. QList<Dictionary> oldLoaded = m_loadedDicts;
  219. m_loadedDicts.clear();
  220. for (QList<Dictionary>::iterator i = oldLoaded.begin(); i != oldLoaded.end(); ++i)
  221. if (loaded.contains(*i))
  222. m_loadedDicts << *i;
  223. }
  224. }
  225. // vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab cindent textwidth=120 formatoptions=tc