PageRenderTime 55ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/xiphos-3.1.5/src/backend/sword_main.cc

#
C++ | 1133 lines | 919 code | 172 blank | 42 comment | 186 complexity | f5a84fbf541f7107f75559402bebe31f MD5 | raw file
Possible License(s): GPL-2.0
  1. /*
  2. * Xiphos Bible Study Tool
  3. * sword_main.cc -
  4. *
  5. * Copyright (C) 2000-2011 Xiphos Developer Team
  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 Library General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
  20. */
  21. #ifdef HAVE_CONFIG_H
  22. #include <config.h>
  23. #endif
  24. #include <set>
  25. #include <swmgr.h>
  26. #include <swmodule.h>
  27. #include <localemgr.h>
  28. #include <swversion.h>
  29. #include <filemgr.h>
  30. #include <markupfiltmgr.h>
  31. #include <swlocale.h>
  32. #include <gtk/gtk.h>
  33. #include <versekey.h>
  34. #include <regex.h>
  35. #include <string.h>
  36. #include <utf8html.h>
  37. #include <url.h>
  38. #include "backend/sword_main.hh"
  39. #include "main/mod_mgr.h"
  40. #include "main/settings.h"
  41. #include "main/sword.h"
  42. #include "main/search_sidebar.h"
  43. #include "main/search_dialog.h"
  44. #include "gui/dialog.h"
  45. #include "gui/debug_glib_null.h"
  46. using namespace sword;
  47. using namespace std;
  48. BackEnd *backend = NULL;
  49. #ifdef DEBUG
  50. static const char *f_message = "backend/sword_main.cc line #%d \"%s\" = %s";
  51. #endif
  52. BackEnd::BackEnd()
  53. {
  54. #ifdef DEBUG
  55. GTimer *t;
  56. double d;
  57. t = g_timer_new();
  58. #endif
  59. main_mgr = new SWMgr(new MarkupFilterMgr(FMT_HTMLHREF));
  60. #ifdef DEBUG
  61. g_timer_stop(t);
  62. d = g_timer_elapsed(t, NULL);
  63. GS_message(("create main_mgr time is %f", d));
  64. #endif
  65. display_mod = NULL;
  66. tree_key = NULL;
  67. commDisplay = 0;
  68. bookDisplay = 0;
  69. dictDisplay = 0;
  70. textDisplay = 0;
  71. entryDisplay = 0;
  72. chapDisplay = 0;
  73. verselistDisplay = 0;
  74. viewerDisplay = 0;
  75. }
  76. BackEnd::~BackEnd()
  77. {
  78. if (main_mgr)
  79. delete main_mgr;
  80. main_mgr = 0;
  81. if (commDisplay)
  82. delete commDisplay;
  83. if (bookDisplay)
  84. delete bookDisplay;
  85. if (dictDisplay)
  86. delete dictDisplay;
  87. if (textDisplay)
  88. delete textDisplay;
  89. if (entryDisplay)
  90. delete entryDisplay;
  91. if (chapDisplay)
  92. delete chapDisplay;
  93. if (verselistDisplay)
  94. delete verselistDisplay;
  95. if (viewerDisplay)
  96. delete viewerDisplay;
  97. commDisplay = 0;
  98. bookDisplay = 0;
  99. dictDisplay = 0;
  100. textDisplay = 0;
  101. entryDisplay = 0;
  102. chapDisplay = 0;
  103. verselistDisplay = 0;
  104. viewerDisplay = 0;
  105. }
  106. void BackEnd::init_SWORD(int gsType)
  107. {
  108. ModMap::iterator it;
  109. if (gsType == 0) {
  110. main_setup_displays();
  111. for (it = main_mgr->Modules.begin();
  112. it != main_mgr->Modules.end(); it++) {
  113. display_mod = (*it).second;
  114. if (!strcmp(display_mod->Type(), TEXT_MODS)) {
  115. display_mod->setDisplay(textDisplay);
  116. }
  117. if (!strcmp(display_mod->Type(), COMM_MODS)) {
  118. display_mod->setDisplay(commDisplay);
  119. }
  120. if (!strcmp(display_mod->Type(), DICT_MODS)) {
  121. display_mod->setDisplay(dictDisplay);
  122. }
  123. if (!strcmp(display_mod->Type(), BOOK_MODS)) {
  124. display_mod->setDisplay(bookDisplay);
  125. }
  126. }
  127. } else if (gsType == 1) { // dialogs
  128. for (it = main_mgr->Modules.begin(); it != main_mgr->Modules.end(); it++) {
  129. display_mod = (*it).second;
  130. if (!strcmp(display_mod->Type(), TEXT_MODS)) {
  131. display_mod->setDisplay(chapDisplay);
  132. } else {
  133. display_mod->setDisplay(entryDisplay);
  134. }
  135. }
  136. } else if (gsType == 2) { // search
  137. for (it = main_mgr->Modules.begin(); it != main_mgr->Modules.end(); it++) {
  138. display_mod = (*it).second;
  139. display_mod->setDisplay(entryDisplay);
  140. }
  141. }
  142. }
  143. void BackEnd::init_lists(MOD_LISTS * mods)
  144. {
  145. ModMap::iterator it;
  146. for (it = main_mgr->Modules.begin();
  147. it != main_mgr->Modules.end(); it++) {
  148. if (!strcmp((*it).second->Type(), TEXT_MODS)) {
  149. mods->biblemods =
  150. g_list_append(mods->biblemods,
  151. strdup((char *) (*it).second->Name()));
  152. mods->text_descriptions =
  153. g_list_append(mods->text_descriptions,
  154. strdup((char *) (*it).second->
  155. Description()));
  156. }
  157. if (!strcmp((*it).second->Type(), COMM_MODS)) {
  158. mods->commentarymods =
  159. g_list_append(mods->commentarymods,
  160. strdup((char *) (*it).second->Name()));
  161. mods->comm_descriptions =
  162. g_list_append(mods->comm_descriptions,
  163. strdup((char *) (*it).second->
  164. Description()));
  165. if (!strcmp((*it).second->getConfigEntry("ModDrv")
  166. , "RawFiles")) {
  167. mods->percommods = g_list_append(mods->percommods,
  168. strdup((char *) (*it).second->Name()));
  169. }
  170. }
  171. if (!strcmp((*it).second->Type(), DICT_MODS)) {
  172. char *feature =
  173. (char *) (*it).second->getConfigEntry("Feature");
  174. if (feature && !strcmp(feature, "DailyDevotion")) {
  175. mods->devotionmods =
  176. g_list_append(mods->devotionmods,
  177. strdup((char *) (*it).second->Name()));
  178. } else {
  179. mods->dictionarymods =
  180. g_list_append(mods->dictionarymods,
  181. strdup((char *) (*it).second->Name()));
  182. mods->dict_descriptions =
  183. g_list_append(mods->dict_descriptions,
  184. strdup((char *) (*it).second->
  185. Description()));
  186. }
  187. }
  188. if (!strcmp((*it).second->Type(), BOOK_MODS)) {
  189. if ((*it).second->getConfigEntry("GSType") &&
  190. !strcmp((*it).second->getConfigEntry("GSType")
  191. , "PrayerList")) {
  192. mods->prayermods = g_list_append(mods->prayermods,
  193. strdup((char *) (*it).second->Name()));
  194. } else {
  195. mods->bookmods =
  196. g_list_append(mods->bookmods,
  197. strdup((char *) (*it).second->Name()));
  198. mods->book_descriptions =
  199. g_list_append(mods->book_descriptions,
  200. strdup((char *) (*it).second->
  201. Description()));
  202. }
  203. }
  204. char *category =
  205. (char *) (*it).second->getConfigEntry("Category");
  206. if (!category)
  207. continue;
  208. if (!strcmp(category, "Maps"))
  209. mods->mapmods
  210. = g_list_append(mods->mapmods,
  211. strdup((char *) (*it).second->Name()));
  212. if (!strcmp(category, "Images"))
  213. mods->imagemods
  214. = g_list_append(mods->imagemods,
  215. strdup((char *) (*it).second->Name()));
  216. }
  217. }
  218. const char *BackEnd::get_sword_version(void)
  219. {
  220. SWVersion retval;
  221. retval = SWVersion::currentVersion;
  222. return retval;
  223. }
  224. GList *BackEnd::get_module_options(void)
  225. {
  226. GList *options = NULL;
  227. StringList optionslist = main_mgr->getGlobalOptions();
  228. for (StringList::iterator it = optionslist.begin();
  229. it != optionslist.end(); it++) {
  230. options = g_list_append(options, strdup((char *) (*it).c_str()));
  231. }
  232. return options;
  233. }
  234. int BackEnd::has_global_option(char * module_name, char * option)
  235. {
  236. SWModule *mod;
  237. ModMap::iterator it;
  238. it = main_mgr->Modules.find(module_name);
  239. if (it != main_mgr->Modules.end()) {
  240. mod = (*it).second;
  241. return mod->getConfig().has("GlobalOptionFilter", option);
  242. } else
  243. return 0;
  244. }
  245. char *BackEnd::get_config_entry(char * module_name, char * entry)
  246. {
  247. if ((this == NULL) || (main_mgr == NULL))
  248. return NULL;
  249. SWModule *mod;
  250. ModMap::iterator it;
  251. it = main_mgr->Modules.find(module_name);
  252. if (it != main_mgr->Modules.end()) {
  253. mod = (*it).second;
  254. return g_strdup((char *) mod->getConfigEntry(entry));
  255. } else
  256. return NULL;
  257. }
  258. void BackEnd::set_cipher_key(char * mod_name, char * key)
  259. {
  260. main_mgr->setCipherKey(mod_name, key);
  261. }
  262. int BackEnd::is_Bible_key(const char * list, char * current_key)
  263. {
  264. VerseKey key;
  265. key.setText(current_key);
  266. ListKey vs = key.ParseVerseList(list, key);
  267. return vs.Count();
  268. }
  269. char *BackEnd::get_render_text(const char *module_name, const char *key)
  270. {
  271. SWModule *mod;
  272. ModMap::iterator it;
  273. it = main_mgr->Modules.find(module_name);
  274. if (it != main_mgr->Modules.end()) {
  275. mod = (*it).second;
  276. mod->setKey(key);
  277. return strdup((char *) mod->RenderText());
  278. }
  279. return NULL;
  280. }
  281. char *BackEnd::get_raw_text(const char *module_name, const char *key)
  282. {
  283. SWModule *mod;
  284. ModMap::iterator it;
  285. it = main_mgr->Modules.find(module_name);
  286. if (it != main_mgr->Modules.end()) {
  287. mod = (*it).second;
  288. mod->setKey(key);
  289. return strdup((char *) mod->getRawEntry());
  290. }
  291. return NULL;
  292. }
  293. char *BackEnd::render_this_text(const char * module_name, const char * text)
  294. {
  295. SWModule *mod;
  296. ModMap::iterator it;
  297. it = main_mgr->Modules.find(module_name);
  298. if (it != main_mgr->Modules.end()) {
  299. mod = (*it).second;
  300. return strdup((char *) mod->RenderText(text));
  301. }
  302. return NULL;
  303. }
  304. char *BackEnd::get_strip_text_from_string(const char * module_name, const char *string)
  305. {
  306. SWModule *mod;
  307. ModMap::iterator it;
  308. it = main_mgr->Modules.find(module_name);
  309. if (it != main_mgr->Modules.end()) {
  310. mod = (*it).second;
  311. return strdup((char *) mod->StripText(string));
  312. }
  313. return NULL;
  314. }
  315. char *BackEnd::get_strip_text(const char *module_name, const char *key)
  316. {
  317. SWModule *mod;
  318. ModMap::iterator it;
  319. it = main_mgr->Modules.find(module_name);
  320. if (it != main_mgr->Modules.end()) {
  321. mod = (*it).second;
  322. mod->setKey(key);
  323. return strdup((char *) mod->StripText());
  324. }
  325. return NULL;
  326. }
  327. char *BackEnd::get_valid_key(const char *key)
  328. {
  329. VerseKey vkey;
  330. char *mykey;
  331. vkey.AutoNormalize(1);
  332. vkey = key;
  333. if ((sword_locale) && (!strcmp(sword_locale,"en")))
  334. mykey = (char*)vkey.getShortText();
  335. else
  336. mykey = (char*)vkey.getText();
  337. return strdup(mykey);
  338. }
  339. char *BackEnd::key_get_book(const char *key)
  340. {
  341. VerseKey vkey;
  342. vkey.AutoNormalize(1);
  343. vkey = key;
  344. return strdup((char*)vkey.getBookName());
  345. }
  346. int BackEnd::key_get_chapter(const char *key)
  347. {
  348. VerseKey vkey;
  349. vkey.AutoNormalize(1);
  350. vkey = key;
  351. return vkey.Chapter();
  352. }
  353. int BackEnd::key_get_verse(const char *key)
  354. {
  355. VerseKey vkey;
  356. vkey.AutoNormalize(1);
  357. vkey = key;
  358. return vkey.Verse();
  359. }
  360. unsigned int BackEnd::key_chapter_count(const char *key)
  361. {
  362. VerseKey vkey;
  363. vkey.AutoNormalize(1);
  364. vkey = key;
  365. return (vkey.getChapterMax());
  366. }
  367. unsigned int BackEnd::key_verse_count(const char *key)
  368. {
  369. VerseKey vkey;
  370. vkey.AutoNormalize(1);
  371. vkey = key;
  372. return (vkey.getVerseMax());
  373. }
  374. char *BackEnd::get_module_key()
  375. {
  376. (const char *) *display_mod;
  377. return strdup((char*)display_mod->KeyText());
  378. }
  379. void BackEnd::save_entry(const char * entry)
  380. {
  381. display_mod->setEntry((const char *) entry);
  382. }
  383. void BackEnd::save_note_entry(const char * module, const char * key, const char * entry)
  384. {
  385. display_mod = main_mgr->Modules[module];
  386. if (display_mod) {
  387. display_mod->setKey(key);
  388. display_mod->KeyText(); /* snap to entry */
  389. display_mod->setEntry((const char *) entry);
  390. GS_message (("\nsave_note_entry\nmod: %s\nkey: %s\nentry: %s",
  391. display_mod->Name(), display_mod->KeyText(),
  392. display_mod->RenderText()));
  393. }
  394. }
  395. void BackEnd::delete_entry(void)
  396. {
  397. display_mod->deleteEntry();
  398. }
  399. const char *BackEnd::module_get_language(const char *module_name)
  400. {
  401. ModMap::iterator it;
  402. it = main_mgr->Modules.find(module_name);
  403. if (it != main_mgr->Modules.end())
  404. return main_get_language_map((*it).second->Lang());
  405. return "unknown";
  406. }
  407. char **BackEnd::get_module_language_list(void)
  408. {
  409. char **retval;
  410. int i;
  411. std::set < SWBuf > module_languages;
  412. std::set < SWBuf > ::iterator ml_it;
  413. // create a set of unique language names in use by modules.
  414. ModMap::iterator it;
  415. for (it = main_mgr->Modules.begin(); it != main_mgr->Modules.end(); it++)
  416. module_languages.insert((*it).second->Lang());
  417. // construct a list of char* from the uniquified set.
  418. retval = g_new0(char *, module_languages.size() + 1);
  419. for (i = 0, ml_it = module_languages.begin();
  420. ml_it != module_languages.end();
  421. ++i, ++ml_it) {
  422. retval[i] = g_strdup(ml_it->c_str());
  423. }
  424. return retval;
  425. }
  426. int BackEnd::is_module(const char *mod_name)
  427. {
  428. if (mod_name == NULL)
  429. return 0;
  430. ModMap::iterator it = main_mgr->Modules.find(mod_name);
  431. if (it != main_mgr->Modules.end()) {
  432. return 1;
  433. }
  434. return 0;
  435. }
  436. int BackEnd::module_type(const char *mod_name)
  437. {
  438. ModMap::iterator it;
  439. if ((!mod_name) || (strlen(mod_name) < 2))
  440. return -1;
  441. it = main_mgr->Modules.find(mod_name);
  442. if (it != main_mgr->Modules.end()) {
  443. if (!strcmp((*it).second->Type(), TEXT_MODS)) {
  444. return TEXT_TYPE;
  445. }
  446. if (!strcmp((*it).second->Type(), COMM_MODS)) {
  447. if (!strcmp((char *) (*it).second->getConfigEntry("ModDrv"), "RawFiles"))
  448. return PERCOM_TYPE;
  449. return COMMENTARY_TYPE;
  450. }
  451. if (!strcmp((*it).second->Type(), DICT_MODS)) {
  452. return DICTIONARY_TYPE;
  453. }
  454. if (!strcmp((*it).second->Type(), BOOK_MODS)) {
  455. if ((*it).second->getConfigEntry("GSType") &&
  456. !strcmp((char *) (*it).second->getConfigEntry("GSType"), "PrayerList"))
  457. return PRAYERLIST_TYPE;
  458. return BOOK_TYPE;
  459. }
  460. }
  461. return -1;
  462. }
  463. char *BackEnd::module_description(char *mod_name)
  464. {
  465. ModMap::iterator it;
  466. if ((!mod_name) || (strlen(mod_name) < 2))
  467. return NULL;
  468. it = main_mgr->Modules.find(mod_name);
  469. if (it != main_mgr->Modules.end()) {
  470. return (*it).second->Description();
  471. }
  472. return NULL;
  473. }
  474. char *BackEnd::module_name_from_description(char *description)
  475. {
  476. ModMap::iterator it;
  477. char *retval = NULL;
  478. if (!description)
  479. return NULL;
  480. for (it = main_mgr->Modules.begin();
  481. it != main_mgr->Modules.end(); it++) {
  482. if (!strcmp((*it).second->Description(), description))
  483. retval = strdup((*it).second->Name());
  484. }
  485. return retval;
  486. }
  487. int BackEnd::get_key_testament(const char * key)
  488. {
  489. sword::VerseKey ikey( key );
  490. return ikey.Testament();
  491. }
  492. int BackEnd::module_has_testament(const char * module_name, int testament)
  493. {
  494. ModMap::iterator it;
  495. int ot = 0;
  496. int nt = 0;
  497. it = main_mgr->Modules.find(module_name);
  498. if (it != main_mgr->Modules.end()) {
  499. SWModule *module = (*it).second;
  500. module->setSkipConsecutiveLinks(true);
  501. *module = sword::TOP; //position to first entry
  502. sword::VerseKey key( module->KeyText() );
  503. if (key.Testament() == 1) { // OT && NT
  504. ot = 1;
  505. } else if (key.Testament() == 2) { //no OT
  506. ot = 0;
  507. }
  508. *module = sword::BOTTOM;
  509. key = module->KeyText();
  510. if (key.Testament() == 1) { // only OT, no NT
  511. nt = 0;
  512. } else if (key.Testament() == 2) { //has NT
  513. nt = 1;
  514. }
  515. module->setSkipConsecutiveLinks(false);
  516. }
  517. switch (testament) {
  518. case 1:
  519. return ot>0;
  520. case 2:
  521. return nt>0;
  522. default:
  523. return false;
  524. }
  525. }
  526. int BackEnd::module_get_testaments(const char * module_name)
  527. {
  528. ModMap::iterator it;
  529. int ot = 0;
  530. int nt = 0;
  531. it = main_mgr->Modules.find(module_name);
  532. if (it != main_mgr->Modules.end()) {
  533. SWModule *module = (*it).second;
  534. module->setSkipConsecutiveLinks(true);
  535. *module = sword::TOP; //position to first entry
  536. sword::VerseKey key( module->KeyText() );
  537. if (key.Testament() == 1) { // OT && NT
  538. ot = 1;
  539. } else if (key.Testament() == 2) { //no OT
  540. ot = 0;
  541. }
  542. *module = sword::BOTTOM;
  543. key = module->KeyText();
  544. if (key.Testament() == 1) { // only OT, no NT
  545. nt = 0;
  546. } else if (key.Testament() == 2) { //has NT
  547. nt = 1;
  548. }
  549. module->setSkipConsecutiveLinks(false);
  550. }
  551. if (ot && nt)
  552. return 2;
  553. else if (!ot && nt)
  554. return 1;
  555. else if (ot && !nt)
  556. return 0;
  557. return -1;
  558. }
  559. char *BackEnd::get_entry_attribute(const char *level1,
  560. const char *level2,
  561. const char *level3,
  562. bool render)
  563. {
  564. UTF8HTML u2html;
  565. if (render)
  566. display_mod->RenderText();
  567. SWBuf attribute2 = display_mod->getEntryAttributes()[level1][level2][level3].c_str();
  568. u2html.processText(attribute2);
  569. if (attribute2.length()) {
  570. return strdup(attribute2.c_str());
  571. }
  572. return NULL;
  573. }
  574. int BackEnd::set_module(const char *module_name)
  575. {
  576. display_mod = main_mgr->Modules[module_name];
  577. if (display_mod)
  578. return 1;
  579. else
  580. return 0;
  581. }
  582. int BackEnd::set_module_key(const char *module_name, const char *key)
  583. {
  584. display_mod = main_mgr->Modules[module_name];
  585. if (display_mod) {
  586. display_mod->setKey(key);
  587. return 1;
  588. }
  589. else
  590. return 0;
  591. }
  592. int BackEnd::set_key(const char *key)
  593. {
  594. if (!key)
  595. return 0;
  596. if (display_mod) {
  597. GS_message((f_message,758,"key",key));
  598. display_mod->setKey(key);
  599. return 1;
  600. }
  601. return 0;
  602. }
  603. char *BackEnd::get_key_from_offset(unsigned long offset)
  604. {
  605. if (tree_key) {
  606. TreeKeyIdx treenode = *tree_key;
  607. treenode.setOffset(offset);
  608. /** if not root node then display **/
  609. if (treenode.getOffset() > 0) {
  610. display_mod->SetKey(treenode);
  611. display_mod->KeyText(); //snap to entry
  612. }
  613. return strdup(display_mod->KeyText());
  614. }
  615. return NULL;
  616. }
  617. unsigned long BackEnd::treekey_set_key(char * key)
  618. {
  619. if (tree_key) {
  620. TreeKeyIdx treenode = *tree_key;
  621. treenode.setText(key);
  622. display_mod->SetKey(treenode);
  623. display_mod->KeyText(); //snap to entry
  624. return treenode.getOffset();
  625. }
  626. return 0;
  627. }
  628. void BackEnd::set_treekey(unsigned long offset)
  629. {
  630. if (!display_mod) {
  631. gui_generic_warning(_("Xiphos failure: \"can't happen\", display_mod: null"
  632. "\nPlease report this. sword_main.cc:set_treekey"
  633. "\nWhat were you doing when this occurred?"));
  634. return;
  635. }
  636. if (tree_key)
  637. delete tree_key;
  638. tree_key = (TreeKeyIdx *) display_mod->CreateKey();
  639. if (tree_key) {
  640. TreeKeyIdx treenode = *tree_key;
  641. treenode.setOffset(offset);
  642. /** if not root node then display **/
  643. if (treenode.getOffset() > 0) {
  644. display_mod->SetKey(treenode);
  645. display_mod->KeyText(); //snap to entry
  646. }
  647. }
  648. }
  649. unsigned long BackEnd::get_treekey_offset_from_key(const char * module_name, const char * key)
  650. {
  651. SWModule *mod;
  652. ModMap::iterator it;
  653. unsigned long retval = 0;
  654. it = main_mgr->Modules.find(module_name);
  655. if (it != main_mgr->Modules.end()) {
  656. mod = (*it).second;
  657. TreeKeyIdx *tree_key_idx = (TreeKeyIdx *) mod->CreateKey();
  658. tree_key_idx->setText(key);
  659. mod->SetKey(tree_key_idx);
  660. //(char*)mod;
  661. retval = tree_key_idx->getOffset();
  662. delete tree_key_idx;
  663. }
  664. return retval;
  665. }
  666. unsigned long BackEnd::get_treekey_offset(void)
  667. {
  668. if (tree_key)
  669. return tree_key->getOffset();
  670. return 0;
  671. }
  672. int BackEnd::treekey_has_children(unsigned long offset)
  673. {
  674. if (tree_key) {
  675. tree_key->setOffset(offset);
  676. return tree_key->hasChildren();
  677. }
  678. return false;
  679. }
  680. int BackEnd::treekey_first_child(unsigned long offset)
  681. {
  682. if (tree_key) {
  683. tree_key->setOffset(offset);
  684. return tree_key->firstChild();
  685. }
  686. return false;
  687. }
  688. int BackEnd::treekey_parent(unsigned long offset)
  689. {
  690. if (tree_key) {
  691. tree_key->setOffset(offset);
  692. return tree_key->parent();
  693. }
  694. return false;
  695. }
  696. char *BackEnd::treekey_get_local_name(unsigned long offset)
  697. {
  698. if (tree_key) {
  699. tree_key->setOffset(offset);
  700. return strdup((char *) tree_key->getLocalName());
  701. }
  702. return NULL;
  703. }
  704. int BackEnd::treekey_next_sibling(unsigned long offset)
  705. {
  706. if (tree_key) {
  707. tree_key->setOffset(offset);
  708. if (tree_key->nextSibling()) {
  709. return 1;
  710. }
  711. }
  712. return 0;
  713. }
  714. int BackEnd::treekey_prev_sibling(unsigned long offset)
  715. {
  716. if (tree_key) {
  717. tree_key->setOffset(offset);
  718. if (tree_key->previousSibling()) {
  719. return 1;
  720. }
  721. }
  722. return 0;
  723. }
  724. char *BackEnd::navigate_module(int direction)
  725. {
  726. if (direction == -1)
  727. return strdup((char *) display_mod->KeyText());
  728. switch (direction) {
  729. case 0:
  730. (*display_mod)--;
  731. break;
  732. case 1:
  733. (*display_mod)++;
  734. break;
  735. }
  736. display_mod->Error();
  737. return strdup((char *) display_mod->KeyText());
  738. }
  739. GList *BackEnd::parse_verse_list(const char * list, char * current_key)
  740. {
  741. GList *retlist = NULL;
  742. VerseKey key;
  743. ListKey vs;
  744. if (!list)
  745. return retlist;
  746. GS_message(("current_key=%s",current_key));
  747. key.setText(current_key);
  748. vs = key.ParseVerseList(list, key, TRUE);
  749. if (!vs.Count())
  750. return retlist;
  751. while (!vs.Error()) {
  752. retlist = g_list_append(retlist, strdup((char*)vs.getText()));
  753. vs++;
  754. }
  755. return retlist;
  756. }
  757. GList *BackEnd::parse_range_list(const char * list)
  758. {
  759. GList *retlist = NULL;
  760. const char *buf = NULL;
  761. VerseKey key;
  762. verses.ClearList();
  763. verses = key.ParseVerseList(list, key, true);
  764. buf = verses.getRangeText();
  765. retlist = g_list_append(retlist, g_strdup(buf));
  766. return retlist;
  767. }
  768. void BackEnd::set_listkey_position(char pos)
  769. {
  770. results.setPosition((char)pos);
  771. }
  772. const char *BackEnd::get_next_listkey(void)
  773. {
  774. // formerly, this used a const char *retval, which was assigned
  775. // to results.getText(). this seems to have a problem in
  776. // 64-bit worlds (only), where retval would be trashed by results++
  777. // because the underlying keytext (sword/src/keys/listkey.cpp)
  778. // would be updated, leaving our retval bogus. OW.
  779. // we solve the problem by copying the data while it's current.
  780. // it's ugly (returning a pointer to a static char []) but it works.
  781. static char retval[128];
  782. while (!results.Error()) {
  783. (void) g_strlcpy(retval, results.getText(), 126);
  784. results++;
  785. return retval;
  786. }
  787. return NULL;
  788. }
  789. int BackEnd::clear_scope(void)
  790. {
  791. current_scope = 0;
  792. return 1;
  793. }
  794. int BackEnd::clear_search_list(void)
  795. {
  796. search_scope_list.ClearList();
  797. return search_scope_list.Count ();
  798. }
  799. int BackEnd::set_range(char * list)
  800. {
  801. search_range = VerseKey().ParseVerseList(list, "", true);
  802. return search_range.Count ();
  803. }
  804. void BackEnd::set_scope2range(void)
  805. {
  806. current_scope = &search_range;
  807. }
  808. int BackEnd::set_scope2last_search(void)
  809. {
  810. current_scope = &search_scope_list;//-- move searchlist into current_scope
  811. return 1;
  812. }
  813. int BackEnd::do_module_index(char *module_name)
  814. {
  815. search_mod = main_mgr->Modules[module_name];
  816. if (!search_mod)
  817. return -1;
  818. char progressunits = 70;
  819. if (!search_mod->hasSearchFramework())
  820. return 0;
  821. search_mod->deleteSearchFramework();
  822. search_mod->createSearchFramework(main_index_percent_update,
  823. (void *) &progressunits);
  824. return 1;
  825. }
  826. int BackEnd::do_module_delete_index(char *module_name)
  827. {
  828. search_mod = main_mgr->Modules[module_name];
  829. if (!search_mod)
  830. return -1;
  831. if (!search_mod->hasSearchFramework())
  832. return 0;
  833. search_mod->deleteSearchFramework();
  834. return 1;
  835. }
  836. int BackEnd::check_for_optimal_search(char * module_name)
  837. {
  838. search_mod = main_mgr->Modules[module_name];
  839. if (!search_mod)
  840. return -2;
  841. if (search_mod->hasSearchFramework() &&
  842. search_mod->isSearchOptimallySupported("God", -4, 0, 0))
  843. return -4; // ** indexed search - clucene **
  844. else
  845. return -2; // ** word search **
  846. }
  847. int BackEnd::do_module_search(char *module_name,
  848. const char *search_string,
  849. int search_type,
  850. int search_params,
  851. int is_dialog)
  852. {
  853. char progressunits = 70;
  854. results.clear();
  855. //search_scope_list.ClearList()
  856. search_mod = NULL;
  857. search_mod = main_mgr->Modules[module_name];
  858. if (!search_mod)
  859. return -1;
  860. if ((current_scope == &search_scope_list) &&
  861. (search_scope_list.Count() == 0))
  862. return 0;
  863. results = search_mod->search(search_string,
  864. search_type,
  865. search_params,
  866. current_scope, 0,
  867. (is_dialog
  868. ? main_dialog_search_percent_update
  869. : main_sidebar_search_percent_update),
  870. (void *) &progressunits);
  871. search_scope_list = results;
  872. if (search_type == -4)
  873. results.sort();
  874. return results.Count();
  875. }
  876. void BackEnd::terminate_search()
  877. {
  878. if (search_mod)
  879. search_mod->terminateSearch = true;
  880. }
  881. char *BackEnd::get_conf_file_item(const char * file, const char * mod_name, const char * item)
  882. {
  883. char *buf = NULL;
  884. SWConfig conf_file(file);
  885. conf_file.Load();
  886. buf = (char *) conf_file[mod_name][item].c_str();
  887. if (strlen(buf))
  888. return strdup(buf);
  889. else
  890. return NULL;
  891. }
  892. void BackEnd::save_conf_file_item(const char * file,
  893. const char * mod_name,
  894. const char * item,
  895. const char * value)
  896. {
  897. SWConfig conf_file(file);
  898. conf_file[mod_name][item] = value;
  899. conf_file.Save();
  900. }
  901. void BackEnd::save_module_key(char *mod_name, char *key)
  902. {
  903. SectionMap::iterator section;
  904. ConfigEntMap::iterator entry;
  905. char *fullfilename;
  906. // first try: $HOME.
  907. char *confdir = g_strdup_printf("%s/%s",
  908. settings.homedir, DOTSWORD);
  909. char *conffile = main_get_mod_config_file(mod_name, confdir);
  910. if (conffile) {
  911. fullfilename = g_strdup_printf("%s/mods.d/%s",
  912. confdir, conffile);
  913. g_free(confdir);
  914. g_free(conffile);
  915. } else {
  916. g_free(confdir);
  917. // second try: system location.
  918. conffile = main_get_mod_config_file(mod_name,
  919. settings.path_to_mods);
  920. if (conffile) {
  921. fullfilename = g_strdup_printf("%s/mods.d/%s",
  922. settings.path_to_mods,
  923. conffile);
  924. g_free(conffile);
  925. } else {
  926. gui_generic_warning(_("Configuration not found"));
  927. return;
  928. }
  929. }
  930. SWConfig *myConfig = new SWConfig(fullfilename);
  931. g_free(fullfilename);
  932. section = myConfig->Sections.find(mod_name);
  933. if (section != myConfig->Sections.end()) {
  934. entry = section->second.find("CipherKey");
  935. if (entry != section->second.end()) {
  936. //-- set cipher key
  937. entry->second = key;
  938. //-- save config file
  939. myConfig->Save();
  940. }
  941. }
  942. delete myConfig;
  943. }
  944. const char *BackEnd::get_osisref_from_key(const char *module, const char *key)
  945. {
  946. ModMap::iterator it;
  947. // we need an OSISRef in module-sensitive context.
  948. // fallback positions: we hope for a supplied module.
  949. // if not, assume KJV (v11n historical reasons; not anglocentric).
  950. // if not, use the 1st module...by which time we're just guessing.
  951. it = main_mgr->Modules.find((module && *module) ? module : "KJV");
  952. if (it == main_mgr->Modules.end()) {
  953. it = main_mgr->Modules.begin();
  954. if (it == main_mgr->Modules.end())
  955. return "";
  956. }
  957. VerseKey *vk = (VerseKey *)(*it).second->getKey();
  958. *vk = key;
  959. return vk->getOSISRef();
  960. }
  961. /* end of file */