1 /*
2  * Xiphos Bible Study Tool
3  * main_window.c - main window gui
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 <gtk/gtk.h>
27 
28 #include "xiphos_html/xiphos_html.h"
29 #include "main/sword.h"
30 #include "main/settings.h"
31 #include "main/xml.h"
32 #include "main/search_dialog.h"
33 #include "main/url.hh"
34 #include "main/biblesync_glue.h"
35 
36 #include "biblesync/biblesync-version.hh"
37 
38 #include "gui/xiphos.h"
39 #include "gui/main_window.h"
40 #include "gui/main_menu.h"
41 #include "gui/sidebar.h"
42 #include "gui/utilities.h"
43 #include "gui/bibletext.h"
44 #include "gui/parallel_view.h"
45 #include "gui/commentary.h"
46 #include "gui/gbs.h"
47 #include "gui/dialog.h"
48 #include "gui/find_dialog.h"
49 #include "gui/dictlex.h"
50 #include "gui/search_dialog.h"
51 #include "gui/commentary_dialog.h"
52 #include "gui/bibletext_dialog.h"
53 #include "gui/bookmark_dialog.h"
54 #include "gui/search_dialog.h"
55 #include "gui/navbar_versekey.h"
56 #include "gui/tabbed_browser.h"
57 #include "gui/widgets.h"
58 #include "gui/tabbed_browser.h"
59 #include "gui/menu_popup.h"
60 #include "gui/preferences_dialog.h"
61 
62 #include "editor/slib-editor.h"
63 
64 #include "gui/debug_glib_null.h"
65 
66 /* X keyboard #definitions, to handle shortcuts */
67 /* we must define the categories of #definitions we need. */
68 #define XK_MISCELLANY
69 #define XK_LATIN1
70 #include <X11/keysymdef.h>
71 
72 WIDGETS widgets;
73 
74 extern gboolean shift_key_pressed;
75 
76 static GtkWidget *nav_toolbar;
77 static int main_window_created = FALSE;
78 
79 /******************************************************************************
80  * Name
81  *  gui_show_hide_texts
82  *
83  * Synopsis
84  *   #include "gui/main_window.h"
85  *
86  *   void gui_show_hide_texts(gboolean choice)
87  *
88  * Description
89  *    Show/hide bible texts
90  *
91  * Return value
92  *   void
93  */
94 
gui_show_hide_texts(gboolean choice)95 void gui_show_hide_texts(gboolean choice)
96 {
97 	settings.showtexts = choice;
98 	gui_tab_set_showtexts(choice);
99 	gui_set_tab_label(settings.currentverse, TRUE);
100 	if (choice == FALSE) {
101 		if (main_window_created)
102 			gtk_widget_hide(widgets.vpaned);
103 		xml_set_value("Xiphos", "misc", "showtexts", "0");
104 	} else {
105 		if (main_window_created) {
106 			gtk_widget_show(widgets.vpaned);
107 			gtk_widget_show(nav_toolbar);
108 		}
109 		xml_set_value("Xiphos", "misc", "showtexts", "1");
110 	}
111 	/*if (main_window_created)
112 	   gui_set_bible_comm_layout(); */
113 }
114 
115 /******************************************************************************
116  * Name
117  *  gui_show_hide_preview
118  *
119  * Synopsis
120  *   #include "gui/main_window.h"
121  *
122  *   void gui_show_hide_preview(gboolean choice)
123  *
124  * Description
125  *    Show/hide bible texts
126  *
127  * Return value
128  *   void
129  */
130 
gui_show_hide_preview(gboolean choice)131 void gui_show_hide_preview(gboolean choice)
132 {
133 	settings.showpreview = choice;
134 	gui_tab_set_showpreview(choice);
135 	if (choice == FALSE) {
136 		if (main_window_created)
137 			gtk_widget_hide(widgets.box_side_preview);
138 		gtk_widget_hide(widgets.vbox_previewer);
139 		xml_set_value("Xiphos", "misc", "showpreview", "0");
140 	} else {
141 		if (main_window_created) {
142 			if (settings.show_previewer_in_sidebar)
143 				gtk_widget_show(widgets.box_side_preview);
144 			else
145 				gtk_widget_show(widgets.vbox_previewer);
146 		}
147 
148 		xml_set_value("Xiphos", "misc", "showpreview", "1");
149 	}
150 }
151 
152 /******************************************************************************
153  * Name
154  *  gui_show_hide_comms
155  *
156  * Synopsis
157  *   #include "gui/main_window.h"
158  *
159  *   void gui_show_hide_comms(gboolean choice)
160  *
161  * Description
162  *    Show/hide Commentaries
163  *
164  * Return value
165  *   void
166  */
167 
gui_show_hide_comms(gboolean choice)168 void gui_show_hide_comms(gboolean choice)
169 {
170 	settings.showcomms = choice;
171 	gui_tab_set_showcomms(choice);
172 	gui_set_tab_label(settings.currentverse, TRUE);
173 	if (choice == FALSE) {
174 		if (main_window_created)
175 			gtk_widget_hide(widgets.notebook_comm_book);
176 		xml_set_value("Xiphos", "misc", "showcomms", "0");
177 	} else {
178 		if (main_window_created)
179 			gtk_widget_show(widgets.notebook_comm_book);
180 		xml_set_value("Xiphos", "misc", "showcomms", "1");
181 	}
182 	if (main_window_created)
183 		gui_set_bible_comm_layout();
184 }
185 
186 /******************************************************************************
187  * Name
188  *  gui_show_hide_dicts
189  *
190  * Synopsis
191  *   #include "gui/main_window.h"
192  *
193  *   void gui_show_hide_dicts(gboolean choice)
194  *
195  * Description
196  *    Show/hide Dictionaries-Lexicons
197  *
198  * Return value
199  *   void
200  */
201 
gui_show_hide_dicts(gboolean choice)202 void gui_show_hide_dicts(gboolean choice)
203 {
204 	settings.showdicts = choice;
205 	gui_tab_set_showdicts(choice);
206 	gui_set_tab_label(settings.currentverse, TRUE);
207 	if (choice == FALSE) {
208 		if (main_window_created)
209 			gtk_widget_hide(widgets.box_dict);
210 		xml_set_value("Xiphos", "misc", "showdicts", "0");
211 	} else {
212 		if (main_window_created)
213 			gtk_widget_show(widgets.box_dict);
214 		xml_set_value("Xiphos", "misc", "showdicts", "1");
215 	}
216 	if (main_window_created)
217 		gui_set_bible_comm_layout();
218 }
219 
220 /******************************************************************************
221  * Name
222  *  gui_set_bible_comm_layout
223  *
224  * Synopsis
225  *   #include "gui/main_window.h"
226  *
227  *   void gui_set_bible_comm_layout(void)
228  *
229  * Description
230  *
231  *
232  * Return value
233  *   void
234  */
235 
gui_set_bible_comm_layout(void)236 void gui_set_bible_comm_layout(void)
237 {
238 	gtk_paned_set_position(GTK_PANED(widgets.hpaned),
239 			       settings.biblepane_width);
240 	gtk_paned_set_position(GTK_PANED(widgets.vpaned),
241 			       settings.biblepane_height);
242 	gtk_paned_set_position(GTK_PANED(widgets.vpaned2),
243 			       settings.commpane_height);
244 
245 	if ((settings.showcomms == TRUE) || (settings.showdicts == TRUE)) {
246 		gtk_widget_show(widgets.vpaned2);
247 	}
248 
249 	gtk_paned_set_position(GTK_PANED(widgets.hpaned),
250 			       (settings.showtexts
251 				    ? settings.biblepane_width
252 				    : 0));
253 
254 	gtk_paned_set_position(GTK_PANED(widgets.vpaned2),
255 			       (settings.showcomms
256 				    ? settings.commpane_height
257 				    : 0));
258 
259 	gtk_paned_set_position(GTK_PANED(widgets.vpaned2),
260 			       (settings.showdicts
261 				    ? settings.commpane_height
262 				    : settings.gs_height));
263 
264 	if ((settings.showcomms == FALSE) && (settings.showdicts == FALSE)) {
265 		gtk_widget_hide(widgets.vpaned2);
266 		gtk_paned_set_position(GTK_PANED(widgets.hpaned),
267 				       settings.gs_width);
268 	}
269 
270 	if ((settings.showcomms == TRUE) || (settings.showdicts == TRUE)) {
271 		gtk_paned_set_position(GTK_PANED(widgets.hpaned),
272 				       settings.biblepane_width);
273 	}
274 	if (((settings.showcomms == FALSE) && (settings.showtexts == FALSE)) || ((settings.comm_showing == FALSE) && (settings.showtexts == FALSE)))
275 		gtk_widget_hide(nav_toolbar);
276 	else
277 		gtk_widget_show(nav_toolbar);
278 
279 	gtk_notebook_set_current_page(GTK_NOTEBOOK(widgets.notebook_comm_book),
280 				      (settings.comm_showing ? 0 : 1));
281 }
282 
283 /******************************************************************************
284  * Name
285  *  gui_change_window_title
286  *
287  * Synopsis
288  *   #include "gui/main_window.h"
289  *
290  *   void gui_change_window_title(gchar * module_name)
291  *
292  * Description
293  *
294  *
295  * Return value
296  *   void
297  */
298 
gui_change_window_title(gchar * module_name)299 void gui_change_window_title(gchar *module_name)
300 {
301 	gchar *title;
302 
303 	if (cur_passage_tab) {
304 		/* borrowed from tabbed_browser.c:pick_tab_label() */
305 		/* echo the current tab's module (full name) in title bar */
306 		if (cur_passage_tab->showtexts || cur_passage_tab->comm_showing) {
307 			title =
308 			    (cur_passage_tab->showtexts ? cur_passage_tab->text_mod : (cur_passage_tab->commentary_mod ? cur_passage_tab->commentary_mod : "[no commentary]"));
309 		} else {
310 			title = (cur_passage_tab->showcomms
311 				     ? (cur_passage_tab->book_mod
312 					    ? cur_passage_tab->book_mod
313 					    : "[no book]")
314 				     : (cur_passage_tab->dictlex_mod
315 					    ? cur_passage_tab->dictlex_mod
316 					    : "[no dict]"));
317 		}
318 	} else
319 		title = module_name;
320 
321 	/*
322 	 * set program title to current module name
323 	 */
324 	title = g_strdup(main_get_module_description(title));
325 	if (!title)
326 		title =
327 		    g_strdup(main_get_module_description(settings.MainWindowModule));
328 	title =
329 	    g_strdup_printf("%s - %s", (title ? title : "[no title]"),
330 			    settings.program_title);
331 	gtk_window_set_title(GTK_WINDOW(widgets.app), title);
332 	g_free(title);
333 }
334 
delete_event(GtkWidget * widget,GdkEvent * event,gpointer user_data)335 static gboolean delete_event(GtkWidget *widget,
336 			     GdkEvent *event, gpointer user_data)
337 {
338 	on_quit_activate(NULL, NULL);
339 	return TRUE;
340 }
341 
342 /******************************************************************************
343  * Name
344  *   on_epaned_button_release_event
345  *
346  * Synopsis
347  *   #include "gui/main_window.h"
348  *
349  *   gboolean on_epaned_button_release_event(GtkWidget * widget,
350  *			GdkEventButton * event, gpointer user_data)
351  *
352  * Description
353  *    get and store pane sizes
354  *
355  * Return value
356  *   gboolean
357  */
358 
epaned_button_release_event(GtkWidget * widget,GdkEventButton * event,gpointer user_data)359 static gboolean epaned_button_release_event(GtkWidget *widget,
360 					    GdkEventButton *event,
361 					    gpointer user_data)
362 {
363 	gint panesize;
364 	gchar layout[80];
365 
366 	panesize = gtk_paned_get_position(GTK_PANED(widget));
367 
368 	if (panesize > 15) {
369 		if (!strcmp((gchar *)user_data, "epaned")) {
370 			settings.sidebar_width = panesize;
371 			sprintf(layout, "%d", settings.sidebar_width);
372 			xml_set_value("Xiphos", "layout",
373 				      "shortcutbar", layout);
374 		}
375 		if (!strcmp((gchar *)user_data, "vpaned")) {
376 			settings.biblepane_height = panesize;
377 			sprintf(layout, "%d", settings.biblepane_height);
378 			xml_set_value("Xiphos", "layout",
379 				      "bibleheight", layout);
380 		}
381 		if (!strcmp((gchar *)user_data, "vpaned2")) {
382 			settings.commpane_height = panesize;
383 			sprintf(layout, "%d", settings.commpane_height);
384 			xml_set_value("Xiphos", "layout",
385 				      "commentaryheight", layout);
386 		}
387 		if (!strcmp((gchar *)user_data, "hpaned1")) {
388 			settings.biblepane_width = panesize;
389 			sprintf(layout, "%d", settings.biblepane_width);
390 			xml_set_value("Xiphos", "layout",
391 				      "textpane", layout);
392 		}
393 		return FALSE;
394 	}
395 	return TRUE;
396 }
397 
398 /******************************************************************************
399  * Name
400  *   final_pane_sizes
401  *
402  * Synopsis
403  *   #include "gui/main_window.h"
404  *
405  *   void final_pane_sizes()
406  *
407  * Description
408  *   on quit, make a last query for pane sizes.
409  *   this is needed because e.g. "maximize window" in the title bar does
410  *   not call on_epaned_button_release_event for each newly-modified pane.
411  *
412  * Return value
413  *   void
414  */
415 
final_pane_sizes()416 void final_pane_sizes()
417 {
418 	epaned_button_release_event(GTK_WIDGET(widgets.epaned), NULL,
419 				    (gchar *)"epaned");
420 	epaned_button_release_event(GTK_WIDGET(widgets.vpaned), NULL,
421 				    (gchar *)"vpaned");
422 	epaned_button_release_event(GTK_WIDGET(widgets.vpaned2), NULL,
423 				    (gchar *)"vpaned2");
424 	epaned_button_release_event(GTK_WIDGET(widgets.hpaned), NULL,
425 				    (gchar *)"hpaned1");
426 }
427 
428 /******************************************************************************
429  * Name
430  *   on_configure_event
431  *
432  * Synopsis
433  *   #include "gui/main_window.h"
434  *
435  *   gboolean on_configure_event(GtkWidget * widget,
436  *				   GdkEventConfigure * event,
437  *				   gpointer user_data)
438  *
439  * Description
440  *   remember placement+size of main window.
441  *
442  * Return value
443  *   gboolean
444  */
445 
on_configure_event(GtkWidget * widget,GdkEventConfigure * event,gpointer user_data)446 static gboolean on_configure_event(GtkWidget *widget,
447 				   GdkEventConfigure *event,
448 				   gpointer user_data)
449 {
450 	gchar layout[80];
451 	gint x;
452 	gint y;
453 
454 	gdk_window_get_root_origin(gtk_widget_get_window(widgets.app), &x, &y);
455 
456 	settings.gs_width = event->width;
457 	settings.gs_height = event->height;
458 	settings.app_x = x;
459 	settings.app_y = y;
460 
461 #if GTK_CHECK_VERSION(3, 12, 0)
462 	sprintf(layout, "%d", gtk_window_is_maximized(GTK_WINDOW(widgets.app)));
463 	xml_set_value("Xiphos", "layout", "maximized", layout);
464 #endif
465 
466 	sprintf(layout, "%d", settings.gs_width);
467 	xml_set_value("Xiphos", "layout", "width", layout);
468 
469 	sprintf(layout, "%d", settings.gs_height);
470 	xml_set_value("Xiphos", "layout", "height", layout);
471 
472 	sprintf(layout, "%d", settings.app_x);
473 	xml_set_value("Xiphos", "layout", "app_x", layout);
474 
475 	sprintf(layout, "%d", settings.app_y);
476 	xml_set_value("Xiphos", "layout", "app_y", layout);
477 	xml_save_settings_doc(settings.fnconfigure);
478 
479 	return FALSE;
480 }
481 
on_notebook_bible_parallel_switch_page(GtkNotebook * notebook,gint page_num,GList ** tl)482 static void on_notebook_bible_parallel_switch_page(GtkNotebook *notebook,
483 						   gint page_num,
484 						   GList **tl)
485 {
486 }
487 
488 #ifdef USE_GTK_3
on_notebook_comm_book_switch_page(GtkNotebook * notebook,gpointer arg,gint page_num,GList ** tl)489 static void on_notebook_comm_book_switch_page(GtkNotebook *notebook,
490 					      gpointer arg,
491 					      gint page_num, GList **tl)
492 #else
493 static void on_notebook_comm_book_switch_page(GtkNotebook *notebook,
494 					      GtkNotebookPage *page,
495 					      gint page_num, GList **tl)
496 #endif
497 {
498 	gchar *url = NULL;
499 
500 	if (page_num == 0) {
501 		settings.comm_showing = TRUE;
502 		gtk_widget_show(nav_toolbar);
503 	} else {
504 		settings.comm_showing = FALSE;
505 		if (!settings.showtexts)
506 			gtk_widget_hide(nav_toolbar);
507 	}
508 
509 	gui_update_tab_struct(NULL,
510 			      settings.CommWindowModule,
511 			      NULL,
512 			      NULL,
513 			      NULL,
514 			      NULL,
515 			      settings.comm_showing,
516 			      settings.showtexts,
517 			      settings.showpreview,
518 			      settings.showcomms, settings.showdicts);
519 	if (settings.comm_showing)
520 		main_display_commentary(settings.CommWindowModule,
521 					settings.currentverse);
522 	else if (settings.book_mod && *settings.book_mod) {
523 		url = g_strdup_printf("sword://%s/%ld", settings.book_mod,
524 				      settings.book_offset);
525 		main_url_handler(url, TRUE);
526 		g_free(url);
527 	}
528 	gui_set_tab_label(settings.currentverse, TRUE);
529 }
530 
new_base_font_size(gboolean up)531 static void new_base_font_size(gboolean up)
532 {
533 	if (up) {
534 		settings.base_font_size++;
535 		if (settings.base_font_size > 5)
536 			settings.base_font_size = 5;
537 	} else {
538 		settings.base_font_size--;
539 		if (settings.base_font_size < -2)
540 			settings.base_font_size = -2;
541 	}
542 
543 	if (settings.base_font_size_str)
544 		g_free(settings.base_font_size_str);
545 	settings.base_font_size_str =
546 	    g_strdup_printf("%+d", settings.base_font_size);
547 
548 	xml_set_value("Xiphos", "fontsize", "basefontsize",
549 		      settings.base_font_size_str);
550 	redisplay_to_realign();
551 }
552 
553 /* temporary shorthand for too-common use */
554 #define sM settings.MainWindowModule
555 #define sC settings.CommWindowModule
556 #define sD settings.DictWindowModule
557 #define sB settings.book_mod
558 #define sV settings.currentverse
559 
kbd_toggle_option(gboolean cond,gchar * option)560 static void kbd_toggle_option(gboolean cond, gchar *option)
561 {
562 	gchar *msg;
563 
564 	if (cond) {
565 		int opt = !main_get_one_option(sM, option); // negate.
566 		main_save_module_options(sM, option, opt);
567 		gchar *url = g_strdup_printf("sword://%s/%s", sM, sV);
568 		main_url_handler(url, TRUE);
569 		g_free(url);
570 		msg =
571 		    g_strdup_printf("%s %s", option, (opt ? "on" : "off"));
572 		gui_set_statusbar(msg);
573 		g_free(msg);
574 	} else {
575 		msg = g_strdup_printf(_("Module has no support for %s."),
576 				      option);
577 		gui_generic_warning(msg);
578 		g_free(msg);
579 	}
580 }
581 
on_vbox1_key_press_event(GtkWidget * widget,GdkEventKey * event,gpointer user_data)582 static gboolean on_vbox1_key_press_event(GtkWidget *widget, GdkEventKey *event,
583 					 gpointer user_data)
584 {
585 	/* these are the mods we actually use for global keys, we always only check for these set */
586 	guint state =
587 	    event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK |
588 			    GDK_MOD1_MASK | GDK_MOD4_MASK);
589 
590 	switch (event->keyval) {
591 	case XK_Shift_L: /* shift keys - we need this for locking strongs (and */
592 	case XK_Shift_R: /* other stuff) while moving mouse to previewer */
593 		shift_key_pressed = TRUE;
594 	/* no break? hm... */
595 
596 	case XK_a:
597 	case XK_A:
598 		if (state == GDK_MOD1_MASK) { // Alt-A  annotation
599 			gui_mark_verse_dialog(sM, sV);
600 		} else if (state ==
601 			   (GDK_CONTROL_MASK | GDK_MOD1_MASK |
602 			    GDK_SHIFT_MASK))
603 			on_biblesync_kbd(3); // BSP audience
604 		break;
605 
606 	case XK_b:
607 	case XK_B:
608 		if (state == GDK_MOD1_MASK) { // Alt-B  bookmark
609 			gchar *label = g_strdup_printf("%s, %s", sV, sM);
610 			gui_bookmark_dialog(label, sM, sV);
611 			g_free(label);
612 		}
613 		break;
614 
615 	case XK_c:
616 	case XK_C:
617 		if (state == GDK_MOD1_MASK) { // Alt-C  commentary pane
618 			gtk_widget_grab_focus(navbar_versekey.lookup_entry);
619 			gtk_notebook_set_current_page(GTK_NOTEBOOK(widgets.notebook_comm_book),
620 						      0);
621 		}
622 #if BIBLESYNC_VERSION_NUM >= 2000000000
623 		else if (state == (GDK_CONTROL_MASK | GDK_MOD1_MASK | GDK_SHIFT_MASK)) {
624 			// BSP chat
625 			if (settings.bs_mode == 0)
626 				gui_generic_warning(_("BibleSync is not active."));
627 			else {
628 				GS_DIALOG *info = gui_new_dialog();
629 #if GTK_CHECK_VERSION(3, 10, 0)
630 				info->stock_icon = g_strdup("dialog-question");
631 #else
632 				info->stock_icon = g_strdup(GTK_STOCK_DIALOG_QUESTION);
633 #endif
634 				info->label_top = g_strdup(_("BibleSync Chat"));
635 				info->text1 = g_strdup(_("[say this]"));
636 				info->label1 = _("Comment:");
637 				info->ok = TRUE;
638 				info->cancel = TRUE;
639 
640 				gint test = gui_gs_dialog(info);
641 				if (test == GS_OK)
642 					biblesync_chat(info->text1);
643 
644 				g_free(info->label_top);
645 				g_free(info->text1);
646 				g_free(info);
647 			}
648 		}
649 #endif /* biblesync >= 2.0.0 */
650 		break;
651 
652 	case XK_d:
653 	case XK_D:
654 		if (state == GDK_MOD1_MASK) // Alt-D  dictionary entry
655 			gtk_widget_grab_focus(widgets.entry_dict);
656 		break;
657 
658 	case XK_f:
659 	case XK_F:
660 		if (state == GDK_CONTROL_MASK) { // Ctrl-F  find text
661 			if (settings.showtexts) {
662 				gui_find_dlg(widgets.html_text,
663 					     sM, FALSE, NULL);
664 			} else if (settings.showcomms) {
665 				if (settings.comm_showing) {
666 					gui_find_dlg(widgets.html_comm,
667 						     sC, FALSE, NULL);
668 				} else {
669 					gui_find_dlg(widgets.html_book,
670 						     sB, FALSE, NULL);
671 				}
672 			} else if (settings.showdicts) {
673 				gui_find_dlg(widgets.html_dict,
674 					     sD, FALSE, NULL);
675 			} else
676 				gui_generic_warning(_("Xiphos: No windows."));
677 		}
678 		break;
679 
680 	case XK_g:
681 	case XK_G:
682 		if (state == GDK_MOD1_MASK) { // Alt-G  genbook entry
683 			gtk_notebook_set_current_page(GTK_NOTEBOOK(widgets.notebook_comm_book),
684 						      1);
685 			gtk_widget_grab_focus(navbar_book.lookup_entry);
686 		}
687 		break;
688 
689 	case XK_j:
690 		if (state == 0) // J    "next verse"
691 			access_on_down_eventbox_button_release_event(VERSE_BUTTON);
692 		break;
693 
694 	case XK_k:
695 		if (state == 0) // K    "previous verse"
696 			access_on_up_eventbox_button_release_event(VERSE_BUTTON);
697 		break;
698 
699 	case XK_l:
700 	case XK_L:
701 		if (state == GDK_CONTROL_MASK) // Ctrl-L  verse entry
702 			gtk_widget_grab_focus(navbar_versekey.lookup_entry);
703 		else if (state == GDK_MOD1_MASK) // Alt-L  lemma
704 			kbd_toggle_option((main_check_for_global_option(sM, "ThMLLemma") ||
705 					   main_check_for_global_option(sM, "OSISLemma")),
706 					  "Lemmas");
707 		break;
708 
709 	case XK_m:
710 	case XK_M:
711 		if (state == GDK_MOD1_MASK) // Alt-M morph
712 		{
713 			kbd_toggle_option((main_check_for_global_option(sM, "GBFMorph") ||
714 					   main_check_for_global_option(sM, "ThMLMorph") ||
715 					   main_check_for_global_option(sM, "OSISMorph")),
716 					  "Morphological Tags");
717 		}
718 		break;
719 
720 	case XK_n:
721 	case XK_N:
722 		if (state == GDK_CONTROL_MASK) // Ctrl-N verse
723 			access_on_down_eventbox_button_release_event(VERSE_BUTTON);
724 		else if (state == 0) // n chapter
725 			access_on_down_eventbox_button_release_event(CHAPTER_BUTTON);
726 		else if (state == GDK_SHIFT_MASK) // N book
727 			access_on_down_eventbox_button_release_event(BOOK_BUTTON);
728 		else if (state == (GDK_CONTROL_MASK | GDK_MOD1_MASK | GDK_SHIFT_MASK)) {
729 			// BSP transient navigate
730 			if (biblesync_active_xmit_allowed()) {
731 				biblesync_prep_and_xmit(sM, sV);
732 				gui_set_statusbar(_("BibleSync: Current navigation sent."));
733 			} else {
734 				gui_generic_warning(_("BibleSync: Not speaking."));
735 			}
736 		}
737 		break;
738 
739 	case XK_o:
740 	case XK_O:
741 		if (state ==
742 		    (GDK_CONTROL_MASK | GDK_MOD1_MASK | GDK_SHIFT_MASK))
743 			on_biblesync_kbd(0); // BSP off
744 		break;
745 
746 	case XK_p:
747 	case XK_P:
748 		if (state == GDK_CONTROL_MASK) // Ctrl-P verse
749 			access_on_up_eventbox_button_release_event(VERSE_BUTTON);
750 		else if (state == 0) // p chapter
751 			access_on_up_eventbox_button_release_event(CHAPTER_BUTTON);
752 		else if (state == GDK_SHIFT_MASK) // P book
753 			access_on_up_eventbox_button_release_event(BOOK_BUTTON);
754 		else if (state == GDK_MOD1_MASK) // Alt-P  parallel detach
755 			on_undockInt_activate(NULL);
756 		else if (state ==
757 			 (GDK_CONTROL_MASK | GDK_MOD1_MASK |
758 			  GDK_SHIFT_MASK))
759 			on_biblesync_kbd(1); // BSP personal
760 		break;
761 
762 	case XK_q:
763 	case XK_Q:
764 		if (state == GDK_CONTROL_MASK) // Ctrl-Q quit
765 			delete_event(NULL, NULL, NULL);
766 		break;
767 
768 	case XK_r:
769 	case XK_R:
770 		if (state == GDK_MOD1_MASK) // Alt-R red words
771 		{
772 			kbd_toggle_option(((main_check_for_global_option(sM, "GBFRedLetterWords")) ||
773 					   (main_check_for_global_option(sM, "OSISRedLetterWords"))),
774 					  "Words of Christ in Red");
775 		}
776 		break;
777 
778 	case XK_s:
779 	case XK_S:
780 		if (state == GDK_MOD1_MASK) // Alt-S strong's
781 		{
782 			kbd_toggle_option(((main_check_for_global_option(sM, "GBFStrongs")) ||
783 					   (main_check_for_global_option(sM, "ThMLStrongs")) ||
784 					   (main_check_for_global_option(sM, "OSISStrongs"))),
785 					  "Strong's Numbers");
786 		} else if (state ==
787 			   (GDK_CONTROL_MASK | GDK_MOD1_MASK |
788 			    GDK_SHIFT_MASK))
789 			on_biblesync_kbd(2); // BSP speaker
790 		break;
791 
792 	case XK_t:
793 	case XK_T:
794 		if (state == GDK_CONTROL_MASK) // Ctrl-T open a new tab
795 			on_notebook_main_new_tab_clicked(NULL, NULL);
796 		else if (state == GDK_MOD1_MASK) // Alt-T transliteration
797 			kbd_toggle_option(true, "Transliteration");
798 		break;
799 
800 	case XK_z:
801 	case XK_Z:
802 		if (state == GDK_MOD1_MASK) // Alt-Z  open personal commentary
803 			access_to_edit_percomm();
804 		break;
805 
806 	case XK_plus: // Ctrl-Plus  Increase base font size
807 		if (state == (GDK_CONTROL_MASK | GDK_SHIFT_MASK))
808 			new_base_font_size(TRUE);
809 		break;
810 
811 	case XK_minus: // Ctrl-Minus  Decrease base font size
812 		if (state == GDK_CONTROL_MASK)
813 			new_base_font_size(FALSE);
814 		break;
815 
816 	case XK_0: // Ctrl-0 (zero)  Neutralize base font size.
817 		if (state == GDK_CONTROL_MASK) {
818 			settings.base_font_size = 1;
819 			new_base_font_size(FALSE);
820 		}
821 		break;
822 
823 	// ctrl-DIGIT [1-9] selects DIGIT-th tab.
824 	case XK_1:
825 	case XK_2:
826 	case XK_3:
827 	case XK_4:
828 	case XK_5:
829 	case XK_6:
830 	case XK_7:
831 	case XK_8:
832 	case XK_9:
833 		if (state == GDK_CONTROL_MASK)
834 			gui_select_nth_tab((event->keyval - XK_0) - 1); /* 0-based list */
835 
836 	case XK_F1: // F1 help
837 		if (state == 0)
838 			on_help_contents_activate(NULL, NULL);
839 		break;
840 
841 	case XK_F2: // F2 preferences
842 		if (state == 0)
843 			on_preferences_activate(NULL, NULL);
844 		break;
845 
846 	case XK_F3: // F3 search
847 		if (state == 0)
848 			main_open_search_dialog();
849 		else if (state == GDK_CONTROL_MASK)
850 			gtk_notebook_set_current_page(GTK_NOTEBOOK(widgets.notebook_sidebar),
851 						      2);
852 		break;
853 
854 	case XK_F4: // F4 module manager
855 		if (state == 0)
856 			on_module_manager_activate(NULL, NULL);
857 		else if (state == GDK_CONTROL_MASK)
858 			gui_close_passage_tab(gtk_notebook_page_num(GTK_NOTEBOOK(widgets.notebook_main),
859 								    ((PASSAGE_TAB_INFO *)
860 								     cur_passage_tab)->page_widget));
861 		break;
862 
863 	case XK_F10: // Shift-F10 bible module right click
864 		if (state == GDK_SHIFT_MASK)
865 			gui_menu_popup(NULL, sM, NULL);
866 		/* FIXME: needs the html widget as first pram */
867 		break;
868 
869 	case XK_F11: // F11 open current bible in separate window, maximized.
870 		if (state == 0)
871 			main_dialogs_open(sM, NULL, TRUE);
872 		break;
873 	}
874 	XI_message(("on_vbox1_key_press_event\nkeycode: %d, keysym: %0x, state: %d",
875 		    event->hardware_keycode, event->keyval, state));
876 	return FALSE;
877 }
878 
on_vbox1_key_release_event(GtkWidget * widget,GdkEventKey * event,gpointer user_data)879 static gboolean on_vbox1_key_release_event(GtkWidget *widget,
880 					   GdkEventKey *event,
881 					   gpointer user_data)
882 {
883 	switch (event->keyval) {
884 	case XK_Shift_L:
885 	case XK_Shift_R:
886 		shift_key_pressed = FALSE;
887 		break;
888 	}
889 	return FALSE;
890 }
891 
892 /******************************************************************************
893  * Name
894  *   create_mainwindow
895  *
896  * Synopsis
897  *   #include "gui/main_window.h"
898  *
899  *   void create_mainwindow(void)
900  *
901  * Description
902  *    create xiphos gui
903  *
904  * Return value
905  *   void
906  */
907 
create_mainwindow(void)908 void create_mainwindow(void)
909 {
910 	char *imagename;
911 	GtkWidget *vbox_gs;
912 	GtkWidget *menu;
913 	GtkWidget *hbox25;
914 	GtkWidget *tab_button_icon;
915 	GtkWidget *label;
916 #ifndef USE_WEBKIT2
917 	GtkWidget *scrolledwindow;
918 #endif
919 	GtkWidget *box_book;
920 	GdkPixbuf *pixbuf;
921 	/*
922 	   GTK_SHADOW_NONE
923 	   GTK_SHADOW_IN
924 	   GTK_SHADOW_OUT
925 	   GTK_SHADOW_ETCHED_IN
926 	   GTK_SHADOW_ETCHED_OUT
927 	 */
928 	settings.shadow_type = GTK_SHADOW_IN;
929 
930 	XI_print(("%s xiphos-%s\n", "Starting", VERSION));
931 	XI_print(("%s\n\n", "Building Xiphos interface"));
932 
933 	widgets.studypad_dialog = NULL;
934 
935 	/* A rough scektch of the main window (widgets.app) and it's children
936 	 *                widgets.app
937 	 *                     |
938 	 *                  vbox_gs
939 	 *                     |
940 	 *                  +--|----+
941 	 *                  |       |
942 	 *                 menu   hbox25
943 	 *                           |
944 	 *                     widgets.epaned
945 	 *                         |
946 	 *                 widgets.vboxMain
947 	 *                 |              |
948 	 *           widgets.hboxtb   widgets.page
949 	 *                            |         |
950 	 *                     widgets.hpaned  nav_toolbar
951 	 *                     |            |
952 	 *              widgets.vpaned---+  +----------------------------widgets.vpaned2---------------+
953 	 *               |               |                                      |                      |
954 	 * widgets.vbox_previewer   widgets.vbox_text              widgets.notebook_comm_book   widgets.box_dict
955 	 *                               |                         |                       |
956 	 *                widgets.notebook_bible_parallel   widgets.box_comm            box_book
957 	 *                               |
958 	 *                     widgets.notebook_text
959 	 *
960 	 */
961 
962 	// The toplevel Xiphos window
963 	widgets.app = gtk_window_new(GTK_WINDOW_TOPLEVEL);
964 	gtk_window_set_title(GTK_WINDOW(widgets.app), _("Xiphos - Bible Study Software"));
965 	g_object_set_data(G_OBJECT(widgets.app), "widgets.app", widgets.app);
966 	gtk_window_set_default_size(GTK_WINDOW(widgets.app), 680, 425);
967 	gtk_widget_set_can_focus(widgets.app, 1);
968 	gtk_window_set_resizable(GTK_WINDOW(widgets.app), TRUE);
969 
970 	// The app icon.
971 	// FIXME:: This should be a big copy of the logo because GTK does the scaling (GTK 3.16?)
972 	imagename = image_locator("gs2-48x48.png");
973 	pixbuf = gdk_pixbuf_new_from_file(imagename, NULL);
974 	g_free(imagename);
975 	gtk_window_set_icon(GTK_WINDOW(widgets.app), pixbuf);
976 
977 	// The main box for our toplevel window.
978 	UI_VBOX(vbox_gs, FALSE, 0);
979 	gtk_widget_show(vbox_gs);
980 	gtk_container_add(GTK_CONTAINER(widgets.app), vbox_gs);
981 
982 	// Add the main menu.
983 	menu = gui_create_main_menu();
984 	gtk_box_pack_start(GTK_BOX(vbox_gs), menu, FALSE, TRUE, 0);
985 
986 	// Another box
987 	UI_HBOX(hbox25, FALSE, 0);
988 	gtk_widget_show(hbox25);
989 	gtk_box_pack_start(GTK_BOX(vbox_gs), hbox25, TRUE, TRUE, 0);
990 
991 	// widgets.epaned
992 	widgets.epaned = UI_HPANE();
993 	gtk_widget_show(widgets.epaned);
994 #if !GTK_CHECK_VERSION(3, 14, 0)
995 	gtk_container_set_border_width(GTK_CONTAINER(widgets.epaned), 4);
996 #endif
997 	gtk_box_pack_start(GTK_BOX(hbox25), widgets.epaned, TRUE, TRUE, 0);
998 	// Another box
999 	UI_VBOX(widgets.vboxMain, FALSE, 0);
1000 	gtk_widget_show(widgets.vboxMain);
1001 	gtk_paned_pack2(GTK_PANED(widgets.epaned), widgets.vboxMain, TRUE, TRUE);
1002 #if !GTK_CHECK_VERSION(3, 14, 0)
1003 	gtk_container_set_border_width(GTK_CONTAINER(widgets.vboxMain), 2);
1004 #endif
1005 
1006 	/*
1007 	 * Notebook to have separate passages opened at once the passages are not
1008 	 * actually open but are switched between similar to bookmarks
1009 	 */
1010 	UI_HBOX(widgets.hboxtb, FALSE, 0);
1011 	if (settings.browsing)
1012 		gtk_widget_show(widgets.hboxtb);
1013 	gtk_box_pack_start(GTK_BOX(widgets.vboxMain), widgets.hboxtb, FALSE, FALSE, 0);
1014 
1015 	widgets.button_new_tab = gtk_button_new();
1016 	// Don't show button here in case !settings.browsing
1017 
1018 #if GTK_CHECK_VERSION(3, 10, 0)
1019 	tab_button_icon = gtk_image_new_from_icon_name("tab-new-symbolic", GTK_ICON_SIZE_SMALL_TOOLBAR);
1020 #else
1021 	tab_button_icon = gtk_image_new_from_stock(GTK_STOCK_ADD, GTK_ICON_SIZE_SMALL_TOOLBAR);
1022 #endif
1023 
1024 	gtk_widget_show(tab_button_icon);
1025 	gtk_container_add(GTK_CONTAINER(widgets.button_new_tab), tab_button_icon);
1026 	gtk_button_set_relief(GTK_BUTTON(widgets.button_new_tab), GTK_RELIEF_NONE);
1027 	gtk_box_pack_start(GTK_BOX(widgets.hboxtb), widgets.button_new_tab, FALSE, FALSE, 0);
1028 	gtk_widget_set_tooltip_text(widgets.button_new_tab, _("Open a new tab"));
1029 
1030 	widgets.notebook_main = gtk_notebook_new();
1031 	gtk_widget_show(widgets.notebook_main);
1032 	gtk_box_pack_start(GTK_BOX(widgets.hboxtb), widgets.notebook_main, TRUE, TRUE, 0);
1033 	gtk_widget_set_size_request(widgets.notebook_main, -1, 25);
1034 	gtk_notebook_set_scrollable(GTK_NOTEBOOK(widgets.notebook_main), TRUE);
1035 	gtk_notebook_popup_enable(GTK_NOTEBOOK(widgets.notebook_main));
1036 	gtk_notebook_set_show_border(GTK_NOTEBOOK(widgets.notebook_main), FALSE);
1037 	// Main passage tabbed notebook end
1038 
1039 	// Another box
1040 	UI_VBOX(widgets.page, FALSE, 0);
1041 	gtk_widget_show(widgets.page);
1042 	gtk_box_pack_start(GTK_BOX(widgets.vboxMain), widgets.page, TRUE, TRUE, 0);
1043 
1044 	//nav toolbar
1045 	nav_toolbar = gui_navbar_versekey_new();
1046 	gtk_box_pack_start(GTK_BOX(widgets.page), nav_toolbar, FALSE, FALSE, 0);
1047 
1048 	// widgets.hpaned
1049 	widgets.hpaned = UI_HPANE();
1050 	gtk_widget_show(widgets.hpaned);
1051 	gtk_box_pack_start(GTK_BOX(widgets.page), widgets.hpaned, TRUE, TRUE, 0);
1052 
1053 	// widgets.vpaned
1054 	widgets.vpaned = UI_VPANE();
1055 	gtk_widget_show(widgets.vpaned);
1056 	gtk_widget_set_size_request(widgets.vpaned, 50, -1);
1057 	gtk_paned_pack1(GTK_PANED(widgets.hpaned), widgets.vpaned, TRUE, FALSE);
1058 
1059 	// widgets.vpaned2
1060 	widgets.vpaned2 = UI_VPANE();
1061 	gtk_widget_set_size_request(widgets.vpaned2, 50, -1);
1062 
1063 	// widgets.vbox_text
1064 	UI_VBOX(widgets.vbox_text, FALSE, 0);
1065 	gtk_widget_show(widgets.vbox_text);
1066 	gtk_paned_pack1(GTK_PANED(widgets.vpaned), widgets.vbox_text, TRUE, TRUE);
1067 
1068 	// Bible/parallel notebook
1069 	widgets.notebook_bible_parallel = gtk_notebook_new();
1070 	gtk_widget_show(widgets.notebook_bible_parallel);
1071 	gtk_box_pack_start(GTK_BOX(widgets.vbox_text), widgets.notebook_bible_parallel, TRUE, TRUE, 0);
1072 	gtk_notebook_set_tab_pos(GTK_NOTEBOOK(widgets.notebook_bible_parallel), GTK_POS_BOTTOM);
1073 	gtk_notebook_set_show_tabs(GTK_NOTEBOOK(widgets.notebook_bible_parallel), TRUE);
1074 	gtk_notebook_set_show_border(GTK_NOTEBOOK(widgets.notebook_bible_parallel), FALSE);
1075 	gtk_container_set_border_width(GTK_CONTAINER(widgets.notebook_bible_parallel), 1);
1076 
1077 	g_signal_connect(G_OBJECT(widgets.notebook_bible_parallel), "change-current-page", G_CALLBACK(on_notebook_bible_parallel_switch_page), NULL);
1078 
1079 	// Text notebook (The bible text show in the standard view)
1080 	widgets.notebook_text = gui_create_bible_pane();
1081 	gtk_container_add(GTK_CONTAINER(widgets.notebook_bible_parallel), widgets.notebook_text);
1082 
1083 	label = gtk_label_new(_("Standard View"));
1084 	gtk_widget_show(label);
1085 	gtk_notebook_set_tab_label(GTK_NOTEBOOK(widgets.notebook_bible_parallel), gtk_notebook_get_nth_page(GTK_NOTEBOOK(widgets.notebook_bible_parallel), 0), label);
1086 
1087 	// Another box (For the previewer?)
1088 	UI_VBOX(widgets.vbox_previewer, FALSE, 0);
1089 	gtk_widget_show(widgets.vbox_previewer);
1090 	gtk_paned_pack2(GTK_PANED(widgets.vpaned), widgets.vbox_previewer, TRUE, TRUE);
1091 	gtk_container_set_border_width(GTK_CONTAINER(widgets.vbox_previewer), 2);
1092 
1093 #ifndef USE_WEBKIT2
1094 	scrolledwindow = gtk_scrolled_window_new(NULL, NULL);
1095 	gtk_widget_show(scrolledwindow);
1096 	gtk_box_pack_start(GTK_BOX(widgets.vbox_previewer), scrolledwindow, TRUE, TRUE, 0);
1097 	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1098 	gtk_scrolled_window_set_shadow_type((GtkScrolledWindow *) scrolledwindow, settings.shadow_type);
1099 #endif
1100 	widgets.html_previewer_text = GTK_WIDGET(XIPHOS_HTML_NEW(NULL, FALSE, VIEWER_TYPE));
1101 	gtk_widget_show(widgets.html_previewer_text);
1102 #ifdef USE_WEBKIT2
1103 	gtk_box_pack_start(GTK_BOX(widgets.vbox_previewer), widgets.html_previewer_text, TRUE, TRUE, 0);
1104 #else
1105 	gtk_container_add(GTK_CONTAINER(scrolledwindow), widgets.html_previewer_text);
1106 #endif
1107 
1108 	// Commentary/book notebook
1109 	widgets.notebook_comm_book = gtk_notebook_new();
1110 	gtk_widget_show(widgets.notebook_comm_book);
1111 
1112 	gtk_paned_pack1(GTK_PANED(widgets.vpaned2), widgets.notebook_comm_book, TRUE, TRUE);
1113 	gtk_container_set_border_width(GTK_CONTAINER(widgets.notebook_comm_book), 1);
1114 
1115 	gtk_notebook_set_tab_pos(GTK_NOTEBOOK(widgets.notebook_comm_book), GTK_POS_BOTTOM);
1116 	gtk_notebook_set_show_tabs(GTK_NOTEBOOK(widgets.notebook_comm_book), TRUE);
1117 	gtk_notebook_set_show_border(GTK_NOTEBOOK(widgets.notebook_comm_book), FALSE);
1118 
1119 	// Commentary pane
1120 	widgets.box_comm = gui_create_commentary_pane();
1121 	gtk_container_add(GTK_CONTAINER(widgets.notebook_comm_book), widgets.box_comm);
1122 
1123 	label = gtk_label_new(_("Commentary View"));
1124 	gtk_widget_show(label);
1125 	gtk_notebook_set_tab_label(GTK_NOTEBOOK(widgets.notebook_comm_book), gtk_notebook_get_nth_page(GTK_NOTEBOOK(widgets.notebook_comm_book), 0), label);
1126 
1127 	// Book pane
1128 	box_book = gui_create_book_pane();
1129 	gtk_container_add(GTK_CONTAINER(widgets.notebook_comm_book), box_book);
1130 
1131 	label = gtk_label_new(_("Book View"));
1132 	gtk_widget_show(label);
1133 	gtk_notebook_set_tab_label(GTK_NOTEBOOK(widgets.notebook_comm_book), gtk_notebook_get_nth_page(GTK_NOTEBOOK(widgets.notebook_comm_book), 1), label);
1134 
1135 	// Dict/lex
1136 	widgets.box_dict = gui_create_dictionary_pane();
1137 	gtk_paned_pack2(GTK_PANED(widgets.vpaned2), widgets.box_dict, TRUE, TRUE);
1138 
1139 	// Statusbar
1140 	widgets.appbar = gtk_statusbar_new();
1141 
1142 #ifndef USE_GTK_3
1143 	gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(widgets.appbar), TRUE);
1144 #endif
1145 	gtk_box_pack_start(GTK_BOX(vbox_gs), widgets.appbar, FALSE, TRUE, 0);
1146 	gui_set_statusbar(_("Welcome to Xiphos"));
1147 
1148 	gtk_paned_pack2(GTK_PANED(widgets.hpaned), widgets.vpaned2, TRUE, FALSE);
1149 	gtk_widget_grab_focus(navbar_versekey.lookup_entry);
1150 
1151 	gtk_window_set_default_size((GtkWindow *)widgets.app, settings.gs_width, settings.gs_height);
1152 	gtk_widget_show_all(widgets.app);
1153 
1154 	if (settings.statusbar != 1)
1155 		gtk_widget_hide(widgets.appbar);
1156 
1157 	/* must connect signals *after* instantiating window above, */
1158 	/* immediately above, otherwise window creation induces */
1159 	/* configure_event, wiping out user's saved geometry specs. */
1160 	/* *important*: drain gtk event queue first (i.e. sync). */
1161 
1162 	sync_windows();
1163 	g_signal_connect((gpointer)vbox_gs, "key_press_event", G_CALLBACK(on_vbox1_key_press_event), NULL);
1164 	g_signal_connect((gpointer)vbox_gs, "key_release_event", G_CALLBACK(on_vbox1_key_release_event), NULL);
1165 
1166 	g_signal_connect(G_OBJECT(widgets.notebook_comm_book), "switch_page", G_CALLBACK(on_notebook_comm_book_switch_page), NULL);
1167 
1168 	g_signal_connect(G_OBJECT(widgets.app), "delete_event", G_CALLBACK(delete_event), NULL);
1169 
1170 	g_signal_connect((gpointer)widgets.app, "configure_event", G_CALLBACK(on_configure_event), NULL);
1171 	g_signal_connect(G_OBJECT(widgets.epaned), "button_release_event", G_CALLBACK(epaned_button_release_event), (gchar *)"epaned");
1172 	g_signal_connect(G_OBJECT(widgets.vpaned), "button_release_event", G_CALLBACK(epaned_button_release_event), (gchar *)"vpaned");
1173 	g_signal_connect(G_OBJECT(widgets.vpaned2), "button_release_event", G_CALLBACK(epaned_button_release_event), (gchar *)"vpaned2");
1174 	g_signal_connect(G_OBJECT(widgets.hpaned), "button_release_event", G_CALLBACK(epaned_button_release_event), (gchar *)"hpaned1");
1175 
1176 	main_window_created = TRUE;
1177 }
1178 
1179 /******************************************************************************
1180  * Name
1181  *   gui_show_main_window
1182  *
1183  * Synopsis
1184  *   #include "gui/main_window.h"
1185  *
1186  *   void gui_show_main_window(void)
1187  *
1188  * Description
1189  *    display the app after all is created
1190  *
1191  * Return value
1192  *   void
1193  */
1194 
gui_show_main_window(void)1195 void gui_show_main_window(void)
1196 {
1197 	gtk_widget_show(widgets.app);
1198 }
1199