PageRenderTime 52ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 1ms

/xiphos-3.1.5/src/main/search_dialog.cc

#
C++ | 1649 lines | 1003 code | 222 blank | 424 comment | 114 complexity | 7b99b1612185f39a906bd05208cb4e61 MD5 | raw file
Possible License(s): GPL-2.0
  1. /*
  2. * Xiphos Bible Study Tool
  3. * search_dialog.cc - glue (: very sticky :)
  4. *
  5. * Copyright (C) 2004-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 <gtk/gtk.h>
  25. #include <regex.h>
  26. #include <swbuf.h>
  27. #include <swmodule.h>
  28. #define XIPHOS_HTML_EXTERN_C
  29. #include "../xiphos_html/xiphos_html.h"
  30. #ifdef __cplusplus
  31. extern "C" {
  32. #ifdef GTKHTML
  33. #include <gtkhtml/gtkhtml.h>
  34. #endif
  35. }
  36. #endif
  37. #include "main/previewer.h"
  38. #include "main/search_dialog.h"
  39. #include "main/settings.h"
  40. #include "main/sword.h"
  41. #include "main/xml.h"
  42. #include "main/url.hh"
  43. #include "gui/search_dialog.h"
  44. #include "gui/bookmark_dialog.h"
  45. #include "gui/bookmarks_treeview.h"
  46. #include "gui/sidebar.h"
  47. #include "gui/widgets.h"
  48. #include "gui/dialog.h"
  49. #include "gui/utilities.h"
  50. #include "gui/export_bookmarks.h"
  51. #include "backend/sword_main.hh"
  52. #include "gui/debug_glib_null.h"
  53. #define SEARCHING _("Searching the ")
  54. #define SMODULE _(" Module")
  55. #define FINDS _("found in ")
  56. #define HTML_START "<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\"><STYLE type=\"text/css\"><!-- A { text-decoration:none } *[dir=rtl] { text-align: right; } --></STYLE></head>"
  57. static BackEnd *backendSearch = NULL;
  58. static gboolean is_running = FALSE;
  59. extern int search_dialog;
  60. static GList *get_custom_list_from_name(const gchar * label);
  61. static void add_ranges(void);
  62. static void add_modlist(void);
  63. gboolean terminate_search; // also accessed from search_dialog.c.
  64. gboolean search_active; // also accessed from search_dialog.c.
  65. static GList *list_of_finds;
  66. static GList *list_for_bookmarking = NULL;
  67. /******************************************************************************
  68. * Name
  69. * main_export_current_adv_search
  70. *
  71. * Synopsis
  72. * #include "main/search_dialog.h"
  73. *
  74. * void main_export_current_adv_search(GString * str, gboolean html)
  75. *
  76. * Description
  77. * exports search results to html or plain text
  78. *
  79. *
  80. * Return value
  81. * void
  82. */
  83. gboolean main_export_current_adv_search (GString * str, gboolean html, gboolean with_scripture)
  84. {
  85. GList *verses = NULL;
  86. GList *tmp = NULL;
  87. RESULTS *list_item;
  88. gboolean ret = FALSE;
  89. gchar *desc;
  90. tmp = g_list_first(list_for_bookmarking);
  91. if (html)
  92. str = g_string_append(str, "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" /></head><body>");
  93. while (tmp) {
  94. verses = (GList*) tmp->data;
  95. GString *verse_string = g_string_new("");
  96. gboolean first_entry = TRUE;
  97. while (verses) {
  98. list_item = (RESULTS *) verses->data;
  99. if (main_is_Bible_key(list_item->key)) {
  100. ret = TRUE;
  101. if (first_entry) {
  102. if (html)
  103. g_string_printf(verse_string, "<ul><b>%s</b>", list_item->module);
  104. else
  105. g_string_printf(verse_string, "%s\n", list_item->module);
  106. first_entry = FALSE;
  107. str = g_string_append(str, verse_string->str);
  108. } else {
  109. desc = g_strdup_printf("%s %s",
  110. list_item->key,
  111. list_item->module);
  112. if (html)
  113. gui_set_html_item ( str,
  114. desc,
  115. list_item->module,
  116. list_item->key,
  117. with_scripture);
  118. else
  119. gui_set_plain_text_item ( str,
  120. desc,
  121. list_item->module,
  122. list_item->key,
  123. with_scripture);
  124. }
  125. }
  126. verses = g_list_next(verses);
  127. }
  128. g_string_free(verse_string, TRUE);
  129. if (html)
  130. str = g_string_append(str, "</ul>");
  131. tmp = g_list_next(tmp);
  132. }
  133. return ret;
  134. }
  135. /******************************************************************************
  136. * Name
  137. * main_save_current_adv_search_as_bookmarks
  138. *
  139. * Synopsis
  140. * #include "main/search_dialog.h"
  141. *
  142. * void main_save_current_adv_search_as_bookmarks (void)
  143. *
  144. * Description
  145. * saves search results as bookmarks - single bookmark per module
  146. *
  147. *
  148. * Return value
  149. * void
  150. */
  151. void main_save_current_adv_search_as_bookmarks (void)
  152. {
  153. GList *verses = NULL;
  154. RESULTS *list_item;
  155. gchar *module_name = NULL;
  156. list_for_bookmarking = g_list_first(list_for_bookmarking);
  157. while (list_for_bookmarking) {
  158. verses = (GList*) list_for_bookmarking->data;
  159. GString *name = g_string_new(NULL);
  160. GString *verse_string = g_string_new("");
  161. gboolean first_entry = TRUE;
  162. while (verses) {
  163. list_item = (RESULTS *) verses->data;
  164. if (main_is_Bible_key(list_item->key)) {
  165. if (first_entry) {
  166. module_name = g_strdup(list_item->module);
  167. first_entry = FALSE;
  168. } else {
  169. verse_string = g_string_append(verse_string,
  170. "; ");
  171. }
  172. verse_string = g_string_append(verse_string,
  173. list_item->key);
  174. }
  175. verses = g_list_next(verses);
  176. }
  177. g_string_printf(name, _("Search result %s: %s"), module_name, settings.searchText);
  178. gui_bookmark_dialog(name->str, module_name, verse_string->str);
  179. g_string_free(name, TRUE);
  180. g_string_free(verse_string, TRUE);
  181. g_free(module_name);
  182. list_for_bookmarking = g_list_next(list_for_bookmarking);
  183. }
  184. }
  185. /******************************************************************************
  186. * Name
  187. * main_range_text_changed
  188. *
  189. * Synopsis
  190. * #include "gui/search_dialog.h"
  191. *
  192. * void main_range_text_changed(GtkEditable * editable)
  193. *
  194. * Description
  195. * text in the range text entry has changed
  196. * text is sent to the backend to get the search range list
  197. * then list_ranges is updated to the range list
  198. * and the range text in the clist_range is updated
  199. *
  200. * Return value
  201. * void
  202. */
  203. void main_range_text_changed(GtkEditable * editable)
  204. {
  205. const gchar *entry;
  206. gchar *buf = NULL;
  207. GtkTreeModel *model;
  208. GtkListStore *list_store;
  209. GtkTreeModel *model_list_ranges;
  210. GtkListStore *store_list_ranges;
  211. GtkTreeSelection *selection;
  212. GtkTreeIter selected;
  213. GtkTreeIter iter;
  214. GList *tmp = NULL;
  215. /* */
  216. model_list_ranges =
  217. gtk_tree_view_get_model(GTK_TREE_VIEW(search1.list_ranges));
  218. store_list_ranges = GTK_LIST_STORE(model_list_ranges);
  219. /* */
  220. model =
  221. gtk_tree_view_get_model(GTK_TREE_VIEW
  222. (search1.list_range_name));
  223. list_store = GTK_LIST_STORE(model);
  224. selection = gtk_tree_view_get_selection
  225. (GTK_TREE_VIEW(search1.list_range_name));
  226. if (!gtk_tree_selection_get_selected
  227. (selection, NULL, &selected))
  228. return;
  229. gtk_list_store_clear(store_list_ranges);
  230. entry = gtk_entry_get_text(GTK_ENTRY(editable));
  231. //count = start_parse_range_list(entry);
  232. tmp = backend->parse_range_list(entry);
  233. while (tmp) {
  234. buf = (gchar*)tmp->data;
  235. if (!buf)
  236. break;
  237. gtk_list_store_append(store_list_ranges, &iter);
  238. gtk_list_store_set(store_list_ranges, &iter,
  239. 0, buf, -1);
  240. g_free(buf);
  241. tmp = g_list_next(tmp);
  242. }
  243. gtk_list_store_set(list_store, &selected, 1, entry, -1);
  244. }
  245. /******************************************************************************
  246. * Name
  247. * set_search_global_option
  248. *
  249. * Synopsis
  250. * #include "main/search1.h"
  251. *
  252. * void set_search_global_option(gchar * option, gchar * choice)
  253. *
  254. * Description
  255. *
  256. *
  257. * Return value
  258. * void
  259. */
  260. static void set_search_global_option(const gchar * option, gboolean choice)
  261. {
  262. const char *on_off;
  263. SWMgr *mgr = backendSearch->get_mgr();
  264. if (choice) {
  265. on_off = "On";
  266. } else {
  267. on_off = "Off";
  268. }
  269. mgr->setGlobalOption(option, on_off);
  270. GS_print(("option = %s is %s\n",option,on_off));
  271. }
  272. /******************************************************************************
  273. * Name
  274. * save_modlist
  275. *
  276. * Synopsis
  277. * #include "gui/search_dialog.h"
  278. *
  279. * void save_modlist(GtkButton * button, gpointer user_data)
  280. *
  281. * Description
  282. * saves the custom module list
  283. *
  284. * Return value
  285. * void
  286. */
  287. void main_save_modlist(void)
  288. {
  289. gchar *text1 = NULL;
  290. gchar *text2 = NULL;
  291. GtkTreeModel *model;
  292. //GtkListStore *list_store;
  293. GtkTreeIter iter;
  294. model = gtk_tree_view_get_model(GTK_TREE_VIEW(search1.module_lists));
  295. //list_store = GTK_LIST_STORE(model);
  296. if (!gtk_tree_model_get_iter_first(model, &iter))
  297. return;
  298. do {
  299. gtk_tree_model_get(model, &iter,
  300. 0, &text1, 1, &text2, -1);
  301. xml_set_list_item("modlists", "modlist", text1, text2);
  302. GS_warning(("%s",text2));
  303. g_free(text1);
  304. g_free(text2);
  305. } while (gtk_tree_model_iter_next(model, &iter));
  306. add_modlist();
  307. }
  308. /******************************************************************************
  309. * Name
  310. * save_range
  311. *
  312. * Synopsis
  313. * #include "gui/search_dialog.h"
  314. *
  315. * void save_range(GtkButton * button, gpointer user_data)
  316. *
  317. * Description
  318. * saves the custom range list
  319. *
  320. * Return value
  321. * void
  322. */
  323. void main_save_range(void)
  324. {
  325. gchar *text1 = NULL;
  326. gchar *text2 = NULL;
  327. GtkTreeModel *model;
  328. //GtkListStore *list_store;
  329. GtkTreeIter iter;
  330. model =
  331. gtk_tree_view_get_model(GTK_TREE_VIEW
  332. (search1.list_range_name));
  333. //list_store = GTK_LIST_STORE(model);
  334. if (!gtk_tree_model_get_iter_first(model, &iter))
  335. return;
  336. do {
  337. gtk_tree_model_get(model, &iter,
  338. 0, &text1, 1, &text2, -1);
  339. xml_set_list_item("ranges", "range", text1, text2);
  340. GS_warning(("%s",text2));
  341. g_free(text1);
  342. g_free(text2);
  343. } while (gtk_tree_model_iter_next(model, &iter));
  344. add_ranges();
  345. }
  346. /******************************************************************************
  347. * Name
  348. * delete_range
  349. *
  350. * Synopsis
  351. * #include "gui/search_dialog.h"
  352. *
  353. * void delete_range(GtkButton * button, gpointer user_data)
  354. *
  355. * Description
  356. * delete the selected custom range
  357. *
  358. * Return value
  359. * void
  360. */
  361. void main_delete_range(void)
  362. {
  363. gchar *name_string = NULL;
  364. GtkTreeModel *model;
  365. GtkListStore *list_store;
  366. GtkTreeSelection *selection;
  367. GtkTreeIter selected;
  368. gchar *str;
  369. model =
  370. gtk_tree_view_get_model(GTK_TREE_VIEW
  371. (search1.list_range_name));
  372. list_store = GTK_LIST_STORE(model);
  373. selection = gtk_tree_view_get_selection
  374. (GTK_TREE_VIEW(search1.list_range_name));
  375. if (!gtk_tree_selection_get_selected
  376. (selection, NULL, &selected))
  377. return;
  378. gtk_tree_model_get(model, &selected, 0, &name_string, -1);
  379. str = g_strdup_printf("<span weight=\"bold\">%s</span>\n\n%s %s",
  380. _("Delete Range?"),
  381. _("Are you sure you want to delete this range?"),
  382. name_string);
  383. if (gui_yes_no_dialog(str, (char *)GTK_STOCK_DIALOG_WARNING)) {
  384. gtk_list_store_remove(list_store, &selected);
  385. xml_remove_node("ranges", "range", name_string);
  386. --search1.list_rows;
  387. main_save_range();
  388. }
  389. g_free(name_string);
  390. g_free(str);
  391. }
  392. /******************************************************************************
  393. * Name
  394. * add_module_finds
  395. *
  396. * Synopsis
  397. * #include "gui/search_dialog.h"
  398. *
  399. * void
  400. *
  401. * Description
  402. *
  403. *
  404. * Return value
  405. * void
  406. */
  407. static void add_module_finds(GList * versekeys)
  408. {
  409. gchar *buf;
  410. GtkTreeModel *model;
  411. GtkListStore *list_store;
  412. GtkTreeIter iter;
  413. GList *tmp = g_list_first(versekeys);
  414. model =
  415. gtk_tree_view_get_model(GTK_TREE_VIEW
  416. (search1.listview_verses));
  417. list_store = GTK_LIST_STORE(model);
  418. gtk_list_store_clear(list_store);
  419. while (tmp) {
  420. buf = (char*) tmp->data;
  421. gtk_list_store_append(list_store, &iter);
  422. gtk_list_store_set(list_store,
  423. &iter,
  424. 0,buf,
  425. -1);
  426. tmp = g_list_next(tmp);
  427. }
  428. }
  429. /******************************************************************************
  430. * Name
  431. * add_ranges
  432. *
  433. * Synopsis
  434. * #include "gui/search_dialog.h"
  435. *
  436. * void add_ranges(void)
  437. *
  438. * Description
  439. * add ranges to clist_range
  440. *
  441. * Return value
  442. * void
  443. */
  444. static void add_ranges(void)
  445. {
  446. gchar *buf[2];
  447. GtkTreeModel *model;
  448. GtkListStore *list_store;
  449. GtkTreeIter iter;
  450. model =
  451. gtk_tree_view_get_model(GTK_TREE_VIEW
  452. (search1.list_range_name));
  453. list_store = GTK_LIST_STORE(model);
  454. gtk_list_store_clear(list_store);
  455. if (xml_set_section_ptr("ranges")) {
  456. if (xml_get_label()) {
  457. buf[0] = xml_get_label();
  458. buf[1] = xml_get_list();
  459. gtk_list_store_append(list_store, &iter);
  460. gtk_list_store_set(list_store,
  461. &iter,
  462. 0, buf[0],
  463. 1, buf[1],
  464. -1);
  465. g_free(buf[0]);
  466. g_free(buf[1]);
  467. }
  468. gui_clear_combo(search1.combo_range);
  469. while (xml_next_item()) {
  470. if (xml_get_label()) {
  471. buf[0] = xml_get_label();
  472. buf[1] = xml_get_list();
  473. gtk_list_store_append(list_store, &iter);
  474. gtk_list_store_set(list_store,
  475. &iter,
  476. 0, buf[0],
  477. 1, buf[1],
  478. -1);
  479. gui_add_item_to_combo(search1.combo_range,
  480. buf[0]);
  481. g_free(buf[0]);
  482. g_free(buf[1]);
  483. }
  484. }
  485. gui_set_combo_index(search1.combo_range,0);
  486. }
  487. }
  488. /******************************************************************************
  489. * Name
  490. * add_modlist
  491. *
  492. * Synopsis
  493. * #include "gui/search_dialog.h"
  494. *
  495. * void add_modlist(void)
  496. *
  497. * Description
  498. * add custom module lists at search dialog start and afer save
  499. *
  500. * Return value
  501. * void
  502. */
  503. static void add_modlist(void)
  504. {
  505. gchar *buf[2];
  506. GtkTreeModel *model;
  507. GtkListStore *list_store;
  508. GtkTreeIter iter;
  509. model = gtk_tree_view_get_model(GTK_TREE_VIEW(search1.module_lists));
  510. list_store = GTK_LIST_STORE(model);
  511. gtk_list_store_clear(list_store);
  512. if (xml_set_section_ptr("modlists")) {
  513. if (xml_get_label()) {
  514. buf[0] = xml_get_label();
  515. buf[1] = xml_get_list();
  516. gtk_list_store_append(list_store, &iter);
  517. gtk_list_store_set(list_store,
  518. &iter,
  519. 0, buf[0],
  520. 1, buf[1],
  521. -1);
  522. g_free(buf[0]);
  523. g_free(buf[1]);
  524. }
  525. gui_clear_combo(search1.combo_list);
  526. while (xml_next_item()) {
  527. if (xml_get_label()) {
  528. buf[0] = xml_get_label();
  529. buf[1] = xml_get_list();
  530. gtk_list_store_append(list_store, &iter);
  531. gtk_list_store_set(list_store,
  532. &iter,
  533. 0, buf[0],
  534. 1, buf[1],
  535. -1);
  536. gui_add_item_to_combo(search1.combo_list,
  537. buf[0]);
  538. g_free(buf[0]);
  539. g_free(buf[1]);
  540. }
  541. }
  542. gui_set_combo_index(search1.combo_list,0);
  543. }
  544. }
  545. /******************************************************************************
  546. * Name
  547. * change_mods_select_label
  548. *
  549. * Synopsis
  550. * #include "gui/search_dialog.h"
  551. *
  552. * void change_mods_select_label(char *mod_name)
  553. *
  554. * Description
  555. * change module name to current search module name
  556. * or list name if searching a list of modules
  557. *
  558. * Return value
  559. * void
  560. */
  561. void main_change_mods_select_label(char *mod_name)
  562. {
  563. gchar *str;
  564. if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(search1.rb_current_module))) {
  565. str = g_strdup_printf("<b>%s</b>%s",Q_("Search: "),mod_name);
  566. gtk_label_set_markup(GTK_LABEL(search1.label_mod_select), str);
  567. g_free(str);
  568. } else
  569. main_add_modlist_to_label();
  570. }
  571. /******************************************************************************
  572. * Name
  573. *
  574. *
  575. * Synopsis
  576. * #include "gui/search_dialog.h"
  577. *
  578. *
  579. *
  580. * Description
  581. *
  582. *
  583. * Return value
  584. * void
  585. */
  586. void main_delete_module(GtkTreeView *treeview)
  587. {
  588. GList *mods = NULL;
  589. gchar *mod_list;
  590. GtkTreeModel *model;
  591. GtkListStore *list_store;
  592. GtkTreeSelection *selection;
  593. GtkTreeIter selected;
  594. gchar *str;
  595. model =
  596. gtk_tree_view_get_model(GTK_TREE_VIEW(treeview));
  597. list_store = GTK_LIST_STORE(model);
  598. selection = gtk_tree_view_get_selection
  599. (GTK_TREE_VIEW(treeview));
  600. if (!gtk_tree_selection_get_selected
  601. (selection, NULL, &selected))
  602. return;
  603. str = g_strdup_printf("<span weight=\"bold\">%s</span>\n\n%s",
  604. _("Remove Module?"),
  605. _("Are you sure you want to remove the selected module?"));
  606. if (gui_yes_no_dialog(str, (char *)GTK_STOCK_DIALOG_WARNING)) {
  607. gtk_list_store_remove(list_store, &selected);
  608. mods = get_current_list(treeview);
  609. mod_list = get_modlist_string(mods);
  610. selection = gtk_tree_view_get_selection
  611. (GTK_TREE_VIEW(search1.module_lists));
  612. model =
  613. gtk_tree_view_get_model(GTK_TREE_VIEW(search1.module_lists));
  614. list_store = GTK_LIST_STORE(model);
  615. if (gtk_tree_selection_get_selected(selection, NULL, &selected))
  616. if (mod_list) {
  617. gtk_list_store_set(list_store, &selected, 1,
  618. mod_list, -1);
  619. g_free(mod_list);
  620. }
  621. }
  622. g_free(str);
  623. }
  624. void main_add_mod_to_list(GtkWidget * tree_widget, gchar * mod_name)
  625. {
  626. GtkTreeModel *model_mods;
  627. GtkTreeModel *model_modules_lists;
  628. GtkTreeIter iter;
  629. GtkTreeIter selected_modules_lists;
  630. GtkListStore *list_store;
  631. GtkListStore *store_modules_lists;
  632. gchar *mod_description = NULL;
  633. gchar *mod_list = NULL;
  634. GList *mods = NULL;
  635. GtkTreeSelection *selection_modules_lists;
  636. model_modules_lists = gtk_tree_view_get_model(GTK_TREE_VIEW(search1.module_lists));
  637. store_modules_lists = GTK_LIST_STORE(model_modules_lists);
  638. selection_modules_lists = gtk_tree_view_get_selection
  639. (GTK_TREE_VIEW(search1.module_lists));
  640. model_mods = gtk_tree_view_get_model(GTK_TREE_VIEW(tree_widget));
  641. list_store = GTK_LIST_STORE(model_mods);
  642. mod_description = backendSearch->module_description(mod_name);
  643. gtk_list_store_append(list_store, &iter);
  644. gtk_list_store_set(list_store, &iter,
  645. 0, mod_description,
  646. 1, mod_name, -1);
  647. mods = get_current_list(GTK_TREE_VIEW(search1.listview_modules));
  648. mod_list = get_modlist_string(mods);
  649. if (mod_list) {
  650. gtk_tree_selection_get_selected
  651. (selection_modules_lists, NULL,
  652. &selected_modules_lists);
  653. gtk_list_store_set(store_modules_lists,
  654. &selected_modules_lists,
  655. 1, mod_list, -1);
  656. g_free(mod_list);
  657. }
  658. ++search1.module_count;
  659. }
  660. /******************************************************************************
  661. * Name
  662. * mod_selection_changed
  663. *
  664. * Synopsis
  665. * #include "gui/search_dialog.h"
  666. *
  667. * void mod_selection_changed(GtkTreeSelection * selection,
  668. * GtkWidget * tree_widget)
  669. *
  670. * Description
  671. *
  672. *
  673. * Return value
  674. * void
  675. */
  676. void main_mod_selection_changed(GtkTreeSelection * selection,
  677. GtkWidget * tree_widget)
  678. {
  679. gchar *mod = NULL;
  680. gchar *mod_description = NULL;
  681. gchar *mod_list = NULL;
  682. GList *mods = NULL;
  683. GtkListStore *store_modules_lists;
  684. GtkListStore *list_store;
  685. GtkTreeSelection *selection_modules_lists;
  686. GtkTreeIter selected_modules_lists;
  687. GtkTreeIter selected;
  688. GtkTreeIter iter;
  689. GtkTreeModel *model_mods;
  690. GtkTreeModel *model_modules_lists;
  691. GtkTreeModel *model =
  692. gtk_tree_view_get_model(GTK_TREE_VIEW(tree_widget));
  693. if (!gtk_tree_selection_get_selected(selection, NULL, &selected))
  694. return;
  695. model_mods =
  696. gtk_tree_view_get_model(GTK_TREE_VIEW
  697. (search1.listview_modules));
  698. list_store = GTK_LIST_STORE(model_mods);
  699. model_modules_lists =
  700. gtk_tree_view_get_model(GTK_TREE_VIEW(search1.module_lists));
  701. store_modules_lists = GTK_LIST_STORE(model_modules_lists);
  702. selection_modules_lists = gtk_tree_view_get_selection
  703. (GTK_TREE_VIEW(search1.module_lists));
  704. if (gtk_tree_model_iter_has_child(model, &selected))
  705. return;
  706. gtk_tree_model_get(model, &selected, UTIL_COL_MODULE, &mod, -1);
  707. if (mod) {
  708. mod_description =
  709. backendSearch->module_description(mod);
  710. if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(search1.rb_current_module))) {
  711. search1.search_mod = g_strdup(mod);
  712. search1.module_count = 1;
  713. } else {
  714. gtk_list_store_append(list_store, &iter);
  715. gtk_list_store_set(list_store, &iter,
  716. 0, mod_description,
  717. 1, mod, -1);
  718. mods = get_current_list(GTK_TREE_VIEW(search1.listview_modules));
  719. mod_list = get_modlist_string(mods);
  720. if (mod_list) {
  721. gtk_tree_selection_get_selected
  722. (selection_modules_lists, NULL,
  723. &selected_modules_lists);
  724. gtk_list_store_set(store_modules_lists,
  725. &selected_modules_lists,
  726. 1, mod_list, -1);
  727. g_free(mod_list);
  728. }
  729. ++search1.module_count;
  730. }
  731. main_change_mods_select_label(mod);
  732. g_free(mod);
  733. }
  734. }
  735. /******************************************************************************
  736. * Name
  737. * main_selection_finds_list_changed
  738. *
  739. * Synopsis
  740. * #include "gui/search_dialog.h"
  741. *
  742. * void main_selection_finds_list_changed(GtkTreeSelection * selection,
  743. * gpointer data)
  744. *
  745. * Description
  746. *
  747. *
  748. * Return value
  749. * void
  750. */
  751. void main_selection_finds_list_changed(GtkTreeSelection *
  752. selection, gpointer data)
  753. {
  754. gchar *text, *path_str;
  755. GList *tmp = NULL;
  756. GtkTreeModel *model;
  757. GtkTreeIter selected;
  758. GtkTreePath *path;
  759. if (!gtk_tree_selection_get_selected (selection,&model,&selected))
  760. return;
  761. gtk_tree_model_get(model, &selected, 0, &text, -1);
  762. path = gtk_tree_model_get_path(model,&selected);
  763. path_str = gtk_tree_path_to_string(path);
  764. GS_message(("\npath: %s\ntext: %s",path_str,text));
  765. tmp = g_list_nth(list_of_finds,atoi(path_str));
  766. tmp = (GList*)tmp->data;
  767. add_module_finds(tmp);
  768. if (text)
  769. g_free(text);
  770. if (path_str)
  771. g_free(path_str);
  772. gtk_tree_path_free(path);
  773. }
  774. /******************************************************************************
  775. * Name
  776. * main_finds_verselist_selection_changed
  777. *
  778. * Synopsis
  779. * #include "gui/search_dialog.h"
  780. *
  781. * void main_finds_verselist_selection_changed(GtkTreeSelection * selection,
  782. * gpointer data)
  783. *
  784. * Description
  785. *
  786. *
  787. * Return value
  788. * void
  789. */
  790. void main_finds_verselist_selection_changed(GtkTreeSelection * selection,
  791. GtkTreeModel * model,
  792. gboolean is_double_click)
  793. {
  794. gchar *text, *buf, *module, *key;
  795. GString *text_str;
  796. //gint textlen;
  797. //GtkTreeModel *model;
  798. GtkTreeIter selected;
  799. if (!gtk_tree_selection_get_selected (selection, &model, &selected))
  800. return;
  801. gtk_tree_model_get(model, &selected, 0, &text, -1);
  802. GS_message(("\ntext: %s", text));
  803. //textlen = strlen(text);
  804. module = text;
  805. // first `:' finds end of module name.
  806. buf = strchr(text, ':');
  807. *(module+(buf-text)) = '\0'; // strncpy unreliably terminates?
  808. // key begins 2 chars after module.
  809. key = buf + 2;
  810. if (verse_selected)
  811. g_free(verse_selected);
  812. const gchar *temp_key = main_url_encode(key);
  813. verse_selected = g_strdup_printf("sword://%s/%s", module, temp_key);
  814. if (is_double_click)
  815. main_url_handler(verse_selected, TRUE);
  816. g_free((gchar *)temp_key);
  817. text_str = g_string_new(backendSearch->get_render_text(module,key));
  818. mark_search_words(text_str);
  819. #ifdef USE_XIPHOS_HTML
  820. GString *html_text = g_string_new("");
  821. MOD_FONT *mf = get_font(module);
  822. g_string_printf(html_text,
  823. HTML_START
  824. "<body text=\"%s\" bgcolor=\"%s\" link=\"%s\">"
  825. "<font face=\"%s\" size=\"%+d\">",
  826. settings.bible_text_color, settings.bible_bg_color,
  827. settings.link_color,
  828. ((mf->old_font) ? mf->old_font : ""),
  829. mf->old_font_size_value);
  830. free_font(mf);
  831. g_string_append(html_text, text_str->str);
  832. g_string_append(html_text, "</font></body></html>");
  833. XIPHOS_HTML_OPEN_STREAM(search1.preview_html, "text/html");
  834. XIPHOS_HTML_WRITE(search1.preview_html,
  835. html_text->str, html_text->len);
  836. XIPHOS_HTML_CLOSE(search1.preview_html);
  837. g_string_free(html_text, TRUE);
  838. #else
  839. gtk_html_load_from_string(GTK_HTML(search1.preview_html),
  840. text_str->str, text_str->len);
  841. #endif
  842. GS_message(("main_finds_verselist_selection_changed: %s %s", module, key));
  843. if (text)
  844. g_free(text);
  845. g_string_free(text_str, TRUE);
  846. }
  847. /******************************************************************************
  848. * Name
  849. *
  850. *
  851. * Synopsis
  852. * #include "gui/search_dialog.h"
  853. *
  854. * void (GtkTreeSelection * selection,
  855. * gpointer data)
  856. *
  857. * Description
  858. *
  859. *
  860. * Return value
  861. * void
  862. */
  863. void main_selection_modules_lists_changed(GtkTreeSelection * selection,
  864. gpointer data)
  865. {
  866. gchar *name, *modules;
  867. GList *tmp = NULL, *tmp2;
  868. GtkTreeModel *model;
  869. GtkTreeIter iter;
  870. GtkListStore *list_store;
  871. GtkTreeIter selected;
  872. if (!gtk_tree_selection_get_selected
  873. (selection, NULL, &selected))
  874. return;
  875. model =
  876. gtk_tree_view_get_model(GTK_TREE_VIEW(search1.module_lists));
  877. gtk_tree_model_get(model, &selected, 0, &name, 1, &modules, -1);
  878. model =
  879. gtk_tree_view_get_model(GTK_TREE_VIEW
  880. (search1.listview_modules));
  881. list_store = GTK_LIST_STORE(model);
  882. gtk_entry_set_text(GTK_ENTRY(search1.entry_list_name), name);
  883. gtk_list_store_clear(list_store);
  884. tmp =
  885. get_custom_list_from_name(gtk_entry_get_text
  886. (GTK_ENTRY
  887. (search1.entry_list_name)));
  888. tmp = tmp2 = g_list_first(tmp);
  889. while (tmp != NULL) {
  890. gtk_list_store_append(list_store, &iter);
  891. gtk_list_store_set(list_store, &iter,
  892. 0,
  893. backendSearch->module_description((gchar *)
  894. tmp->data), 1,
  895. (gchar *) tmp->data, -1);
  896. g_free((gchar *) tmp->data);
  897. tmp = g_list_next(tmp);
  898. }
  899. g_list_free(tmp2);
  900. if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(search1.rb_current_module)))
  901. main_add_modlist_to_label();
  902. g_free(name);
  903. g_free(modules);
  904. }
  905. /******************************************************************************
  906. * Name
  907. * add_modlist_to_label
  908. *
  909. * Synopsis
  910. * #include "gui/search_dialog.h"
  911. *
  912. * void add_modlist_to_label(void)
  913. *
  914. * Description
  915. *
  916. *
  917. * Return value
  918. * void
  919. */
  920. void main_add_modlist_to_label(void)
  921. {
  922. GList *mods = NULL;
  923. gchar *mod_list, *str;
  924. mods = get_current_list(GTK_TREE_VIEW(search1.listview_modules));
  925. mod_list = get_modlist_string(mods);
  926. if (strlen(mod_list) > 60)
  927. str = g_strdup_printf("<b>%s</b>%60.60s...",
  928. Q_("Search: "), mod_list);
  929. else
  930. str = g_strdup_printf("<b>%s</b>%s",
  931. Q_("Search: "), mod_list);
  932. gtk_label_set_markup(GTK_LABEL(search1.label_mod_select), str);
  933. g_free(mod_list);
  934. g_free(str);
  935. }
  936. void main_comboboxentry2_changed(GtkComboBox * combobox, gpointer user_data)
  937. {
  938. GList *mod_list = NULL;
  939. gchar *str = NULL;
  940. gchar *mod_list_str = NULL;
  941. const gchar *name = NULL;
  942. if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(search1.rb_custom_list)))
  943. return;
  944. name = gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(combobox))));
  945. mod_list = get_custom_list_from_name(name);
  946. mod_list_str = get_modlist_string(mod_list);
  947. if (strlen(mod_list_str) > 60)
  948. str = g_strdup_printf("<b>%s</b>%60.60s...",
  949. Q_("Search: "), mod_list_str);
  950. else
  951. str = g_strdup_printf("<b>%s</b>%s",
  952. Q_("Search: "), mod_list_str);
  953. gtk_label_set_markup(GTK_LABEL(search1.label_mod_select), str);
  954. g_free(mod_list_str);
  955. g_free(str);
  956. }
  957. /******************************************************************************
  958. * Name
  959. *
  960. *
  961. * Synopsis
  962. * #include "gui/search_dialog.h"
  963. *
  964. *
  965. *
  966. * Description
  967. *
  968. *
  969. * Return value
  970. * void
  971. */
  972. static void check_search_global_options(void)
  973. {
  974. set_search_global_option("Strong's Numbers",
  975. gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(search1.
  976. cb_include_strongs)));
  977. set_search_global_option("Morphological Tags",
  978. gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(search1.
  979. cb_include_morphs)));
  980. set_search_global_option("Footnotes",
  981. gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(search1.
  982. cb_include_footnotes)));
  983. }
  984. /******************************************************************************
  985. * Name
  986. * get_current_search_mod
  987. *
  988. * Synopsis
  989. * #include "gui/search_dialog.h"
  990. *
  991. * GList *get_current_search_mod(void)
  992. *
  993. * Description
  994. *
  995. *
  996. * Return value
  997. * GList *
  998. */
  999. static GList *get_current_search_mod(void)
  1000. {
  1001. GList *items = NULL;
  1002. items =
  1003. g_list_append(items, (gchar *) g_strdup(search1.search_mod));
  1004. return items;
  1005. }
  1006. /******************************************************************************
  1007. * Name
  1008. * get_custom_list_from_name
  1009. *
  1010. * Synopsis
  1011. * #include "gui/search_dialog.h"
  1012. *
  1013. * gchar *get_custom_list_from_name(gchar * name)
  1014. *
  1015. * Description
  1016. * used by setup_search() - returns the search range (scope)
  1017. *
  1018. * Return value
  1019. * gchar *
  1020. */
  1021. static GList *get_custom_list_from_name(const gchar * label)
  1022. {
  1023. GList *items = NULL;
  1024. gchar *mod_list = NULL;
  1025. const gchar *t;
  1026. gchar *token;
  1027. search1.module_count = 0;
  1028. t = ",";
  1029. mod_list =
  1030. (gchar *) xml_get_list_from_label("modlists", "modlist",
  1031. label);
  1032. token = strtok(mod_list, t);
  1033. ++search1.module_count;
  1034. while (token != NULL) {
  1035. ++search1.module_count;
  1036. items = g_list_append(items, (gchar *)
  1037. g_strdup(token));
  1038. token = strtok(NULL, t);
  1039. }
  1040. return items;
  1041. }
  1042. /******************************************************************************
  1043. * Name
  1044. * set_up_search
  1045. *
  1046. * Synopsis
  1047. * #include "gui/search_dialog.h"
  1048. *
  1049. * void set_up_search(void)
  1050. *
  1051. * Description
  1052. * checks for and setups some of the search options
  1053. *
  1054. * Return value
  1055. * void
  1056. */
  1057. static void set_up_dialog_search(GList *modlist)
  1058. {
  1059. const gchar *label;
  1060. gchar *range = NULL;
  1061. //gui_begin_html(search1.results_html, TRUE);
  1062. backendSearch->clear_scope();
  1063. if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(search1.rb_custom_range))) {
  1064. // if any non-bible, non-commentary modules are in use,
  1065. // we must not respect this "custom range" selector.
  1066. gboolean range_ok = TRUE;
  1067. while (modlist) {
  1068. int mod_type = backend->module_type((char*)modlist->data);
  1069. if ((mod_type != TEXT_TYPE) &&
  1070. (mod_type != COMMENTARY_TYPE)) {
  1071. range_ok = FALSE;
  1072. break;
  1073. }
  1074. modlist = g_list_next(modlist);
  1075. }
  1076. if (range_ok) {
  1077. backendSearch->clear_search_list();
  1078. label =
  1079. gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child (GTK_BIN(search1.combo_range))));
  1080. range =
  1081. (gchar *) xml_get_list_from_label("ranges", "range",
  1082. label);
  1083. if (range) {
  1084. backendSearch->set_range(range);
  1085. backendSearch->set_scope2range();
  1086. }
  1087. }
  1088. }
  1089. else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(search1.rb_last))) {
  1090. backendSearch->set_scope2last_search();
  1091. }
  1092. else {
  1093. backendSearch->clear_search_list();
  1094. }
  1095. }
  1096. /******************************************************************************
  1097. * Name
  1098. * main_get_rendered_text
  1099. *
  1100. * Synopsis
  1101. * #include "main/sword.h"
  1102. *
  1103. * char *main_get_rendered_text(char *module_name, char *key)
  1104. *
  1105. * Description
  1106. *
  1107. *
  1108. * Return value
  1109. * char *
  1110. */
  1111. char *main_get_search_rendered_text(char *module_name, char *key)
  1112. {
  1113. check_search_global_options();
  1114. return backendSearch->get_render_text(module_name, key);
  1115. }
  1116. static
  1117. void _clear_find_lists(void)
  1118. {
  1119. GList *tmp, *base;
  1120. gchar *tmp_buf;
  1121. base = list_of_finds = g_list_first(list_of_finds);
  1122. while (list_of_finds) {
  1123. tmp = (GList*) list_of_finds->data;
  1124. while (tmp) {
  1125. tmp_buf = (char*) tmp->data;
  1126. GS_message(("%s",tmp_buf));
  1127. if (tmp_buf) g_free(tmp_buf);
  1128. tmp = g_list_next(tmp);
  1129. }
  1130. if (list_of_finds->data)
  1131. g_list_free((GList*)list_of_finds->data);
  1132. list_of_finds = g_list_next(list_of_finds);
  1133. }
  1134. if (base)
  1135. g_list_free(base);
  1136. list_of_finds = NULL;
  1137. }
  1138. static
  1139. void _clear_bookmarking_lists(void)
  1140. {
  1141. GList *tmp = NULL;
  1142. RESULTS *results;
  1143. list_for_bookmarking = g_list_first(list_for_bookmarking);
  1144. while (list_for_bookmarking) {
  1145. tmp = (GList*) list_for_bookmarking->data;
  1146. while (tmp) {
  1147. results = (RESULTS*) tmp->data;
  1148. GS_message(("%s://%s",results->module,results->key));
  1149. if (results->module) g_free(results->module);
  1150. if (results->key) g_free(results->key);
  1151. if (results) g_free (results);
  1152. tmp = g_list_next(tmp);
  1153. }
  1154. list_for_bookmarking = g_list_next(list_for_bookmarking);
  1155. }
  1156. if (list_for_bookmarking)
  1157. g_list_free(list_for_bookmarking);
  1158. list_for_bookmarking = NULL;
  1159. }
  1160. void main_do_dialog_search(void)
  1161. {
  1162. gint search_type, search_params, finds;
  1163. const gchar *search_string;
  1164. const gchar *attribute_search_string = NULL;
  1165. gchar *module;
  1166. gchar buf[256];
  1167. GList *search_mods = NULL;
  1168. const gchar *key_buf;
  1169. GString *str;
  1170. GList *tmp = NULL;
  1171. GList *tmp_list = NULL;
  1172. GList *tmp_bookmark_list = NULL;
  1173. SWBuf swbuf = "";
  1174. GtkTreeModel *model;
  1175. GtkListStore *list_store;
  1176. GtkTreeIter iter;
  1177. GtkTreeModel *model2;
  1178. GtkListStore *list_store2;
  1179. gint x = 0;
  1180. gint mod_type;
  1181. char *num;
  1182. gchar msg[300];
  1183. RESULTS *results;
  1184. _clear_find_lists();
  1185. _clear_bookmarking_lists();
  1186. model =
  1187. gtk_tree_view_get_model(GTK_TREE_VIEW
  1188. (search1.listview_results));
  1189. list_store = GTK_LIST_STORE(model);
  1190. gtk_list_store_clear(list_store);
  1191. model2 =
  1192. gtk_tree_view_get_model(GTK_TREE_VIEW
  1193. (search1.listview_verses));
  1194. list_store2 = GTK_LIST_STORE(model2);
  1195. gtk_list_store_clear(list_store2);
  1196. search_string =
  1197. gtk_entry_get_text(GTK_ENTRY(search1.search_entry));
  1198. if (strlen(search_string) < 1)
  1199. return;
  1200. str = g_string_new("");
  1201. gtk_notebook_set_current_page(GTK_NOTEBOOK(search1.notebook), 1);
  1202. search_type =
  1203. (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(search1.rb_regexp))
  1204. ? 0
  1205. : (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(search1.rb_exact_phrase))
  1206. ? -1
  1207. : (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(search1.rb_words))
  1208. ? -2
  1209. : (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(search1.rb_optimized))
  1210. ? -4
  1211. : -3 /* fallthrough to attribute */ ))));
  1212. GS_message(("search_type = %d", search_type));
  1213. search_params =
  1214. gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(search1.cb_case_sensitive)) ? 0 : REG_ICASE;
  1215. // For attribute-based searches, e.g. "Word//Lemma/G140",
  1216. // we must constrain the match to whole words. Otherwise,
  1217. // we will inadvertently return e.g. 140 plus 1401 and 1404.
  1218. if (search_type == -3) {
  1219. if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(search1.rb_strongs))) {
  1220. search_params |= SEARCHFLAG_MATCHWHOLEENTRY;
  1221. attribute_search_string = g_strdup_printf(
  1222. "Word//Lemma./%s",
  1223. search_string);
  1224. } else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(search1.rb_morphs))) {
  1225. search_params |= SEARCHFLAG_MATCHWHOLEENTRY;
  1226. attribute_search_string = g_strdup_printf(
  1227. "Word//Morph/%s",
  1228. search_string);
  1229. } else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(search1.rb_footnotes))) {
  1230. attribute_search_string = g_strdup_printf(
  1231. "Footnote//body/%s",
  1232. search_string);
  1233. }
  1234. GS_message(("%s",attribute_search_string));
  1235. }
  1236. if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(search1.rb_custom_list))) {
  1237. const gchar *name;
  1238. name =
  1239. gtk_entry_get_text(GTK_ENTRY(
  1240. gtk_bin_get_child (GTK_BIN(search1.combo_list))));
  1241. search_mods = get_custom_list_from_name(name);
  1242. } else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(search1.rb_mod_list))) {
  1243. search_mods = get_current_list(GTK_TREE_VIEW(search1.listview_modules));
  1244. } else
  1245. search_mods = get_current_search_mod();
  1246. search_mods = g_list_first(search_mods);
  1247. set_up_dialog_search(search_mods);
  1248. snprintf(settings.searchText, 255, "%s", search_string);
  1249. settings.searchType = search_type;
  1250. check_search_global_options();
  1251. terminate_search = FALSE;
  1252. search_active = TRUE;
  1253. // must ensure that no accents or vowel points are enabled.
  1254. SWMgr *mgr = backendSearch->get_mgr();
  1255. mgr->setGlobalOption("Greek Accents", "Off");
  1256. mgr->setGlobalOption("Hebrew Vowel Points", "Off");
  1257. mgr->setGlobalOption("Arabic Vowel Points", "Off");
  1258. while (search_mods != NULL) {
  1259. module = (gchar *) search_mods->data;
  1260. if (terminate_search) {
  1261. // we simply wrap through the remaining
  1262. // set so as to free memory in use.
  1263. goto clean;
  1264. }
  1265. if (!main_is_module(module)) {
  1266. sprintf(msg, _("%s:\nNo such module is installed.\n%s"),
  1267. module,
  1268. _("Please adjust the module list."));
  1269. gui_generic_warning(msg);
  1270. goto clean;
  1271. }
  1272. sprintf(buf, "%s %s %s", SEARCHING, module, SMODULE);
  1273. gui_set_progressbar_text(search1.progressbar, buf);
  1274. // reset search type each time through, because
  1275. // it might have gotten downgraded last time.
  1276. search_type = settings.searchType;
  1277. if (search_type == -4) {
  1278. search_type = backendSearch->check_for_optimal_search(module);
  1279. if (search_type == -2) {
  1280. sprintf(msg, _("No fast-search index exists for %s.%s%s"),
  1281. module,
  1282. _("\nSearch on this module is now `multi word'."),
  1283. _("\nSee the Module Manager, Maintenance pane."));
  1284. gui_generic_warning(msg);
  1285. }
  1286. }
  1287. GS_message(("search_type = %d",search_type));
  1288. finds = backendSearch->do_module_search(module,
  1289. (attribute_search_string
  1290. ? mgr->getModule(module)->
  1291. StripText(attribute_search_string)
  1292. : mgr->getModule(module)->
  1293. StripText(search_string)),
  1294. search_type,
  1295. search_params,
  1296. TRUE);
  1297. tmp_list = g_list_first(tmp_list);
  1298. tmp_list = NULL;
  1299. tmp_bookmark_list = g_list_first(tmp_bookmark_list);
  1300. tmp_bookmark_list = NULL;
  1301. mod_type = backendSearch->module_type(module);
  1302. while ((key_buf = backendSearch->get_next_listkey()) != NULL) {
  1303. if (mod_type == TEXT_TYPE)
  1304. g_string_printf(str, "%s: %s %s", module, key_buf, backendSearch->get_strip_text(module, key_buf));
  1305. else
  1306. g_string_printf(str, "%s: %s", module, key_buf);
  1307. tmp_list = g_list_append(tmp_list, (char*) g_strdup(str->str));
  1308. results = g_new(RESULTS,1);
  1309. results->module = g_strdup(module);
  1310. results->key = g_strdup(key_buf);
  1311. tmp_bookmark_list = g_list_append(tmp_bookmark_list,
  1312. (RESULTS*) results);
  1313. }
  1314. list_of_finds = g_list_append(list_of_finds, (GList*)tmp_list);
  1315. list_for_bookmarking = g_list_append(list_for_bookmarking, (GList*)tmp_bookmark_list);
  1316. // add number of hits in each module to finds listview
  1317. num = main_format_number(finds);
  1318. g_string_printf(str, "%s %s %s", num, FINDS, module);
  1319. g_free(num);
  1320. gtk_list_store_append(list_store, &iter);
  1321. gtk_list_store_set(list_store,
  1322. &iter,
  1323. 0, str->str,
  1324. -1);
  1325. ++x;
  1326. if (x == 1) { // add verse list for hits in first module to verse listview
  1327. tmp = (GList*) list_of_finds->data;
  1328. add_module_finds(g_list_first(tmp));
  1329. }
  1330. clean:
  1331. g_free(module);
  1332. search_mods = g_list_next(search_mods);
  1333. }
  1334. search_active = FALSE;
  1335. if (attribute_search_string)
  1336. g_free((gchar*)attribute_search_string);
  1337. g_list_free(search_mods);
  1338. gui_set_progressbar_text(search1.progressbar, _("Search finished"));
  1339. gui_set_progressbar_fraction(search1.progressbar, 0);
  1340. g_string_free(str, TRUE);
  1341. gtk_widget_grab_focus(search1.listview_verses);
  1342. }
  1343. /******************************************************************************
  1344. * Name
  1345. * main_open_search_dialog
  1346. *
  1347. * Synopsis
  1348. * #include "gui/search_dialog.h"
  1349. *
  1350. * void main_open_search_dialog(void)
  1351. *
  1352. * Description
  1353. * create and setup the search dialog
  1354. *
  1355. * Return value
  1356. * void
  1357. */
  1358. void main_open_search_dialog(void)
  1359. {
  1360. if (!is_running) {
  1361. // get rid of holdover from last time, if it exited poorly.
  1362. if (backendSearch)
  1363. delete backendSearch;
  1364. backendSearch = new BackEnd();
  1365. /* create and show search dialog */
  1366. gui_create_search_dialog();
  1367. backendSearch->init_SWORD(2);
  1368. /* initiate module count to 0 */
  1369. search1.module_count = 0;
  1370. /* add custom ranges to list_ranges */
  1371. add_ranges();
  1372. /* add custom modlist to module_list */
  1373. add_modlist();
  1374. /* set search module to current module */
  1375. search1.search_mod = settings.MainWindowModule;
  1376. main_change_mods_select_label(settings.MainWindowModule);
  1377. /* add one to module count */
  1378. ++search1.module_count;
  1379. is_running = TRUE;
  1380. } else
  1381. gdk_window_raise(GDK_WINDOW(search1.dialog));
  1382. search_dialog = TRUE;
  1383. }
  1384. void main_close_search_dialog(void)
  1385. {
  1386. _clear_find_lists();
  1387. _clear_bookmarking_lists();
  1388. is_running = FALSE;
  1389. delete backendSearch;
  1390. backendSearch = NULL;
  1391. }
  1392. /******************************************************************************
  1393. * Name
  1394. * search_percent_update
  1395. *
  1396. * Synopsis
  1397. * #include "main/search.h"
  1398. *
  1399. * void search_percent_update(char percent, void *userData)
  1400. *
  1401. * Description
  1402. * updates the progress bar during shortcut bar search
  1403. *
  1404. * Return value
  1405. * void
  1406. */
  1407. void main_dialog_search_percent_update(char percent, void *userData)
  1408. {
  1409. char maxHashes = *((char *) userData);
  1410. float num;
  1411. static char printed = 0;
  1412. if (terminate_search) {
  1413. backendSearch->terminate_search();
  1414. // this is WAY WRONG but at least it cleans up the dying window. */
  1415. // _clear_find_lists(); why would i have ever done this here? oy.
  1416. is_running = FALSE;
  1417. } else {
  1418. /* update search dialog progress */
  1419. while ((((float) percent) / 100) * maxHashes > printed) {
  1420. num = (float) percent / 100;
  1421. gui_set_progressbar_fraction(search1.progressbar, (gdouble)num);
  1422. printed++;
  1423. }
  1424. printed = 0;
  1425. }
  1426. sync_windows();
  1427. }