PageRenderTime 46ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

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

#
C++ | 441 lines | 305 code | 61 blank | 75 comment | 41 complexity | b84b199aa55a110fbccfbb99dfa72752 MD5 | raw file
Possible License(s): GPL-2.0
  1. /*
  2. * Xiphos Bible Study Tool
  3. * search_sidebar.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 <ctype.h>
  27. #include <swmodule.h>
  28. #ifdef __cplusplus
  29. extern "C" {
  30. #endif
  31. #include <gtkhtml/gtkhtml.h>
  32. #ifdef __cplusplus
  33. }
  34. #endif
  35. #include "main/search_dialog.h"
  36. #include "main/search_sidebar.h"
  37. #include "main/settings.h"
  38. #include "main/sword.h"
  39. #include "main/xml.h"
  40. #include "gui/search_dialog.h"
  41. #include "gui/search_sidebar.h"
  42. #include "gui/sidebar.h"
  43. #include "gui/widgets.h"
  44. #include "gui/dialog.h"
  45. #include "gui/utilities.h"
  46. #include "backend/sword_main.hh"
  47. #include "gui/debug_glib_null.h"
  48. #ifdef HAVE_DBUS
  49. #include "gui/ipc.h"
  50. #endif
  51. #define SEARCHING N_("Searching the ")
  52. #define SMODULE N_(" Module")
  53. #define FINDS N_("found in ")
  54. static BackEnd *backendSearch;
  55. int search_dialog;
  56. /**********************************************************************/
  57. /****************************** sidebar search ************************/
  58. /**********************************************************************/
  59. /******************************************************************************
  60. * Name
  61. * fill_search_results_list
  62. *
  63. * Synopsis
  64. * #include "sidebar_search.h"
  65. *
  66. * void fill_search_results_list(int finds)
  67. *
  68. * Description
  69. * display a list of keys found during search
  70. *
  71. * Return value
  72. * void
  73. */
  74. static void fill_search_results_list(int finds)
  75. {
  76. gchar buf[256];
  77. gchar *tmpbuf;
  78. const gchar *key_buf = NULL;
  79. GtkTreeModel *model;
  80. GtkListStore *list_store;
  81. GtkTreeIter iter;
  82. GtkTreeSelection *selection;
  83. GtkTreePath *path;
  84. gchar *buf1 = _("matches");
  85. RESULTS *list_item;
  86. gchar *num;
  87. if (!backendSearch)
  88. main_init_sidebar_search_backend();
  89. is_search_result = TRUE;
  90. if (list_of_verses) {
  91. GList *chaser = list_of_verses;
  92. while (chaser) {
  93. list_item = (RESULTS*)chaser->data;
  94. g_free(list_item->module);
  95. g_free(list_item->key);
  96. g_free(list_item);
  97. chaser = g_list_next(chaser);
  98. }
  99. g_list_free(list_of_verses);
  100. list_of_verses = NULL;
  101. }
  102. gtk_widget_set_sensitive(sidebar.menu_item_save_search,FALSE);
  103. selection = gtk_tree_view_get_selection
  104. (GTK_TREE_VIEW(sidebar.results_list));
  105. list_store = gtk_list_store_new(1, G_TYPE_STRING);
  106. backendSearch->set_listkey_position((char) 1); /* TOP */
  107. while ((key_buf = backendSearch->get_next_listkey()) != NULL) {
  108. tmpbuf = (gchar*) key_buf;
  109. gtk_list_store_append(list_store, &iter);
  110. gtk_list_store_set(list_store, &iter, 0,
  111. tmpbuf, -1);
  112. list_item = g_new(RESULTS,1);
  113. list_item->module = g_strdup(settings.sb_search_mod);
  114. list_item->key = g_strdup(tmpbuf);
  115. list_of_verses = g_list_append(list_of_verses,
  116. (RESULTS *) list_item);
  117. }
  118. model = GTK_TREE_MODEL(list_store);
  119. gtk_tree_view_set_model (GTK_TREE_VIEW(sidebar.results_list), model);
  120. num = main_format_number(finds);
  121. sprintf(buf, "%s %s", num, buf1);
  122. g_free(num);
  123. gui_set_statusbar (buf);
  124. gtk_notebook_set_current_page(GTK_NOTEBOOK(widgets.notebook_sidebar),3);
  125. /* cleanup progress bar */
  126. gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(ss.progressbar_search),
  127. 0.0);
  128. /* display first item in list by selection row*/
  129. if (!gtk_tree_model_get_iter_first(model,&iter))
  130. return;
  131. gtk_widget_set_sensitive(sidebar.menu_item_save_search,TRUE);
  132. path = gtk_tree_model_get_path(model,&iter);
  133. gtk_tree_selection_select_path(selection,
  134. path);
  135. gtk_tree_path_free(path);
  136. gui_verselist_button_release_event(NULL,NULL,NULL);
  137. return;
  138. }
  139. #ifdef HAVE_DBUS
  140. GList* get_list_of_references()
  141. {
  142. RESULTS* list_item;
  143. GList *tmp = list_of_verses;
  144. GList *references = NULL;
  145. while (tmp) {
  146. list_item = (RESULTS*)tmp->data;
  147. references = g_list_append(references, list_item->key);
  148. tmp = g_list_next(tmp);
  149. }
  150. return g_list_first(references);
  151. }
  152. #endif
  153. /******************************************************************************
  154. * Name
  155. * main_do_sidebar_search
  156. *
  157. * Synopsis
  158. * main_do_sidebar_search(gpointer user_data)
  159. *
  160. * Description
  161. * search from sidebar
  162. *
  163. * Return value
  164. * void
  165. */
  166. void main_do_sidebar_search(gpointer user_data)
  167. {
  168. GString *new_search = g_string_new(NULL);
  169. gint search_params, finds;
  170. const char *search_string = NULL;
  171. char *search_module;
  172. if (!backendSearch)
  173. main_init_sidebar_search_backend();
  174. gtk_widget_set_sensitive(sidebar.menu_item_save_search,FALSE);
  175. search_dialog = FALSE;
  176. search_string = gtk_entry_get_text(GTK_ENTRY(ss.entrySearch));
  177. if (strlen(search_string) < 1)
  178. return;
  179. /* text -vs- commentary search selection. */
  180. if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(ss.radiobutton_search_text))) {
  181. strcpy(settings.sb_search_mod,
  182. settings.MainWindowModule);
  183. }
  184. else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(ss.radiobutton_search_comm))) {
  185. if (!settings.CommWindowModule ||
  186. (strlen(settings.CommWindowModule) == 0)) {
  187. gui_generic_warning(_("There is no commentary module."));
  188. return;
  189. }
  190. strcpy(settings.sb_search_mod,settings.CommWindowModule);
  191. }
  192. search_module = settings.sb_search_mod;
  193. backendSearch->clear_scope();
  194. if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(ss.rrbUseBounds))) {
  195. gchar *str;
  196. backendSearch->clear_search_list();
  197. str = g_strdup_printf("%s - %s",
  198. #ifdef USE_GTK_3
  199. gtk_combo_box_text_get_active_text((GtkComboBoxText*)
  200. ss.entryLower),
  201. gtk_combo_box_text_get_active_text((GtkComboBoxText*)
  202. ss.entryUpper));
  203. #else
  204. gtk_combo_box_get_active_text(GTK_COMBO_BOX
  205. (ss.entryLower)),
  206. gtk_combo_box_get_active_text(GTK_COMBO_BOX
  207. (ss.entryUpper)));
  208. #endif
  209. backendSearch->set_range(str);
  210. backendSearch->set_scope2range();
  211. g_free(str);
  212. }
  213. if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(ss.rbLastSearch)))
  214. backendSearch->set_scope2last_search();
  215. snprintf(settings.searchText, 255, "%s", search_string);
  216. settings.searchType =
  217. gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(ss.rbRegExp)) ? 0 :
  218. gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(ss.rbPhraseSearch)) ? -1 : -2;
  219. if (settings.searchType == -2)
  220. settings.searchType = backendSearch->check_for_optimal_search(search_module);
  221. // if we do lucene search (-4), we assume AND for simple sidebar search.
  222. // therefore, we must prepend '+' to each word to force that semantic.
  223. if (settings.searchType == -4) {
  224. g_string_append_c(new_search, '+');
  225. while (*search_string) {
  226. while (((*search_string) != ' ') && ((*search_string) != '\0'))
  227. g_string_append_c(new_search, *(search_string++));
  228. if ((*search_string) == ' ') {
  229. g_string_append_c(new_search, ' ');
  230. search_string++;
  231. if ((*search_string) != '\0')
  232. g_string_append_c(new_search, '+');
  233. }
  234. }
  235. search_string = new_search->str;
  236. }
  237. search_params =
  238. gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(ss.ckbCaseSensitive)) ? 0 : REG_ICASE;
  239. terminate_search = FALSE;
  240. search_active = TRUE;
  241. // must ensure that no accents or vowel points are enabled.
  242. SWMgr *mgr = backendSearch->get_mgr();
  243. mgr->setGlobalOption("Greek Accents", "Off");
  244. mgr->setGlobalOption("Hebrew Vowel Points", "Off");
  245. mgr->setGlobalOption("Arabic Vowel Points", "Off");
  246. finds = backendSearch->do_module_search(search_module,
  247. mgr->getModule(search_module)->
  248. StripText(search_string),
  249. settings.searchType,
  250. search_params,
  251. FALSE);
  252. g_string_free(new_search, TRUE);
  253. search_active = FALSE;
  254. fill_search_results_list (finds);
  255. #ifdef HAVE_DBUS
  256. IpcObject *obj = ipc_get_main_ipc();
  257. if (obj){
  258. obj->references = get_list_of_references();
  259. ipc_object_search_performed(obj, settings.searchText,
  260. &finds, NULL);
  261. }
  262. #endif
  263. }
  264. void main_sidebar_perscomm_dump(void)
  265. {
  266. if (!backendSearch)
  267. main_init_sidebar_search_backend();
  268. strcpy(settings.sb_search_mod,settings.MainWindowModule);
  269. backendSearch->clear_scope();
  270. backendSearch->clear_search_list();
  271. fill_search_results_list(backendSearch->do_module_search
  272. /* personal commentary */ (settings.CommWindowModule,
  273. /* find one character */ ".",
  274. /* regexp */ 0,
  275. /* case is irrelevant */ 0,
  276. /* happening in sidebar */ FALSE));
  277. }
  278. void main_init_sidebar_search_backend(void)
  279. {
  280. if (!backendSearch)
  281. {
  282. backendSearch = new BackEnd();
  283. main_search_sidebar_fill_bounds_combos();
  284. }
  285. }
  286. void main_delete_sidebar_search_backend(void)
  287. {
  288. delete backendSearch;
  289. }
  290. void main_search_sidebar_fill_bounds_combos(void)
  291. {
  292. VerseKey key;
  293. char *book = NULL;
  294. char *module_name;
  295. int i = 0;
  296. //int testaments;
  297. if (!backendSearch)
  298. main_init_sidebar_search_backend();
  299. //module_name = settings.sb_search_mod;
  300. module_name = g_strdup(settings.MainWindowModule);
  301. //testaments = backendSearch->module_get_testaments(module_name);
  302. GtkTreeModel* upper_model = gtk_combo_box_get_model(
  303. GTK_COMBO_BOX(ss.entryUpper));
  304. gtk_list_store_clear(GTK_LIST_STORE(upper_model));
  305. GtkTreeModel* lower_model = gtk_combo_box_get_model(
  306. GTK_COMBO_BOX(ss.entryLower));
  307. gtk_list_store_clear(GTK_LIST_STORE(lower_model));
  308. if (backendSearch->module_has_testament(module_name, 1)) {
  309. while (i < key.BMAX[0]) {
  310. key.Testament(1);
  311. key.Book(i+1);
  312. book = strdup((const char *) key.getBookName());
  313. #ifdef USE_GTK_3
  314. gtk_combo_box_text_append_text((GtkComboBoxText*)ss.entryUpper, book);
  315. gtk_combo_box_text_append_text((GtkComboBoxText*)ss.entryLower, book);
  316. #else
  317. gtk_combo_box_append_text(GTK_COMBO_BOX(ss.entryUpper), book);
  318. gtk_combo_box_append_text(GTK_COMBO_BOX(ss.entryLower), book);
  319. #endif
  320. ++i;
  321. g_free(book);
  322. }
  323. }
  324. i = 0;
  325. if (backendSearch->module_has_testament(module_name, 2)) {
  326. while (i < key.BMAX[1]) {
  327. key.Testament(2);
  328. key.Book(i+1);
  329. book = strdup((const char *) key.getBookName());
  330. #ifdef USE_GTK_3
  331. gtk_combo_box_text_append_text((GtkComboBoxText*)ss.entryUpper, book);
  332. gtk_combo_box_text_append_text((GtkComboBoxText*)ss.entryLower, book);
  333. #else
  334. gtk_combo_box_append_text(GTK_COMBO_BOX(ss.entryUpper), book);
  335. gtk_combo_box_append_text(GTK_COMBO_BOX(ss.entryLower), book);
  336. #endif
  337. ++i;
  338. g_free(book);
  339. }
  340. }
  341. gtk_combo_box_set_active(GTK_COMBO_BOX(ss.entryLower),0);
  342. gtk_combo_box_set_active(GTK_COMBO_BOX(ss.entryUpper),65);
  343. }
  344. /******************************************************************************
  345. * Name
  346. * search_percent_update
  347. *
  348. * Synopsis
  349. * #include "main/search.h"
  350. *
  351. * void search_percent_update(char percent, void *userData)
  352. *
  353. * Description
  354. * updates the progress bar during shortcut bar search
  355. *
  356. * Return value
  357. * void
  358. */
  359. void main_sidebar_search_percent_update(char percent, void *userData)
  360. {
  361. char maxHashes = *((char *) userData);
  362. float num;
  363. char buf[80];
  364. static char printed = 0;
  365. if (!backendSearch)
  366. main_init_sidebar_search_backend();
  367. if (terminate_search) {
  368. backendSearch->terminate_search();
  369. } else {
  370. while ((((float) percent) / 100) * maxHashes > printed) {
  371. sprintf(buf, "%f", (((float) percent) / 100));
  372. num = (float) percent / 100;
  373. gtk_progress_bar_set_fraction((GtkProgressBar *)
  374. ss.progressbar_search, num);
  375. printed++;
  376. }
  377. }
  378. sync_windows();
  379. printed = 0;
  380. }