1 /*********
2 *
3 * In the name of the Father, and of the Son, and of the Holy Spirit.
4 *
5 * This file is part of BibleTime's source code, http://www.bibletime.info/.
6 *
7 * Copyright 1999-2016 by the BibleTime developers.
8 * The BibleTime source code is licensed under the GNU General Public License
9 * version 2.0.
10 *
11 **********/
12
13 #include "moduleinterface.h"
14
15 #include "qtquick2applicationviewer.h"
16
17 #include "backend/config/btconfig.h"
18 #include "backend/bookshelfmodel/btbookshelftreemodel.h"
19 #include "backend/managers/cswordbackend.h"
20 #include "backend/keys/cswordversekey.h"
21 #include "mobile/util/findqmlobject.h"
22 #include "mobile/btmmain.h"
23 #include <cmath>
24 #include <QQuickItem>
25 #include <QQmlProperty>
26 #include <QQmlContext>
27 #include <QDebug>
28 #include <QQmlProperty>
29 #include <QCoreApplication>
30 #include "btwindowinterface.h"
31 #include "gridchooser.h"
32
33 namespace btm {
34
35 struct FontSettings {
36 QString language;
37 QString fontName;
38 qreal fontSize;
39 };
40
41 static QList<FontSettings> savedFontSettings;
42
ModuleInterface()43 ModuleInterface::ModuleInterface() {
44 }
45
46 enum TextRoles {
47 TextRole = Qt::UserRole + 1
48 };
49
50 using MRole = BtBookshelfModel::ModuleRole;
51 static const MRole HR(BtBookshelfModel::ModuleHiddenRole);
52 static const MRole PR(BtBookshelfModel::ModulePointerRole);
53 static const MRole IR(BtBookshelfModel::ModuleHasIndexRole);
54 static const MRole CR(BtBookshelfModel::ModuleCategoryRole);
55
setupTextModel(const QSet<QString> & modelSet,RoleItemModel * model)56 static void setupTextModel(const QSet<QString>& modelSet, RoleItemModel* model) {
57
58 QHash<int, QByteArray> roleNames;
59 roleNames[TextRole] = "modelText";
60 model->setRoleNames(roleNames);
61
62 QStringList modelList = modelSet.toList();
63 modelList.sort();
64
65 model->clear();
66 for (int i=0; i< modelList.count(); ++i) {
67 QString source = modelList.at(i);
68 QStandardItem* item = new QStandardItem();
69 item->setData(source, TextRole);
70 model->appendRow(item);
71 }
72 }
73
getModule(BtBookshelfModel * bookshelfModel,const QModelIndex & index)74 static CSwordModuleInfo* getModule(BtBookshelfModel* bookshelfModel, const QModelIndex& index) {
75 QVariant var = bookshelfModel->data(index, PR);
76 CSwordModuleInfo* module = static_cast<CSwordModuleInfo*>(var.value<void*>());
77 return module;
78 }
79
updateCategoryAndLanguageModels()80 void ModuleInterface::updateCategoryAndLanguageModels() {
81 QQuickItem* object = findQmlObject("moduleChooser");
82 if (object == nullptr)
83 return;
84
85 getCategoriesAndLanguages();
86 setupTextModel(m_categories, &m_categoryModel);
87 setupTextModel(m_languages, &m_languageModel);
88 updateWorksModel();
89 object->setProperty("categoryModel", QVariant::fromValue(&m_categoryModel));
90 object->setProperty("languageModel", QVariant::fromValue(&m_languageModel));
91 }
92
getCategoriesAndLanguages()93 void ModuleInterface::getCategoriesAndLanguages() {
94
95 m_categories.clear();
96 m_languages.clear();
97
98 QQuickItem* object = findQmlObject("moduleChooser");
99 if (object == nullptr)
100 return;
101
102 BtBookshelfModel* bookshelfModel = CSwordBackend::instance()->model();
103 if (bookshelfModel == nullptr)
104 return;
105 int count = bookshelfModel->rowCount();
106 for (int row=0; row<count; ++row) {
107 QModelIndex index = bookshelfModel->index(row);
108 CSwordModuleInfo* module = getModule(bookshelfModel, index);
109 CSwordModuleInfo::Category category = module->category();
110 QString categoryName = module->categoryName(category);
111 const CLanguageMgr::Language* language = module->language();
112 QString languageName = language->translatedName();
113 m_categories.insert(categoryName);
114 m_languages.insert(languageName);
115 }
116 }
117
installedModuleLanguages()118 QStringList ModuleInterface::installedModuleLanguages() {
119 QStringList languages;
120 CLanguageMgr::LangMap langMap = CLanguageMgr::instance()->availableLanguages();
121 for (auto lang: langMap) {
122 languages << lang->englishName();
123 }
124 return languages;
125 }
126
127
updateWorksModel()128 void ModuleInterface::updateWorksModel() {
129 m_worksModel.clear();
130 m_modules.clear();
131
132 QString currentLang = currentLanguage();
133 QString currentCat = currentCategory();
134
135 QHash<int, QByteArray> roleNames;
136 roleNames[TextRole] = "modelText";
137 m_worksModel.setRoleNames(roleNames);
138
139 BtBookshelfModel* bookshelfModel = CSwordBackend::instance()->model();
140 if (bookshelfModel == nullptr)
141 return;
142 int count = bookshelfModel->rowCount();
143 for (int row=0; row<count; ++row) {
144 QModelIndex index = bookshelfModel->index(row);
145 CSwordModuleInfo* module = getModule(bookshelfModel, index);
146 CSwordModuleInfo::Category category = module->category();
147 QString categoryName = module->categoryName(category);
148 const CLanguageMgr::Language* language = module->language();
149 QString languageName = language->translatedName();
150 if (languageName == currentLang &&
151 categoryName == currentCat) {
152 m_modules << module;
153 QString moduleName = module->name();
154 QStandardItem* item = new QStandardItem();
155 item->setData(moduleName, TextRole);
156 m_worksModel.appendRow(item);
157 }
158 }
159
160 QQuickItem* object = findQmlObject("moduleChooser");
161 if (object == nullptr)
162 return;
163 object->setProperty("worksModel", QVariant::fromValue(&m_worksModel));
164 }
165
currentLanguage() const166 QString ModuleInterface::currentLanguage() const {
167 QQuickItem* object = findQmlObject("moduleChooser");
168 if (object == nullptr)
169 return "";
170 int row = object->property("languageIndex").toInt();
171 QModelIndex modelIndex = m_languageModel.index(row,0);
172 QString language = modelIndex.data(TextRole).toString();
173 return language;
174
175 }
176
currentCategory() const177 QString ModuleInterface::currentCategory() const {
178 QQuickItem* object = findQmlObject("moduleChooser");
179 if (object == nullptr)
180 return "";
181 int row = object->property("categoryIndex").toInt();
182 QModelIndex modelIndex = m_categoryModel.index(row,0);
183 QString category = modelIndex.data(TextRole).toString();
184 return category;
185 }
186
category(int index)187 QString ModuleInterface::category(int index) {
188 if (index < 0 || index >= m_modules.count())
189 return "";
190 CSwordModuleInfo* module = m_modules.at(index);
191 if (module == nullptr)
192 return "";
193 CSwordModuleInfo::Category category = module->category();
194 if (category == 0)
195 return "";
196 return module->categoryName(category);
197 }
198
englishCategory(int index)199 QString ModuleInterface::englishCategory(int index) {
200 if (index < 0 || index >= m_modules.count())
201 return "";
202 CSwordModuleInfo* module = m_modules.at(index);
203 if (module == nullptr)
204 return "";
205 CSwordModuleInfo::Category category = module->category();
206 if (category == 0)
207 return "";
208 return module->englishCategoryName(category);
209 }
210
language(int index)211 QString ModuleInterface::language(int index) {
212 if (index < 0 || index >= m_modules.count())
213 return "";
214 CSwordModuleInfo* module = m_modules.at(index);
215 if (module == nullptr)
216 return "";
217 const CLanguageMgr::Language* language = module->language();
218 if (language == nullptr)
219 return "";
220 return language->translatedName();
221 }
222
module(int index)223 QString ModuleInterface::module(int index) {
224 if (index < 0 || index >= m_modules.count())
225 return "";
226 CSwordModuleInfo* module = m_modules.at(index);
227 if (module == nullptr)
228 return "";
229 return module->name();
230 }
231
isLocked(const QString & moduleName)232 bool ModuleInterface::isLocked(const QString& moduleName) {
233 CSwordModuleInfo* module = CSwordBackend::instance()->findModuleByName(moduleName);
234 if (module) {
235
236 // Verse intros must be false for checking lock
237 if (module->type() == CSwordModuleInfo::Bible ||
238 module->type() == CSwordModuleInfo::Commentary) {
239 ((sword::VerseKey*)(module->module().getKey()))->setIntros(false);
240 }
241
242 bool locked = module->isLocked();
243 return locked;
244 }
245 return false;
246 }
247
unlock(const QString & moduleName,const QString & unlockKey)248 void ModuleInterface::unlock(const QString& moduleName, const QString& unlockKey) {
249 CSwordModuleInfo* module = CSwordBackend::instance()->findModuleByName(moduleName);
250 if (module) {
251 module->unlock(unlockKey);
252
253 // Re-initialize module pointers:
254 CSwordBackend *backend = CSwordBackend::instance();
255 backend->reloadModules(CSwordBackend::OtherChange);
256 module = CSwordBackend::instance()->findModuleByName(moduleName);
257 updateWorksModel();
258 }
259 }
260
getLanguageFromEnglishName(const QString & name)261 static const CLanguageMgr::Language* getLanguageFromEnglishName(const QString& name) {
262 CLanguageMgr::LangMap langMap = CLanguageMgr::instance()->availableLanguages();
263 for (auto l: langMap) {
264 if (l->englishName() == name)
265 return l;
266 }
267 return nullptr;
268 }
269
getFontNameForLanguage(const QString & language)270 QString ModuleInterface::getFontNameForLanguage(const QString& language)
271 {
272 auto lang = getLanguageFromEnglishName(language);
273 if (lang) {
274 BtConfig::FontSettingsPair fontPair = btConfig().getFontForLanguage(*lang);
275 if (fontPair.first) {
276 QFont font = fontPair.second;
277 QString fontFamily = font.family();
278 return fontFamily;
279 }
280 }
281 QString fontFamily = getDefaultFont().family();
282 return fontFamily;
283 }
284
getFontSizeForLanguage(const QString & language)285 qreal ModuleInterface::getFontSizeForLanguage(const QString& language)
286 {
287 auto lang = getLanguageFromEnglishName(language);
288 if (lang) {
289 BtConfig::FontSettingsPair fontPair = btConfig().getFontForLanguage(*lang);
290 if (fontPair.first) {
291 QFont font = fontPair.second;
292 int fontPointSize = font.pointSize();
293 return fontPointSize;
294 }
295 }
296 qreal pointSize = getDefaultFont().pointSizeF();
297 return pointSize;
298 }
299
setFontForLanguage(const QString & language,const QString & fontName,qreal fontSize)300 void ModuleInterface::setFontForLanguage(const QString& language, const QString& fontName, qreal fontSize) {
301 if (CLanguageMgr::instance() == nullptr)
302 return;
303 auto lang = getLanguageFromEnglishName(language);
304 if (lang) {
305
306 QFont font;
307 font.setFamily(fontName);
308 font.setPointSizeF(fontSize);
309 BtConfig::FontSettingsPair fontPair;
310 fontPair.first = true;
311 fontPair.second = font;
312 btConfig().setFontForLanguage(*lang, fontPair);
313 }
314 }
315
saveCurrentFonts()316 void ModuleInterface::saveCurrentFonts() {
317 savedFontSettings.clear();
318 CLanguageMgr::LangMap langMap = CLanguageMgr::instance()->availableLanguages();
319 for (auto lang: langMap) {
320 BtConfig::FontSettingsPair fontPair = btConfig().getFontForLanguage(*lang);
321 if (fontPair.first) {
322 FontSettings fontSettings;
323 QFont font = fontPair.second;
324 fontSettings.language = lang->englishName();
325 fontSettings.fontName = font.family();
326 fontSettings.fontSize = font.pointSize();
327 savedFontSettings.append(fontSettings);
328 }
329 }
330 }
331
restoreSavedFonts()332 void ModuleInterface::restoreSavedFonts() {
333 for (auto fontSettings : savedFontSettings) {
334 setFontForLanguage(fontSettings.language, fontSettings.fontName, fontSettings.fontSize);
335 }
336 }
337
338 } // end namespace
339