1 /*
2 * Xiphos Bible Study Tool
3 * tabbed_browser.c - functions to facilitate tabbed browsing of different passages at once
4 *
5 * Copyright (C) 2000-2020 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
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <unistd.h>
27 #include <gtk/gtk.h>
28 #include <glib.h>
29 #include <glib/gstdio.h>
30 #include <libxml/tree.h>
31 #include <libxml/parser.h>
32
33 #include "editor/slib-editor.h"
34
35 #include "gui/xiphos.h"
36 #include "gui/tabbed_browser.h"
37 #include "gui/bibletext.h"
38 #include "gui/bibletext_dialog.h"
39 #include "gui/commentary.h"
40 #include "gui/sidebar.h"
41 #include "gui/cipher_key_dialog.h"
42 #include "gui/main_menu.h"
43 #include "gui/main_window.h"
44 #include "gui/parallel_tab.h"
45 #include "gui/dialog.h"
46 #include "gui/font_dialog.h"
47 #include "gui/dictlex.h"
48 #include "gui/widgets.h"
49 #include "gui/utilities.h"
50
51 #include "main/lists.h"
52 #include "main/navbar_versekey.h"
53 #include "main/settings.h"
54 #include "main/sword.h"
55 #include "main/tab_history.h"
56 #include "main/xml.h"
57
58 #include <glib/gstdio.h>
59
60 #include "gui/debug_glib_null.h"
61
62 static GtkWidget *tab_widget_new(PASSAGE_TAB_INFO *tbinf,
63 const gchar *label_text);
64 void notebook_main_add_page(PASSAGE_TAB_INFO *tbinf);
65 void set_current_tab(PASSAGE_TAB_INFO *pt);
66
67 gboolean stop_refresh = FALSE;
68 gboolean change_tabs_no_redisplay = FALSE;
69 gboolean closing_tab = FALSE;
70
71 GList *passage_list;
72
73 /******************************************************************************
74 * externs
75 */
76
77 extern gboolean sync_on;
78 //extern gboolean gsI_isrunning;
79 PASSAGE_TAB_INFO *cur_passage_tab;
80
81 /******************************************************************************
82 * globals to this file only
83 */
84 static gboolean page_change = FALSE;
85 static gint removed_page;
86 static const gchar *default_tab_filename = ".last_session_tabs";
87 static const gchar *no_tab_filename = ".last_session_no_tabs";
88
yes_no2true_false(const gchar * yes_no)89 static int yes_no2true_false(const gchar *yes_no)
90 {
91 return (yes_no && !strcmp(yes_no, "yes"));
92 }
93
true_false2yes_no(int true_false)94 static gchar *true_false2yes_no(int true_false)
95 {
96 return (true_false ? "yes" : "no");
97 }
98
99 /******************************************************************************
100 * Name
101 * gui_recompute_shows
102 *
103 * Synopsis
104 * #include "tabbed_browser.h"
105 *
106 * void gui_recompute_shows(void)
107 *
108 * Description
109 * a new set of text/preview/comm/dict showings has been selected.
110 * re-align the displayed world with that.
111 *
112 * Return value
113 * void
114 */
gui_recompute_shows(gboolean flush)115 void gui_recompute_shows(gboolean flush)
116 {
117 if (stop_refresh)
118 return;
119 stop_refresh = TRUE;
120
121 if (flush)
122 main_flush_widgets_content();
123
124 if (cur_passage_tab)
125 gui_reassign_strdup(&settings.currentverse,
126 cur_passage_tab->text_commentary_key);
127
128 gui_show_hide_preview(settings.showpreview);
129 gui_show_hide_texts(settings.showtexts);
130 gui_show_hide_dicts(settings.showdicts);
131 gui_show_hide_comms(settings.showcomms);
132 gui_set_bible_comm_layout();
133
134 sync_windows();
135
136 stop_refresh = FALSE;
137 }
138
139 /******************************************************************************
140 * Name
141 * gui_recompute_view_menu_choices
142 *
143 * Synopsis
144 * #include "tabbed_browser.h"
145 *
146 * void gui_recompute_view_menu_choices(void)
147 *
148 * Description
149 * formerly part of gui_recompute_shows, but moved here to keep from
150 * triggering toggled signals on these items before new content is
151 * ready to be displayed
152 *
153 * Return value
154 * void
155 */
gui_recompute_view_menu_choices(void)156 void gui_recompute_view_menu_choices(void)
157 {
158 change_tabs_no_redisplay = TRUE;
159
160 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widgets.viewtexts_item),
161 settings.showtexts);
162 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widgets.viewcomms_item),
163 settings.showcomms);
164 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widgets.viewdicts_item),
165 settings.showdicts);
166 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widgets.viewpreview_item),
167 settings.showpreview);
168
169 change_tabs_no_redisplay = FALSE;
170 }
171
172 /******************************************************************************
173 * Name
174 * set_current_tab
175 *
176 * Synopsis
177 * #include "tabbed_browser.h"
178 *
179 * void set_current_tab (PASSAGE_TAB_INFO *pt)
180 *
181 * Description
182 * point cur_passage_tab to the current tab and turns the close button on
183 * and off
184 *
185 * Return value
186 * void
187 */
188
set_current_tab(PASSAGE_TAB_INFO * pt)189 void set_current_tab(PASSAGE_TAB_INFO *pt)
190 {
191 PASSAGE_TAB_INFO *ot = cur_passage_tab;
192
193 if (stop_refresh)
194 return;
195
196 if (!closing_tab && ot != NULL && ot->button_close != NULL) {
197 gtk_widget_set_sensitive(ot->button_close, FALSE);
198 }
199 cur_passage_tab = pt;
200 if (pt != NULL && pt->button_close != NULL) {
201 //main_update_tab_history_menu((PASSAGE_TAB_INFO*)pt);
202 gtk_widget_set_sensitive(pt->button_close, TRUE);
203
204 /* adopt panel shows from passage tab memory. */
205 settings.showtexts = pt->showtexts;
206 settings.showpreview = pt->showpreview;
207 settings.showcomms = pt->showcomms;
208 settings.showdicts = pt->showdicts;
209 settings.comm_showing = pt->comm_showing;
210 gui_recompute_shows(TRUE);
211 }
212 }
213
214 /******************************************************************************
215 * Name
216 * pick_tab_label
217 *
218 * Synopsis
219 * #include "tabbed_browser.h"
220 *
221 * void pick_tab_label(PASSAGE_TAB_INFO *pt)
222 *
223 * Description
224 * selects a tab label based on panel shows.
225 *
226 * Return value
227 * GString *
228 * ** caller must free it **
229 */
230
pick_tab_label(PASSAGE_TAB_INFO * pt)231 GString *pick_tab_label(PASSAGE_TAB_INFO *pt)
232 {
233 GString *str = g_string_new(NULL);
234
235 const char *abbrev_text = main_get_abbreviation(pt->text_mod);
236 const char *abbrev_comm =
237 main_get_abbreviation(pt->commentary_mod);
238 const char *abbrev_dict = main_get_abbreviation(pt->dictlex_mod);
239 const char *abbrev_book = main_get_abbreviation(pt->book_mod);
240
241 if (pt->showparallel) {
242 g_string_printf(str, "%s", _("Parallel View"));
243 return str;
244 }
245
246 if (pt->showtexts || (pt->showcomms && pt->comm_showing)) {
247 g_string_printf(str, "%s: %s",
248 (pt->showtexts
249 ? (abbrev_text ? abbrev_text : pt->text_mod)
250 : (pt->commentary_mod
251 ? (abbrev_comm ? abbrev_comm : pt->commentary_mod)
252 : "[no commentary]")),
253 pt->text_commentary_key);
254 } else {
255 g_string_printf(str, "%s",
256 (pt->showcomms
257 ? (pt->book_mod
258 ? (abbrev_book ? abbrev_book : pt->book_mod)
259 : "[no book]")
260 : (pt->dictlex_mod
261 ? (abbrev_dict ? abbrev_dict : pt->dictlex_mod)
262 : "[no dict]")));
263 }
264 return str;
265 }
266
267 /******************************************************************************
268 * Name
269 * notebook_main_add_page
270 *
271 * Synopsis
272 * #include "tabbed_browser.h"
273 *
274 * void notebook_main_add_page(PASSAGE_TAB_INFO *tbinf)
275 *
276 * Description
277 * adds a new page and label to the main notebook for a new scripture passage
278 *
279 * Return value
280 * void
281 */
notebook_main_add_page(PASSAGE_TAB_INFO * tbinf)282 void notebook_main_add_page(PASSAGE_TAB_INFO *tbinf)
283 {
284 GtkWidget *tab_widget;
285 GtkWidget *menu_label;
286 GString *str;
287
288 str = pick_tab_label(tbinf);
289 UI_VBOX(tbinf->page_widget, FALSE, 0);
290 if (tbinf->showparallel)
291 widgets.parallel_tab = tbinf->page_widget;
292 gtk_widget_show(tbinf->page_widget);
293
294 tab_widget = tab_widget_new(tbinf, str->str);
295 /*gtk_notebook_insert_page(GTK_NOTEBOOK(widgets.notebook_main),
296 tbinf->page_widget,
297 tab_widget,
298 tbinf->showparallel ? 1 : -1); */
299 gtk_notebook_append_page(GTK_NOTEBOOK(widgets.notebook_main),
300 tbinf->page_widget, tab_widget);
301
302 gtk_notebook_set_menu_label_text(GTK_NOTEBOOK(widgets.notebook_main),
303 tbinf->page_widget, str->str);
304
305 menu_label = gtk_label_new(str->str);
306 gtk_notebook_set_menu_label(GTK_NOTEBOOK(widgets.notebook_main),
307 tbinf->page_widget, menu_label);
308 g_string_free(str, TRUE);
309 }
310
311 /******************************************************************************
312 * Name
313 * gui_save_tabs
314 *
315 * Synopsis
316 * #include "tabbed_browser.h"
317 *
318 * Description
319 * Saves the information for the current set of tabs.
320 *
321 * Return value
322 *
323 */
324
gui_save_tabs(const gchar * filename)325 void gui_save_tabs(const gchar *filename)
326 {
327 xmlDocPtr xml_doc;
328 xmlNodePtr root_node;
329 xmlNodePtr cur_node;
330 xmlNodePtr section_node;
331 // xmlAttrPtr xml_attr;
332 //const xmlChar *xml_filename;
333 gchar *file;
334 GList *tmp = NULL;
335
336 if (NULL == filename)
337 filename = default_tab_filename;
338
339 if (g_access(filename, F_OK) == 0) {
340 /* we're done, just copy for local use that can be free'd */
341 file = g_strdup(filename);
342 } else {
343 gchar *tabs_dir = g_strdup_printf("%s/tabs/", settings.gSwordDir);
344 if (g_access(tabs_dir, F_OK) == -1) {
345 if ((g_mkdir(tabs_dir, S_IRWXU)) == -1) {
346 gui_generic_warning_modal(_("Can't create tabs dir."));
347 return;
348 }
349 }
350 file = g_strdup_printf("%s%s", tabs_dir, filename);
351 g_free(tabs_dir);
352 }
353 //xml_filename = (const xmlChar *) file;
354
355 xml_doc = xmlNewDoc((const xmlChar *)"1.0");
356
357 if (xml_doc == NULL) {
358 gui_generic_warning_modal("Tabs document not created successfully.");
359 return;
360 }
361
362 root_node = xmlNewNode(NULL, (const xmlChar *)"Xiphos_Tabs");
363 //xml_attr =
364 xmlNewProp(root_node, (const xmlChar *)"Version",
365 (const xmlChar *)VERSION);
366 xmlDocSetRootElement(xml_doc, root_node);
367
368 section_node = xmlNewChild(root_node, NULL,
369 (const xmlChar *)"tabs", NULL);
370
371 for (tmp = g_list_first(passage_list); tmp != NULL;
372 tmp = g_list_next(tmp)) {
373
374 PASSAGE_TAB_INFO *pt = (PASSAGE_TAB_INFO *)tmp->data;
375
376 cur_node = xmlNewChild(section_node,
377 NULL, (const xmlChar *)"tab",
378 NULL);
379 xmlNewProp(cur_node, (const xmlChar *)"text_mod",
380 (const xmlChar *)pt->text_mod);
381 xmlNewProp(cur_node, (const xmlChar *)"commentary_mod",
382 (const xmlChar *)pt->commentary_mod);
383 xmlNewProp(cur_node, (const xmlChar *)"dictlex_mod",
384 (const xmlChar *)pt->dictlex_mod);
385 xmlNewProp(cur_node, (const xmlChar *)"book_mod",
386 (const xmlChar *)pt->book_mod);
387 xmlNewProp(cur_node,
388 (const xmlChar *)"text_commentary_key",
389 (const xmlChar *)pt->text_commentary_key);
390 xmlNewProp(cur_node, (const xmlChar *)"dictlex_key",
391 (const xmlChar *)pt->dictlex_key);
392 xmlNewProp(cur_node, (const xmlChar *)"book_offset",
393 (const xmlChar *)pt->book_offset);
394 xmlNewProp(cur_node, (const xmlChar *)"comm_showing",
395 (const xmlChar *)
396 true_false2yes_no(pt->comm_showing));
397 xmlNewProp(cur_node, (const xmlChar *)"showtexts",
398 (const xmlChar *)
399 true_false2yes_no(pt->showtexts));
400 xmlNewProp(cur_node, (const xmlChar *)"showpreview",
401 (const xmlChar *)
402 true_false2yes_no(pt->showpreview));
403 xmlNewProp(cur_node, (const xmlChar *)"showcomms",
404 (const xmlChar *)
405 true_false2yes_no(pt->showcomms));
406 xmlNewProp(cur_node, (const xmlChar *)"showdicts",
407 (const xmlChar *)
408 true_false2yes_no(pt->showdicts));
409 xmlNewProp(cur_node, (const xmlChar *)"showparallel",
410 (const xmlChar *)
411 true_false2yes_no(pt->showparallel));
412 }
413 xmlSaveFormatFile(file, xml_doc, 1);
414 g_free(file);
415 xmlFreeDoc(xml_doc);
416 }
417
418 /******************************************************************************
419 * Name
420 *
421 *
422 * Synopsis
423 * #include "tabbed_browser.h"
424 *
425 * void _save_off_tabs(const gchar *filename)
426 *
427 * Description
428 * Saves the information for the current set of tabs.
429 *
430 * Return value
431 *
432 */
433
_save_off_tab(const gchar * filename)434 static void _save_off_tab(const gchar *filename)
435 {
436 xmlDocPtr xml_doc;
437 xmlNodePtr root_node;
438 xmlNodePtr cur_node;
439 xmlNodePtr section_node;
440 //xmlAttrPtr xml_attr;
441 gchar *tabs_dir;
442 gchar *file;
443
444 if (NULL == filename)
445 filename = no_tab_filename;
446
447 tabs_dir = g_strdup_printf("%s/tabs/", settings.gSwordDir);
448
449 if (g_access(tabs_dir, F_OK) == -1) {
450 if ((g_mkdir(tabs_dir, S_IRWXU)) == -1) {
451 gui_generic_warning_modal("Can't create tabs dir.");
452 return;
453 }
454 }
455 file = g_strdup_printf("%s%s", tabs_dir, filename);
456 g_free(tabs_dir);
457
458 xml_doc = xmlNewDoc((const xmlChar *)"1.0");
459
460 if (xml_doc == NULL) {
461 gui_generic_warning_modal("Tabs document not created successfully.");
462 return;
463 }
464
465 root_node = xmlNewNode(NULL, (const xmlChar *)"Xiphos_Tabs");
466 //xml_attr =
467 xmlNewProp(root_node, (const xmlChar *)"Version",
468 (const xmlChar *)VERSION);
469 xmlDocSetRootElement(xml_doc, root_node);
470
471 section_node = xmlNewChild(root_node, NULL,
472 (const xmlChar *)"tabs", NULL);
473
474 cur_node = xmlNewChild(section_node,
475 NULL, (const xmlChar *)"tab", NULL);
476 xmlNewProp(cur_node, (const xmlChar *)"text_mod",
477 (const xmlChar *)settings.MainWindowModule);
478 xmlNewProp(cur_node, (const xmlChar *)"commentary_mod",
479 (const xmlChar *)settings.CommWindowModule);
480 xmlNewProp(cur_node, (const xmlChar *)"dictlex_mod",
481 (const xmlChar *)settings.DictWindowModule);
482 xmlNewProp(cur_node, (const xmlChar *)"book_mod",
483 (const xmlChar *)settings.book_mod);
484 xmlNewProp(cur_node, (const xmlChar *)"text_commentary_key",
485 (const xmlChar *)settings.currentverse);
486 xmlNewProp(cur_node, (const xmlChar *)"dictlex_key",
487 (const xmlChar *)settings.dictkey);
488 xmlNewProp(cur_node, (const xmlChar *)"book_offset",
489 (const xmlChar *)settings.book_key);
490 xmlNewProp(cur_node, (const xmlChar *)"comm_showing",
491 (const xmlChar *)
492 true_false2yes_no(settings.comm_showing));
493 xmlNewProp(cur_node, (const xmlChar *)"showtexts",
494 (const xmlChar *)
495 true_false2yes_no(settings.showtexts));
496 xmlNewProp(cur_node, (const xmlChar *)"showpreview",
497 (const xmlChar *)
498 true_false2yes_no(settings.showpreview));
499 xmlNewProp(cur_node, (const xmlChar *)"showcomms",
500 (const xmlChar *)
501 true_false2yes_no(settings.showcomms));
502 xmlNewProp(cur_node, (const xmlChar *)"showdicts",
503 (const xmlChar *)
504 true_false2yes_no(settings.showdicts));
505 xmlNewProp(cur_node, (const xmlChar *)"showparallel",
506 (const xmlChar *)"no");
507
508 xmlSaveFormatFile(file, xml_doc, 1);
509 g_free(file);
510 xmlFreeDoc(xml_doc);
511 }
512
513 /******************************************************************************
514 * Name
515 * gui_load_tabs
516 *
517 * Synopsis
518 * #include "tabbed_browser.h"
519 *
520 * Description
521 * Load the tabs from the given file.
522 *
523 * Return value
524 *
525 */
526
gui_load_tabs(const gchar * filename)527 void gui_load_tabs(const gchar *filename)
528 {
529 xmlDocPtr xml_doc;
530 xmlNodePtr tmp_node, childnode;
531 //const xmlChar *xml_filename;
532 gboolean error = FALSE;
533 gboolean back_compat_need_save = FALSE;
534 settings.showparatab = FALSE;
535 PASSAGE_TAB_INFO *pt = NULL, *pt_first = NULL;
536
537 stop_refresh = TRUE;
538
539 if (filename == NULL) {
540 error = TRUE;
541 } else {
542 gchar *file;
543
544 if (g_access(filename, F_OK) == 0) {
545 /* we're done, just copy for local use that can be free'd */
546 file = g_strdup(filename);
547 } else {
548 gchar *tabs_dir =
549 g_strdup_printf("%s/tabs/",
550 settings.gSwordDir);
551 if (g_access(tabs_dir, F_OK) == -1) {
552 XI_message(("Creating new tabs directory\n"));
553 gui_save_tabs(filename);
554 }
555 file = g_strdup_printf("%s%s", tabs_dir, filename);
556 g_free(tabs_dir);
557 }
558
559 /* we need this for first time non tabbed browsing */
560 if (!settings.browsing && g_access(file, F_OK) == -1) {
561 _save_off_tab(filename);
562 }
563 //xml_filename = (const xmlChar *) file;
564 xml_doc = xmlParseFile(file);
565 g_free(file);
566 if (xml_doc == NULL) {
567 gui_generic_warning_modal("Tabs document not parsed successfully.");
568 error = TRUE;
569 } else {
570 tmp_node = xmlDocGetRootElement(xml_doc);
571 if (tmp_node == NULL) {
572 gui_generic_warning_modal("Tabs document is empty.");
573 xmlFreeDoc(xml_doc);
574 error = TRUE;
575 } else if (xmlStrcmp(tmp_node->name,
576 (const xmlChar *)"Xiphos_Tabs")) {
577 gui_generic_warning_modal("Tabs document has wrong type, root node != Xiphos_Tabs");
578 xmlFreeDoc(xml_doc);
579 error = TRUE;
580 }
581 }
582
583 if (error == FALSE) {
584 for (childnode = tmp_node->children;
585 childnode != NULL;
586 childnode = childnode->next) {
587 if (!xmlStrcmp(childnode->name,
588 (const xmlChar *)"tabs")) {
589 tmp_node = childnode;
590 for (tmp_node = tmp_node->children;
591 tmp_node != NULL;
592 tmp_node = tmp_node->next) {
593 if (!xmlStrcmp(tmp_node->name,
594 (const xmlChar *)"tab")) {
595 gchar *val;
596
597 pt = g_new0(PASSAGE_TAB_INFO,
598 1);
599 if (pt_first ==
600 NULL)
601 pt_first =
602 pt;
603
604 /* load per-tab module information. */
605 val = (gchar *)
606 xmlGetProp(tmp_node,
607 (const xmlChar *)"text_mod");
608 pt->text_mod =
609 g_strdup(val);
610 xmlFree(val);
611 val = (gchar *)
612 xmlGetProp(tmp_node,
613 (const xmlChar *)"commentary_mod");
614 pt->commentary_mod =
615 g_strdup(val);
616 xmlFree(val);
617 val = (gchar *)
618 xmlGetProp(tmp_node,
619 (const xmlChar *)"dictlex_mod");
620 pt->dictlex_mod =
621 g_strdup(val);
622 xmlFree(val);
623 val = (gchar *)
624 xmlGetProp(tmp_node,
625 (const xmlChar *)"book_mod");
626 pt->book_mod =
627 g_strdup(val);
628 xmlFree(val);
629 val = (gchar *)
630 xmlGetProp(tmp_node,
631 (const xmlChar *)"text_commentary_key");
632 pt->text_commentary_key = g_strdup(val);
633 xmlFree(val);
634 val = (gchar *)
635 xmlGetProp(tmp_node,
636 (const xmlChar *)"dictlex_key");
637 pt->dictlex_key =
638 g_strdup(val);
639 xmlFree(val);
640 val = (gchar *)
641 xmlGetProp(tmp_node,
642 (const xmlChar *)"book_offset");
643 pt->book_offset =
644 g_strdup(val);
645 xmlFree(val);
646 val = (gchar *)
647 xmlGetProp(tmp_node,
648 (const xmlChar *)"comm_showing");
649 pt->comm_showing =
650 yes_no2true_false(val);
651 xmlFree(val);
652 val = (gchar *)
653 xmlGetProp(tmp_node,
654 (const xmlChar *)"showparallel");
655 pt->showparallel =
656 yes_no2true_false(val);
657 xmlFree(val);
658 if (pt->showparallel) {
659 settings.showparatab = TRUE;
660 pt->paratab =
661 gui_create_parallel_tab();
662 gtk_box_pack_start(GTK_BOX(widgets.page),
663 pt->paratab,
664 TRUE,
665 TRUE,
666 0);
667 gtk_widget_hide(pt->paratab);
668 gui_parallel_tab_sync((gchar *)
669 settings.currentverse);
670 settings.showparatab = TRUE;
671 sync_on =
672 TRUE;
673 } else
674 pt->paratab = NULL;
675
676 /*
677 * load per-tab "show" state.
678 * includes backward compatibility:
679 * if there is no per-tab state,
680 * take tab state from global state.
681 */
682 if ((val =
683 (gchar *)
684 xmlGetProp(tmp_node,
685 (const xmlChar *)"showtexts"))) {
686 pt->showtexts = yes_no2true_false(val);
687 xmlFree(val);
688 val =
689 (gchar *)
690 xmlGetProp(tmp_node,
691 (const xmlChar *)"showpreview");
692 pt->showpreview = yes_no2true_false(val);
693 xmlFree(val);
694 val =
695 (gchar *)
696 xmlGetProp(tmp_node,
697 (const xmlChar *)"showcomms");
698 pt->showcomms = yes_no2true_false(val);
699 xmlFree(val);
700 val =
701 (gchar *)
702 xmlGetProp(tmp_node,
703 (const xmlChar *)"showdicts");
704 pt->showdicts = yes_no2true_false(val);
705 xmlFree(val);
706
707 } else {
708 pt->showtexts = settings.showtexts;
709 pt->showpreview = settings.showpreview;
710 pt->showcomms = settings.showcomms;
711 pt->showdicts = settings.showdicts;
712 back_compat_need_save = TRUE;
713 }
714
715 pt->history_items =
716 0;
717 pt->current_history_item = 0;
718 pt->first_back_click = TRUE;
719 main_add_tab_history_item((PASSAGE_TAB_INFO *)pt);
720
721 gui_reassign_strdup(&settings.currentverse,
722 pt->text_commentary_key);
723
724 passage_list =
725 g_list_append(passage_list,
726 (PASSAGE_TAB_INFO *)pt);
727 notebook_main_add_page(pt);
728 }
729 }
730 }
731 }
732 }
733 xmlFreeDoc(xml_doc);
734
735 /* backward compatibility completion. */
736 if (back_compat_need_save)
737 gui_save_tabs(filename);
738
739 if (error == TRUE || pt == NULL) {
740 pt = g_new0(PASSAGE_TAB_INFO, 1);
741 pt->text_mod = g_strdup(settings.MainWindowModule);
742 pt->commentary_mod =
743 g_strdup(settings.CommWindowModule);
744 pt->dictlex_mod =
745 g_strdup(settings.DictWindowModule);
746 pt->book_mod = g_strdup(settings.book_mod); //NULL;
747 pt->text_commentary_key =
748 g_strdup(settings.currentverse);
749 pt->dictlex_key = g_strdup(settings.dictkey);
750 pt->book_offset = NULL; //settings.book_offset = atol(xml_get_value( "keys", "offset"));
751
752 pt->paratab = NULL;
753
754 pt->showtexts = settings.showtexts;
755 pt->showpreview = settings.showpreview;
756 pt->showcomms = settings.showcomms;
757 pt->showdicts = settings.showdicts;
758
759 pt->history_items = 0;
760 pt->current_history_item = 0;
761 pt->first_back_click = TRUE;
762 // main_add_tab_history_item((PASSAGE_TAB_INFO*)pt);
763 passage_list =
764 g_list_append(passage_list,
765 (PASSAGE_TAB_INFO *)pt);
766 notebook_main_add_page(pt);
767 } else {
768 // first passage is current/displayed.
769 pt = pt_first;
770
771 pt->paratab = NULL;
772 // This is a hack to keep gs from loading the settings
773 // from the last session into the last tab loaded here.
774 gui_reassign_strdup(&settings.MainWindowModule,
775 pt->text_mod);
776 gui_reassign_strdup(&settings.CommWindowModule,
777 pt->commentary_mod);
778 gui_reassign_strdup(&settings.DictWindowModule,
779 pt->dictlex_mod);
780 gui_reassign_strdup(&settings.book_mod,
781 pt->book_mod);
782 gui_reassign_strdup(&settings.currentverse,
783 pt->text_commentary_key);
784 gui_reassign_strdup(&settings.dictkey,
785 pt->dictlex_key);
786 settings.book_offset = atol(pt->book_offset);
787 }
788 }
789
790 stop_refresh = FALSE;
791 set_current_tab(pt);
792 gui_recompute_view_menu_choices();
793 }
794
795 /******************************************************************************
796 * Name
797 * on_notebook_main_close_page
798 *
799 * Synopsis
800 * #include "tabbed_browser.h"
801 *
802 * void on_notebook_main_close_page(GtkButton * button, gpointer user_data)
803 *
804 * Description
805 *
806 *
807 * Return value
808 * void
809 */
810
on_notebook_main_close_page(GtkButton * button,gpointer user_data)811 static void on_notebook_main_close_page(GtkButton *button,
812 gpointer user_data)
813 {
814 PASSAGE_TAB_INFO *pt = (PASSAGE_TAB_INFO *)user_data;
815 closing_tab = TRUE;
816 gui_close_passage_tab(gtk_notebook_page_num(GTK_NOTEBOOK(widgets.notebook_main),
817 pt->page_widget));
818 closing_tab = FALSE;
819 }
820
821 /******************************************************************************
822 * Name
823 * tab_widget_new
824 *
825 * Synopsis
826 * #include "tabbed_browser.h"
827 *
828 * GtkWidget* tab_widget_new(PASSAGE_TAB_INFO *tbinf,const gchar *label_text)
829 *
830 * Description
831 * creates a tab widget that contains a label and a close button
832 *
833 * Return value
834 * GtkWidget*
835 */
836
tab_widget_new(PASSAGE_TAB_INFO * tbinf,const gchar * label_text)837 static GtkWidget *tab_widget_new(PASSAGE_TAB_INFO *tbinf,
838 const gchar *label_text)
839 {
840 GtkWidget *box;
841 #ifdef USE_GTK_3
842 // GdkRGBA color;
843 #else
844 GdkColor color;
845 #endif
846
847 g_return_val_if_fail(label_text != NULL, NULL);
848 #if GTK_CHECK_VERSION(3, 10, 0)
849 tbinf->button_close = gtk_button_new_from_icon_name("window-close-symbolic", GTK_ICON_SIZE_MENU);
850 #if GTK_CHECK_VERSION(3, 20, 0)
851 gtk_button_set_relief(GTK_BUTTON(tbinf->button_close), GTK_RELIEF_NONE);
852 #else
853 #endif
854 #else
855 GtkWidget *tmp_toolbar_icon = gtk_image_new_from_stock(GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU);
856 tbinf->button_close = gtk_button_new();
857 gtk_button_set_image(GTK_BUTTON(tbinf->button_close), tmp_toolbar_icon);
858 gtk_button_set_relief(GTK_BUTTON(tbinf->button_close), GTK_RELIEF_NONE);
859 #endif
860
861 #ifndef USE_GTK_3
862 gtk_rc_parse_string("style \"tab-button-style\"\n"
863 "{\n"
864 " GtkWidget::focus-padding = 0\n"
865 " GtkWidget::focus-line-width = 0\n"
866 " xthickness = 0\n"
867 " ythickness = 0\n"
868 " GtkButton::internal-border = {0, 0, 0, 0}\n"
869 " GtkButton::default-border = {0, 0, 0, 0}\n"
870 " GtkButton::default-outside-border = {0, 0, 0, 0}\n"
871 "}\n"
872 "widget \"*.button-close\" style \"tab-button-style\"");
873 gtk_widget_set_name(GTK_WIDGET(tbinf->button_close),
874 "button-close");
875 #else
876 gtk_widget_set_size_request(tbinf->button_close, 18, 16);
877 #endif
878
879 #ifndef USE_GTK_3
880 GtkRequisition r;
881 gtk_widget_size_request(tbinf->button_close, &r);
882 #endif
883
884 gtk_widget_set_sensitive(tbinf->button_close, FALSE);
885 gtk_widget_show(tbinf->button_close);
886 tbinf->tab_label = GTK_LABEL(gtk_label_new(label_text));
887 gtk_widget_show(GTK_WIDGET(tbinf->tab_label));
888
889 #ifdef USE_GTK_3
890 #else
891 color.red = 0;
892 color.green = 0;
893 color.blue = 0;
894
895 gtk_widget_modify_fg(tbinf->button_close, GTK_STATE_NORMAL,
896 &color);
897 gtk_widget_modify_fg(tbinf->button_close, GTK_STATE_INSENSITIVE,
898 &color);
899 gtk_widget_modify_fg(tbinf->button_close, GTK_STATE_ACTIVE,
900 &color);
901 gtk_widget_modify_fg(tbinf->button_close, GTK_STATE_PRELIGHT,
902 &color);
903 gtk_widget_modify_fg(tbinf->button_close, GTK_STATE_SELECTED,
904 &color);
905 #endif
906
907 UI_HBOX(box, FALSE, 0);
908 gtk_box_pack_start(GTK_BOX(box), GTK_WIDGET(tbinf->tab_label),
909 TRUE, TRUE, 0);
910 gtk_box_pack_start(GTK_BOX(box), tbinf->button_close, FALSE, FALSE,
911 0);
912
913 gtk_widget_show(box);
914
915 g_signal_connect(G_OBJECT(tbinf->button_close), "clicked",
916 G_CALLBACK(on_notebook_main_close_page), tbinf);
917
918 return box;
919 }
920
921 /******************************************************************************
922 * Name
923 * gui_notebook_main_switch_page
924 *
925 * Synopsis
926 * #include "tabbed_browser.h"
927 *
928 * void gui_notebook_main_switch_page(GtkNotebook * notebook,
929 * GtkNotebookPage * page,
930 * gint page_num, GList * tl)
931 *
932 * Description
933 * sets gui to new passage
934 *
935 * Return value
936 * void
937 */
938 #ifdef USE_GTK_3
gui_notebook_main_switch_page(GtkNotebook * notebook,gpointer arg,gint page_num,GList ** tl)939 void gui_notebook_main_switch_page(GtkNotebook *notebook,
940 gpointer arg,
941 gint page_num, GList **tl)
942 #else
943 void gui_notebook_main_switch_page(GtkNotebook *notebook,
944 GtkNotebookPage *page,
945 gint page_num, GList **tl)
946 #endif
947 {
948 gboolean comm_showing;
949 gint number_of_pages = gtk_notebook_get_n_pages(notebook);
950 PASSAGE_TAB_INFO *pt;
951
952 if (stop_refresh)
953 return;
954
955 XI_message(("on_notebook_main_switch_page"));
956 page_change = TRUE;
957 /* get data structure for new passage */
958 /*
959 * this is needed to stop seg fault if the left tab is closed when
960 * there are only two tabs - because number_of_pages equals 2 even
961 * thought there is only 1.
962 */
963 if (number_of_pages == 2 && removed_page == 0)
964 pt = (PASSAGE_TAB_INFO *)g_list_nth_data(*tl, 0);
965 else
966 pt = (PASSAGE_TAB_INFO *)g_list_nth_data(*tl, page_num);
967 removed_page = 1;
968 //cur_passage_tab = pt;
969
970 #ifdef USE_TREEVIEW_PATH
971 if (cur_passage_tab && cur_passage_tab->book_mod)
972 gui_collapse_treeview_to_book(GTK_TREE_VIEW(sidebar.module_list),
973 cur_passage_tab->book_mod);
974 #endif /* USE_TREEVIEW_PATH */
975
976 if (!pt->showparallel) {
977 if (cur_passage_tab && cur_passage_tab->paratab)
978 gtk_widget_hide(cur_passage_tab->paratab);
979 gtk_widget_show(widgets.hpaned);
980 }
981
982 set_current_tab(pt);
983
984 companion_activity = TRUE;
985 if (pt->showparallel) {
986 gtk_widget_hide(widgets.hpaned);
987 if (pt->paratab)
988 gtk_widget_show(pt->paratab);
989 companion_activity = FALSE;
990 page_change = FALSE;
991 settings.paratab_showing = TRUE;
992 return;
993 } else
994 settings.paratab_showing = FALSE;
995
996 //sets the book mod and key
997 main_display_book(pt->book_mod, pt->book_offset);
998
999 #ifdef USE_TREEVIEW_PATH
1000 if (pt->showcomms && pt->book_mod)
1001 gui_expand_treeview_to_path(GTK_TREE_VIEW(sidebar.module_list),
1002 pt->book_mod);
1003 #endif /* USE_TREEVIEW_PATH */
1004
1005 comm_showing = settings.comm_showing;
1006 settings.comm_showing = 1;
1007 //sets the commentary mod and key
1008 main_display_commentary(pt->commentary_mod,
1009 pt->text_commentary_key);
1010 settings.comm_showing = comm_showing;
1011 //sets the text mod and key
1012 main_display_bible(pt->text_mod, pt->text_commentary_key);
1013
1014 navbar_versekey.module_name =
1015 g_string_assign(navbar_versekey.module_name, pt->text_mod);
1016 navbar_versekey.key =
1017 g_string_assign(navbar_versekey.key, pt->text_commentary_key);
1018 main_update_nav_controls(navbar_versekey.module_name->str,
1019 pt->text_commentary_key);
1020
1021 //sets the dictionary mod and key
1022 main_display_dictionary(pt->dictlex_mod, pt->dictlex_key);
1023
1024 gtk_notebook_set_current_page(GTK_NOTEBOOK(widgets.notebook_comm_book),
1025 (pt->comm_showing ? 0 : 1));
1026
1027 gui_recompute_view_menu_choices();
1028
1029 companion_activity = FALSE;
1030
1031 page_change = FALSE;
1032 }
1033
1034 /******************************************************************************
1035 * Name
1036 * gui_select_nth_tab
1037 *
1038 * Synopsis
1039 * #include "tabbed_browser.h"
1040 *
1041 * void gui_select_nth_tab(gint page_num)
1042 *
1043 * Description
1044 * from ctrl-DIGIT in main_window.c, select a tab.
1045 * the tab list is 0-based: page_num must already be 0-normalized.
1046 *
1047 * Return value
1048 * void
1049 */
1050
gui_select_nth_tab(gint page_num)1051 void gui_select_nth_tab(gint page_num)
1052 {
1053 gint number_of_pages =
1054 gtk_notebook_get_n_pages(GTK_NOTEBOOK(widgets.notebook_main));
1055
1056 /* within bounds of available tabs? */
1057 if (page_num >= number_of_pages)
1058 return;
1059
1060 settings.tab_page = page_num;
1061 gtk_notebook_set_current_page(GTK_NOTEBOOK(widgets.notebook_main),
1062 page_num);
1063 gui_notebook_main_switch_page(GTK_NOTEBOOK(widgets.notebook_main),
1064 NULL, page_num, &passage_list);
1065 }
1066
1067 /******************************************************************************
1068 * Name
1069 * gui_set_tab_label
1070 *
1071 * Synopsis
1072 * #include "tabbed_browser.h"
1073 if *
1074 * void gui_set_tab_label(const char *key, gboolean one_tab)
1075 *
1076 * Description
1077 * sets tab label(s) to current verse.
1078 * dependent on linkedtabs setting, either just cur or all.
1079 * one_tab means don't loop the set, just set current.
1080 *
1081 * Return value
1082 * void
1083 */
1084
gui_set_tab_label(const gchar * key,gboolean one_tab)1085 void gui_set_tab_label(const gchar *key, gboolean one_tab)
1086 {
1087 if (stop_refresh)
1088 return;
1089
1090 if ((settings.linkedtabs && !one_tab) || (cur_passage_tab == NULL)) {
1091 GList *tmp = NULL;
1092 for (tmp = g_list_first(passage_list); tmp != NULL;
1093 tmp = g_list_next(tmp))
1094 gui_set_named_tab_label(key, (PASSAGE_TAB_INFO *)
1095 tmp->data,
1096 ((PASSAGE_TAB_INFO *)
1097 tmp->data ==
1098 cur_passage_tab));
1099 } else {
1100 gui_set_named_tab_label(key, cur_passage_tab, TRUE);
1101 }
1102 }
1103
1104 /******************************************************************************
1105 * Name
1106 * gui_set_named_tab_label
1107 *
1108 * Synopsis
1109 * #include "tabbed_browser.h"
1110 *
1111 * void gui_set_named_tab_label(const char *key, PASSAGE_TAB_INFO *pt)
1112 *
1113 * Description
1114 * sets specified tab label to current verse
1115 *
1116 * Return value
1117 * void
1118 */
1119
gui_set_named_tab_label(const gchar * key,PASSAGE_TAB_INFO * pt,gboolean update)1120 void gui_set_named_tab_label(const gchar *key, PASSAGE_TAB_INFO *pt,
1121 gboolean update)
1122 {
1123 GString *str;
1124
1125 if (stop_refresh)
1126 return;
1127
1128 gui_reassign_strdup(&pt->text_commentary_key, (char *)key);
1129 str = pick_tab_label(pt);
1130
1131 gtk_label_set_text(pt->tab_label, str->str);
1132 gtk_notebook_set_menu_label_text(GTK_NOTEBOOK(widgets.notebook_main),
1133 pt->page_widget, str->str);
1134 if (update)
1135 main_add_tab_history_item((PASSAGE_TAB_INFO *)pt);
1136 g_string_free(str, TRUE);
1137 }
1138
1139 /******************************************************************************
1140 * Name
1141 *
1142 *
1143 * Synopsis
1144 * #include "tabbed_browser.h"
1145 *
1146 *
1147 *
1148 * Description
1149 *
1150 *
1151 * Return value
1152 * void
1153 */
1154
gui_update_tab_struct(const gchar * text_mod,const gchar * commentary_mod,const gchar * dictlex_mod,const gchar * book_mod,const gchar * dictlex_key,const gchar * book_offset,gboolean comm_showing,gboolean showtexts,gboolean showpreview,gboolean showcomms,gboolean showdicts)1155 void gui_update_tab_struct(const gchar *text_mod,
1156 const gchar *commentary_mod,
1157 const gchar *dictlex_mod,
1158 const gchar *book_mod,
1159 const gchar *dictlex_key,
1160 const gchar *book_offset,
1161 gboolean comm_showing,
1162 gboolean showtexts,
1163 gboolean showpreview,
1164 gboolean showcomms, gboolean showdicts)
1165 {
1166 if (stop_refresh)
1167 return;
1168
1169 /* if (!settings.browsing)
1170 return;
1171 */
1172
1173 if (page_change)
1174 return;
1175 if (!cur_passage_tab)
1176 return;
1177 cur_passage_tab->showtexts = showtexts;
1178 cur_passage_tab->showpreview = showpreview;
1179 cur_passage_tab->showcomms = showcomms;
1180 cur_passage_tab->showdicts = showdicts;
1181
1182 if (text_mod) {
1183 gui_reassign_strdup(&cur_passage_tab->text_mod,
1184 (char *)text_mod);
1185 }
1186 if (commentary_mod) {
1187 cur_passage_tab->comm_showing = comm_showing;
1188 gui_reassign_strdup(&cur_passage_tab->commentary_mod,
1189 (char *)commentary_mod);
1190 }
1191 if (dictlex_mod) {
1192 gui_reassign_strdup(&cur_passage_tab->dictlex_mod,
1193 (char *)dictlex_mod);
1194 }
1195 if (book_mod) {
1196 cur_passage_tab->comm_showing = comm_showing;
1197 gui_reassign_strdup(&cur_passage_tab->book_mod,
1198 (char *)book_mod);
1199 }
1200 if (book_offset) {
1201 gui_reassign_strdup(&cur_passage_tab->book_offset,
1202 (char *)book_offset);
1203 }
1204 if (dictlex_key) {
1205 gui_reassign_strdup(&cur_passage_tab->dictlex_key,
1206 (char *)dictlex_key);
1207 }
1208 }
1209
1210 /******************************************************************************
1211 * Name
1212 * gui_open_passage_in_new_tab
1213 *
1214 * Synopsis
1215 * #include "tabbed_browser.h"
1216 *
1217 * void gui_open_passage_in_new_tab(gchar *verse_key)
1218 *
1219 * Description
1220 * opens the given verse in a new passage tab
1221 *
1222 * Return value
1223 * void
1224 */
gui_open_passage_in_new_tab(gchar * verse_key)1225 void gui_open_passage_in_new_tab(gchar *verse_key)
1226 {
1227 PASSAGE_TAB_INFO *pt;
1228
1229 if (stop_refresh)
1230 return;
1231
1232 if (!settings.browsing)
1233 return;
1234
1235 if ((pt = g_new0(PASSAGE_TAB_INFO, 1)) == NULL) {
1236 gui_generic_warning("Could not allocate a new tab");
1237 return;
1238 }
1239 pt->text_mod = g_strdup(settings.MainWindowModule);
1240 pt->commentary_mod = g_strdup(settings.CommWindowModule);
1241 pt->dictlex_mod = g_strdup(settings.DictWindowModule);
1242 pt->book_mod = g_strdup(settings.book_mod);
1243 pt->paratab = NULL;
1244
1245 pt->text_commentary_key = g_strdup(verse_key);
1246 pt->dictlex_key = g_strdup(settings.dictkey);
1247 pt->book_offset = g_strdup_printf("%ld", settings.book_offset);
1248 pt->comm_showing = settings.comm_showing;
1249
1250 if (cur_passage_tab && cur_passage_tab->showparallel) {
1251 pt->showtexts = 1;
1252 pt->showcomms = 1;
1253 pt->showdicts = 1;
1254 } else {
1255 pt->showtexts = settings.showtexts;
1256 pt->showcomms = settings.showcomms;
1257 pt->showdicts = settings.showdicts;
1258 }
1259
1260 pt->showpreview = settings.showpreview;
1261 pt->showparallel = FALSE;
1262
1263 pt->history_items = 0;
1264 pt->current_history_item = 0;
1265 pt->first_back_click = TRUE;
1266 main_add_tab_history_item((PASSAGE_TAB_INFO *)pt);
1267
1268 passage_list =
1269 g_list_append(passage_list, (PASSAGE_TAB_INFO *)pt);
1270 //set_current_tab(pt);
1271 notebook_main_add_page(pt);
1272
1273 gtk_notebook_set_current_page(GTK_NOTEBOOK(widgets.notebook_main),
1274 gtk_notebook_page_num(GTK_NOTEBOOK(widgets.notebook_main),
1275 pt->page_widget));
1276 }
1277
1278 /******************************************************************************
1279 * Name
1280 * gui_open_parallel_view_in_new_tab
1281 *
1282 * Synopsis
1283 * #include "tabbed_browser.h"
1284 *
1285 * void gui_open_parallel_view_in_new_tab(void)
1286 *
1287 * Description
1288 * opens the parallel view in a new tab
1289 *
1290 * Return value
1291 * void
1292 */
1293
gui_open_parallel_view_in_new_tab(void)1294 void gui_open_parallel_view_in_new_tab(void)
1295 {
1296 PASSAGE_TAB_INFO *pt;
1297
1298 if (stop_refresh)
1299 return;
1300
1301 if (!settings.browsing)
1302 return;
1303
1304 if ((pt = g_new0(PASSAGE_TAB_INFO, 1)) == NULL) {
1305 gui_generic_warning("Could not allocate a new tab");
1306 return;
1307 }
1308
1309 pt->showtexts = FALSE;
1310 pt->showpreview = TRUE;
1311 pt->showcomms = FALSE;
1312 pt->showdicts = FALSE;
1313 pt->showparallel = TRUE;
1314 pt->text_mod = g_strdup(settings.MainWindowModule);
1315 pt->commentary_mod = g_strdup(settings.CommWindowModule);
1316 pt->dictlex_mod = g_strdup(settings.DictWindowModule);
1317 pt->book_mod = g_strdup(settings.book_mod);
1318 pt->showbookeditor = FALSE;
1319 pt->comm_showing = FALSE;
1320
1321 pt->text_commentary_key = g_strdup(settings.currentverse);
1322 pt->dictlex_key = g_strdup(settings.dictkey);
1323 pt->book_offset = g_strdup_printf("%ld", settings.book_offset);
1324
1325 passage_list =
1326 g_list_append(passage_list, (PASSAGE_TAB_INFO *)pt);
1327 set_current_tab(pt);
1328 gui_recompute_view_menu_choices();
1329 notebook_main_add_page(pt);
1330 pt->paratab = gui_create_parallel_tab();
1331 gui_parallel_tab_sync((gchar *)settings.currentverse);
1332 /*gtk_box_pack_start(GTK_BOX(widgets.page), pt->paratab, TRUE, TRUE,
1333 0); */
1334 gtk_notebook_set_current_page(GTK_NOTEBOOK(widgets.notebook_main),
1335 gtk_notebook_page_num(GTK_NOTEBOOK(widgets.notebook_main),
1336 pt->page_widget));
1337 }
1338
1339 /******************************************************************************
1340 * Name
1341 * gui_open_module_in_new_tab
1342 *
1343 * Synopsis
1344 * #include "tabbed_browser.h"
1345 *
1346 * void gui_open_module_in_new_tab(gchar *verse_key)
1347 *
1348 * Description
1349 * opens the given module in a new passage tab
1350 *
1351 * Return value
1352 * void
1353 */
1354
gui_open_module_in_new_tab(gchar * module)1355 void gui_open_module_in_new_tab(gchar *module)
1356 {
1357 PASSAGE_TAB_INFO *pt;
1358 gint module_type;
1359
1360 if (stop_refresh)
1361 return;
1362
1363 if (!settings.browsing)
1364 return;
1365
1366 if ((pt = g_new0(PASSAGE_TAB_INFO, 1)) == NULL) {
1367 gui_generic_warning("Could not allocate a new tab");
1368 return;
1369 }
1370 module_type = main_get_mod_type(module);
1371
1372 pt->showtexts = FALSE;
1373 pt->showpreview = settings.showpreview;
1374 pt->showcomms = FALSE;
1375 pt->showdicts = FALSE;
1376 pt->showparallel = FALSE;
1377 pt->paratab = NULL;
1378
1379 switch (module_type) {
1380 case -1:
1381 return;
1382 break;
1383 case TEXT_TYPE:
1384 pt->text_mod = g_strdup(module);
1385 pt->commentary_mod = g_strdup(settings.CommWindowModule);
1386 pt->dictlex_mod = g_strdup(settings.DictWindowModule);
1387 pt->book_mod = g_strdup(settings.book_mod);
1388 pt->showtexts = TRUE;
1389 break;
1390 case COMMENTARY_TYPE:
1391 pt->text_mod = g_strdup(settings.MainWindowModule);
1392 pt->commentary_mod = g_strdup(module);
1393 pt->dictlex_mod = g_strdup(settings.DictWindowModule);
1394 pt->book_mod = g_strdup(settings.book_mod);
1395 pt->showcomms = TRUE;
1396 pt->comm_showing = 1;
1397 break;
1398 case DICTIONARY_TYPE:
1399 pt->text_mod = g_strdup(settings.MainWindowModule);
1400 pt->commentary_mod = g_strdup(settings.CommWindowModule);
1401 pt->dictlex_mod = g_strdup(module);
1402 pt->book_mod = g_strdup(settings.book_mod);
1403 pt->showdicts = TRUE;
1404 break;
1405 case BOOK_TYPE:
1406 pt->text_mod = g_strdup(settings.MainWindowModule);
1407 pt->commentary_mod = g_strdup(settings.CommWindowModule);
1408 pt->dictlex_mod = g_strdup(settings.DictWindowModule);
1409 pt->book_mod = g_strdup(module);
1410 pt->showcomms = TRUE;
1411 pt->comm_showing = 0;
1412 break;
1413 case PRAYERLIST_TYPE:
1414 pt->text_mod = g_strdup(settings.MainWindowModule);
1415 pt->commentary_mod = g_strdup(settings.CommWindowModule);
1416 pt->dictlex_mod = g_strdup(settings.DictWindowModule);
1417 pt->book_mod = g_strdup(module);
1418 pt->showcomms = TRUE;
1419 pt->comm_showing = 0;
1420 break;
1421 }
1422
1423 pt->text_commentary_key = g_strdup(settings.currentverse);
1424 pt->dictlex_key = g_strdup(settings.dictkey);
1425 pt->book_offset = g_strdup_printf("%ld", settings.book_offset);
1426
1427 passage_list =
1428 g_list_append(passage_list, (PASSAGE_TAB_INFO *)pt);
1429 //set_current_tab(pt);
1430 notebook_main_add_page(pt);
1431
1432 gtk_notebook_set_current_page(GTK_NOTEBOOK(widgets.notebook_main),
1433 gtk_notebook_page_num(GTK_NOTEBOOK(widgets.notebook_main),
1434 pt->page_widget));
1435 }
1436
1437 /******************************************************************************
1438 * Name
1439 * gui_close_all_tabs
1440 *
1441 * Synopsis
1442 * #include "tabbed_browser.h"
1443 *
1444 * void gui_close_all_tabs(void)
1445 *
1446 * Description
1447 * called from preferences dialog when disable browsing is chosen
1448 *
1449 * Return value
1450 * void
1451 */
1452
gui_close_all_tabs(void)1453 void gui_close_all_tabs(void)
1454 {
1455 gint i;
1456 gint number_of_pages =
1457 gtk_notebook_get_n_pages(GTK_NOTEBOOK(widgets.notebook_main));
1458
1459 if (stop_refresh)
1460 return;
1461
1462 for (i = number_of_pages - 1; i > -1; i--) {
1463 PASSAGE_TAB_INFO *pt =
1464 (PASSAGE_TAB_INFO *)g_list_nth_data(passage_list,
1465 (guint)i);
1466 passage_list = g_list_remove(passage_list, pt);
1467 g_free(pt->text_mod);
1468 g_free(pt->commentary_mod);
1469 g_free(pt->dictlex_mod);
1470 g_free(pt->book_mod);
1471 g_free(pt->text_commentary_key);
1472 g_free(pt->dictlex_key);
1473 g_free(pt->book_offset);
1474 g_free(pt);
1475 gtk_notebook_remove_page(GTK_NOTEBOOK(widgets.notebook_main), i);
1476 }
1477
1478 g_list_free(passage_list);
1479 passage_list = NULL;
1480 cur_passage_tab = NULL;
1481 // gui_set_text_frame_label(cur_t);
1482 }
1483
1484 /******************************************************************************
1485 * Name
1486 * gui_close_passage_tab
1487 *
1488 * Synopsis
1489 * #include "tabbed_browser.h"
1490 *
1491 * void gui_close_passage_tab(gint pagenum)
1492 *
1493 * Description
1494 * closes the given passage tab or the current one if pagenum = -1
1495 *
1496 * Return value
1497 * void
1498 */
gui_close_passage_tab(gint pagenum)1499 void gui_close_passage_tab(gint pagenum)
1500 {
1501 if (stop_refresh)
1502 return;
1503
1504 if (-1 == pagenum)
1505 pagenum =
1506 gtk_notebook_get_current_page(GTK_NOTEBOOK(widgets.notebook_main));
1507 if (1 ==
1508 gtk_notebook_get_n_pages(GTK_NOTEBOOK(widgets.notebook_main)))
1509 return;
1510 PASSAGE_TAB_INFO *pt =
1511 (PASSAGE_TAB_INFO *)g_list_nth_data(passage_list,
1512 (guint)pagenum);
1513 if (pt->showparallel || (2 <=
1514 gtk_notebook_get_n_pages(GTK_NOTEBOOK(widgets.notebook_main)))) {
1515 // (surely this is always true!?)
1516
1517 if (pagenum > 0) {
1518 gtk_notebook_set_current_page(GTK_NOTEBOOK(widgets.notebook_main), 0);
1519 cur_passage_tab = (PASSAGE_TAB_INFO *)
1520 g_list_nth_data(passage_list, (guint)0);
1521 }
1522 }
1523
1524 stop_refresh = TRUE;
1525 sync_windows();
1526 stop_refresh = FALSE;
1527
1528 passage_list = g_list_remove(passage_list, pt);
1529 if (pt->text_mod)
1530 g_free(pt->text_mod);
1531 if (pt->commentary_mod)
1532 g_free(pt->commentary_mod);
1533 if (pt->dictlex_mod)
1534 g_free(pt->dictlex_mod);
1535 if (pt->book_mod)
1536 g_free(pt->book_mod);
1537 if (pt->text_commentary_key)
1538 g_free(pt->text_commentary_key);
1539 if (pt->dictlex_key)
1540 g_free(pt->dictlex_key);
1541 if (pt->book_offset)
1542 g_free(pt->book_offset);
1543 if (pt->showparallel) {
1544 gtk_widget_hide(pt->paratab);
1545 gui_destroy_parallel_tab();
1546 settings.showparatab = FALSE;
1547 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widgets.parallel_tab_item),
1548 settings.showparatab);
1549 }
1550 g_free(pt);
1551 //cur_passage_tab = NULL;
1552 removed_page = pagenum;
1553 gtk_notebook_remove_page(GTK_NOTEBOOK(widgets.notebook_main),
1554 pagenum);
1555 }
1556
on_notebook_main_new_tab_clicked(GtkButton * button,gpointer user_data)1557 void on_notebook_main_new_tab_clicked(GtkButton *button,
1558 gpointer user_data)
1559 {
1560 gui_open_passage_in_new_tab(settings.currentverse);
1561 }
1562
1563 /******************************************************************************
1564 * Name
1565 * gui_notebook_main_setup
1566 *
1567 * Synopsis
1568 * #include "tabbed_browser.h"
1569 *
1570 * void gui_notebook_main_setup(int tabs)
1571 *
1572 * Description
1573 * set up notebook for browsing multiple passages
1574 *
1575 * Return value
1576 * void
1577 */
gui_notebook_main_setup(int tabs,const char * tabsfile)1578 void gui_notebook_main_setup(int tabs, const char *tabsfile)
1579 {
1580 if (stop_refresh)
1581 return;
1582
1583 removed_page = 1;
1584 cur_passage_tab = NULL;
1585 passage_list = NULL;
1586
1587 gui_load_tabs(tabsfile ? tabsfile
1588 : (tabs ? default_tab_filename : no_tab_filename));
1589
1590 g_signal_connect(G_OBJECT(widgets.notebook_main),
1591 "switch-page",
1592 G_CALLBACK(gui_notebook_main_switch_page),
1593 &passage_list);
1594
1595 g_signal_connect(G_OBJECT(widgets.button_new_tab), "clicked",
1596 G_CALLBACK(on_notebook_main_new_tab_clicked),
1597 NULL);
1598
1599 //show the new tab button here instead of in main_window.c so it
1600 //doesn't get shown if !settings.browsing
1601 gtk_widget_show(widgets.button_new_tab);
1602 gui_notebook_main_switch_page(GTK_NOTEBOOK(widgets.notebook_main),
1603 NULL,
1604 settings.tab_page, &passage_list);
1605 }
1606
1607 /******************************************************************************
1608 * Name
1609 * gui_notebook_main_shutdown
1610 *
1611 * Synopsis
1612 * #include "tabbed_browser.h"
1613 *
1614 * void gui_notebook_main_shutdown(int tabs)
1615 *
1616 * Description
1617 * shut down main notebook and clean mem
1618 *
1619 * Return value
1620 * void
1621 */
gui_notebook_main_shutdown(int tabs)1622 void gui_notebook_main_shutdown(int tabs)
1623 {
1624 if (stop_refresh)
1625 return;
1626
1627 gui_save_tabs(tabs ? default_tab_filename : no_tab_filename);
1628 passage_list = g_list_first(passage_list);
1629 while (passage_list != NULL) {
1630 PASSAGE_TAB_INFO *pt =
1631 (PASSAGE_TAB_INFO *)passage_list->data;
1632 g_free(pt->text_mod);
1633 g_free(pt->commentary_mod);
1634 g_free(pt->dictlex_mod);
1635 g_free(pt->book_mod);
1636 g_free(pt->text_commentary_key);
1637 g_free(pt->dictlex_key);
1638 g_free(pt->book_offset);
1639 g_free((PASSAGE_TAB_INFO *)passage_list->data);
1640 passage_list = g_list_next(passage_list);
1641 }
1642 g_list_free(passage_list);
1643 cur_passage_tab = NULL;
1644 }
1645
gui_tab_set_showtexts(int show)1646 void gui_tab_set_showtexts(int show)
1647 {
1648 if (cur_passage_tab)
1649 cur_passage_tab->showtexts = show;
1650 }
1651
gui_tab_set_showpreview(int show)1652 void gui_tab_set_showpreview(int show)
1653 {
1654 if (cur_passage_tab)
1655 cur_passage_tab->showpreview = show;
1656 }
1657
gui_tab_set_showcomms(int show)1658 void gui_tab_set_showcomms(int show)
1659 {
1660 if (cur_passage_tab)
1661 cur_passage_tab->showcomms = show;
1662 }
1663
gui_tab_set_showdicts(int show)1664 void gui_tab_set_showdicts(int show)
1665 {
1666 if (cur_passage_tab)
1667 cur_passage_tab->showdicts = show;
1668 }
1669
_is_paratab_showing(void)1670 static int _is_paratab_showing(void)
1671 {
1672 if (settings.paratab_showing)
1673 return 1;
1674 return 0;
1675 }
1676
_tabs_on(void)1677 static void _tabs_on(void)
1678 {
1679 xml_set_value("Xiphos", "tabs", "browsing", "1");
1680 settings.browsing = TRUE;
1681 gui_close_all_tabs();
1682 gui_load_tabs(default_tab_filename);
1683 gtk_widget_show(widgets.hboxtb);
1684 gtk_widget_show(widgets.hpaned);
1685 }
1686
_tabs_off(void)1687 static void _tabs_off(void)
1688 {
1689 int page = _is_paratab_showing();
1690 xml_set_value("Xiphos", "tabs", "browsing", "0");
1691 gui_save_tabs(default_tab_filename);
1692 if (settings.showparatab) {
1693 gui_close_passage_tab(gtk_notebook_page_num(GTK_NOTEBOOK(widgets.notebook_main),
1694 widgets.parallel_tab));
1695 settings.showparatab = FALSE;
1696 }
1697 gui_close_all_tabs();
1698 settings.browsing = FALSE;
1699 gui_load_tabs(no_tab_filename);
1700 gtk_widget_hide(widgets.hboxtb);
1701 gtk_notebook_set_current_page(GTK_NOTEBOOK(widgets.notebook_bible_parallel),
1702 page);
1703 }
1704
gui_tabs_on_off(int on)1705 void gui_tabs_on_off(int on)
1706 {
1707 if (on)
1708 _tabs_on();
1709 else
1710 _tabs_off();
1711 }
1712