1 
2 /*
3  * Osmo - a handy personal organizer
4  *
5  * Copyright (C) 2007 Tomasz Maka <pasp@users.sourceforge.net>
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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */
21 
22 #include "gui.h"
23 #include "about.h"
24 #include "i18n.h"
25 #include "utils.h"
26 #include "utils_gui.h"
27 #include "utils_date.h"
28 #include "calendar.h"
29 #include "calendar_notes.h"
30 #include "calendar_fullyear.h"
31 #include "calendar_widget.h"
32 #include "calendar_jumpto.h"
33 #include "calendar_calc.h"
34 #ifdef HAVE_LIBICAL
35 #include "calendar_ical.h"
36 #endif  /* HAVE_LIBICAL */
37 #include "calendar_utils.h"
38 #include "notes.h"
39 #include "notes_items.h"
40 #include "tasks.h"
41 #include "tasks_items.h"
42 #include "tasks_utils.h"
43 #include "notes_items.h"
44 #include "contacts.h"
45 #include "contacts_items.h"
46 #include "options_prefs.h"
47 #include "check_events.h"
48 #include "stock_icons.h"
49 #include "preferences_gui.h"
50 #include "calendar_preferences_gui.h"
51 #include "config.h"
52 
53 #ifndef WIN32
54 #include <glib-unix.h>
55 #endif /* WIN32 */
56 
57 struct  osmo_prefs              config;
58 /*------------------------------------------------------------------------------*/
59 
60 void
gui_quit_osmo_cb(GtkToolButton * toolbutton,gpointer data)61 gui_quit_osmo_cb(GtkToolButton *toolbutton, gpointer data) {
62     GUI *appGUI = (GUI *) data;
63     gui_quit_osmo(appGUI);
64 }
65 
66 /*------------------------------------------------------------------------------*/
67 void
gui_show_about_window_cb(GtkToolButton * toolbutton,gpointer data)68 gui_show_about_window_cb(GtkToolButton *toolbutton, gpointer data) {
69     GUI *appGUI = (GUI *) data;
70     GtkWidget *window = opt_create_about_window(appGUI);
71     gtk_widget_show(window);
72 }
73 
74 /*------------------------------------------------------------------------------*/
75 void
gui_save_data_and_run_command(gchar * command,GUI * appGUI)76 gui_save_data_and_run_command (gchar *command, GUI *appGUI) {
77     gui_save_all_data (appGUI);
78     utl_run_command (command, FALSE);
79 }
80 
81 /*------------------------------------------------------------------------------*/
82 
83 void
gui_save_all_data(GUI * appGUI)84 gui_save_all_data (GUI *appGUI) {
85 
86     cal_write_notes (appGUI);
87 #ifdef TASKS_ENABLED
88     store_task_columns_info (appGUI);
89     write_tasks_entries (appGUI);
90 #endif  /* TASKS_ENABLED */
91 #ifdef HAVE_LIBICAL
92     write_ical_entries (appGUI);
93     ics_calendar_refresh (appGUI);
94 #endif  /* HAVE_LIBICAL */
95 #ifdef CONTACTS_ENABLED
96     store_contact_columns_info (appGUI);
97     write_contacts_entries (appGUI);
98 #endif  /* CONTACTS_ENABLED */
99 #ifdef NOTES_ENABLED
100     store_note_columns_info (appGUI);
101     write_notes_entries (appGUI);
102 #endif  /* NOTES_ENABLED */
103     prefs_write_config (appGUI);
104 
105 }
106 
107 /*------------------------------------------------------------------------------*/
108 
109 void
gui_toggle_window_visibility(GUI * appGUI)110 gui_toggle_window_visibility (GUI *appGUI) {
111 
112     if (appGUI->no_tray == FALSE) {
113 
114         appGUI->window_visible = !appGUI->window_visible;
115 
116         if (appGUI->window_visible == TRUE) {
117             gtk_status_icon_set_from_icon_name (appGUI->osmo_trayicon, OSMO_STOCK_SYSTRAY_NORMAL);
118             gtk_window_set_default_size (GTK_WINDOW(appGUI->main_window),
119                                          config.window_size_x, config.window_size_y);
120             gtk_window_move (GTK_WINDOW (appGUI->main_window), config.window_x, config.window_y);
121             gtk_widget_show (appGUI->main_window);
122         } else {
123             if (appGUI->calendar_only == FALSE) {
124                 gui_save_all_data (appGUI);
125                 gtk_window_get_size (GTK_WINDOW(appGUI->main_window),
126                                     &config.window_size_x, &config.window_size_y);
127                 gdk_window_get_root_origin (gtk_widget_get_window(appGUI->main_window),
128                                     &config.window_x, &config.window_y);
129             }
130             gtk_widget_hide (appGUI->main_window);
131         }
132     }
133 }
134 
135 /*------------------------------------------------------------------------------*/
136 
137 void
gui_toggle_fullscreen(GUI * appGUI)138 gui_toggle_fullscreen (GUI *appGUI) {
139     if (config.fullscreen == FALSE) {
140         gtk_window_fullscreen (GTK_WINDOW(appGUI->main_window));
141         config.fullscreen = TRUE;
142     } else {
143         gtk_window_unfullscreen (GTK_WINDOW(appGUI->main_window));
144         config.fullscreen = FALSE;
145     }
146 }
147 
148 /*------------------------------------------------------------------------------*/
149 
150 void
gui_quit_osmo(GUI * appGUI)151 gui_quit_osmo (GUI *appGUI) {
152 
153 #ifdef NOTES_ENABLED
154     if (appGUI->nte->editor_active == TRUE) {
155         editor_close_cb (NULL, appGUI);
156     }
157 #endif  /* NOTES_ENABLED */
158 
159     if (appGUI->osmo_trayicon != NULL) {
160         gtk_status_icon_set_visible (appGUI->osmo_trayicon, FALSE);
161     }
162 
163     if (appGUI->calendar_only == FALSE) {
164         if (appGUI->current_tab == PAGE_CALENDAR
165 #ifdef TASKS_ENABLED
166             || appGUI->current_tab == PAGE_TASKS
167 #endif  /* TASKS ENABLED */
168 #if defined(NOTES_ENABLED) && defined(CONTACTS_ENABLED)
169             || appGUI->current_tab == PAGE_CONTACTS || appGUI->current_tab == PAGE_NOTES) {
170 #elif CONTACTS_ENABLED
171             || appGUI->current_tab == PAGE_CONTACTS) {
172 #else
173             ) {
174 #endif  /* NOTES_ENABLED && CONTACTS_ENABLED */
175             config.latest_tab = appGUI->current_tab;
176         }
177 
178 #ifdef CONTACTS_ENABLED
179         config.find_mode = gtk_combo_box_get_active (GTK_COMBO_BOX(appGUI->cnt->contacts_find_combobox));
180 #endif  /* CONTACTS_ENABLED */
181 
182 #ifdef TASKS_ENABLED
183         config.current_category_in_tasks = gtk_combo_box_get_active (GTK_COMBO_BOX(appGUI->tsk->cf_combobox));
184 #endif  /* TASKS_ENABLED */
185 
186 #ifdef NOTES_ENABLED
187         config.current_category_in_notes = gtk_combo_box_get_active (GTK_COMBO_BOX(appGUI->nte->cf_combobox));
188 #endif  /* NOTES_ENABLED */
189 
190         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON(appGUI->cal->notes_button), FALSE);
191 
192         if (appGUI->window_visible == TRUE) {
193             if (!config.fullscreen) {
194                 gtk_window_get_size (GTK_WINDOW(appGUI->main_window),
195                                     &config.window_size_x, &config.window_size_y);
196             }
197         }
198     }
199 
200     if (appGUI->window_visible == TRUE) {
201         gdk_window_get_root_origin (gtk_widget_get_window(appGUI->main_window),
202                             &config.window_x, &config.window_y);
203     }
204 
205     pango_font_description_free(appGUI->cal->fd_day_name_font);
206     pango_font_description_free(appGUI->cal->fd_cal_font);
207     pango_font_description_free(appGUI->cal->fd_notes_font);
208 
209     if (appGUI->calendar_only == FALSE) {
210         g_source_remove(appGUI->timer);
211         config.lastrun_date = utl_date_get_current_julian ();
212         config.lastrun_time = utl_time_get_current_seconds ();
213         gui_save_all_data (appGUI);
214 #ifdef HAVE_LIBNOTIFY
215 #ifdef TASKS_ENABLED
216         free_notifications_list (appGUI);
217 #endif  /* TASKS_ENABLED */
218 #endif  /* HAVE_LIBNOTIFY */
219         cal_free_notes_list (appGUI);
220     }
221 
222     utl_gui_url_remove_links (&appGUI->about_links_list, &appGUI->about_link_index);
223     gtk_main_quit ();
224 }
225 
226 /*------------------------------------------------------------------------------*/
227 
228 void
229 gui_window_close_cb (GtkWidget *widget, GdkEvent *event, gpointer user_data) {
230 
231     GUI *appGUI = (GUI *)user_data;
232 
233     if (config.enable_systray == TRUE && appGUI->no_tray == FALSE && appGUI->calendar_only == FALSE) {
234         gui_toggle_window_visibility (appGUI);
235     } else {
236         gui_quit_osmo (appGUI);
237     }
238 }
239 
240 /*------------------------------------------------------------------------------*/
241 
242 void
243 gui_activate_find_fields (GUI *appGUI) {
244 
245 #ifdef NOTES_ENABLED
246     if (appGUI->current_tab == PAGE_NOTES) {
247         gtk_widget_grab_focus (GTK_WIDGET(appGUI->nte->notes_find_entry));
248     }
249 #endif  /* NOTES_ENABLED */
250 
251 #ifdef TASKS_ENABLED
252     if (appGUI->current_tab == PAGE_TASKS) {
253         gtk_widget_grab_focus (GTK_WIDGET(appGUI->tsk->tasks_find_entry));
254     }
255 #endif  /* TASKS_ENABLED */
256 
257 #ifdef CONTACTS_ENABLED
258     if (appGUI->current_tab == PAGE_CONTACTS) {
259         gtk_widget_grab_focus (GTK_WIDGET(appGUI->cnt->contacts_find_entry));
260     }
261 #endif  /* CONTACTS_ENABLED */
262 
263 }
264 
265 /*------------------------------------------------------------------------------*/
266 
267 gint
268 get_first_active_page (GUI *appGUI) {
269 
270     if (!config.hide_calendar)
271         return PAGE_CALENDAR;
272 #ifdef TASKS_ENABLED
273     if (!config.hide_tasks)
274         return PAGE_TASKS;
275 #endif  /* TASKS_ENABLED */
276 #ifdef CONTACTS_ENABLED
277     if (!config.hide_contacts)
278         return PAGE_CONTACTS;
279 #endif  /* CONTACTS_ENABLED */
280 #ifdef NOTES_ENABLED
281     if (!config.hide_notes)
282         return PAGE_NOTES;
283 #endif  /* NOTES_ENABLED */
284 
285     return PAGE_CALENDAR;
286 }
287 
288 /*------------------------------------------------------------------------------*/
289 
290 void
291 set_visible_page (gint page, gboolean dir, GUI *appGUI) {
292 
293 gboolean flag;
294 gint n = 1;
295 
296     if (dir == FALSE) n = -1;
297 
298     page += n;
299     flag = TRUE;
300 
301     while (flag) {
302 
303         flag = FALSE;
304 
305         switch (page) {
306             case PAGE_CALENDAR:
307                 if (config.hide_calendar) {
308                     page += n;
309                     flag = TRUE;
310                 }
311                 break;
312 #ifdef TASKS_ENABLED
313             case PAGE_TASKS:
314                 if (config.hide_tasks) {
315                     page += n;
316                     flag = TRUE;
317                 }
318                 break;
319 #endif  /* TASKS_ENABLED */
320 #ifdef CONTACTS_ENABLED
321             case PAGE_CONTACTS:
322                 if (config.hide_contacts) {
323                     page += n;
324                     flag = TRUE;
325                 }
326                 break;
327 #endif  /* CONTACTS_ENABLED */
328 #ifdef NOTES_ENABLED
329             case PAGE_NOTES:
330                 if (config.hide_notes) {
331                     page += n;
332                     flag = TRUE;
333                 }
334                 break;
335 #endif  /* NOTES_ENABLED */
336         }
337     }
338 
339     if (dir == FALSE) {
340         appGUI->current_tab = (page < 0) ? appGUI->number_of_tabs-1:page;
341     } else {
342         appGUI->current_tab = (page == appGUI->number_of_tabs) ? get_first_active_page(appGUI):page;
343     }
344     gtk_notebook_set_current_page (GTK_NOTEBOOK (appGUI->notebook), appGUI->current_tab);
345 
346     gui_activate_find_fields (appGUI);
347 
348 }
349 
350 /*------------------------------------------------------------------------------*/
351 
352 static gint
353 get_visible_tabs (GUI *appGUI)
354 {
355     gint i = 0;
356 
357     if (!config.hide_calendar) i++;
358 #ifdef TASKS_ENABLED
359     if (!config.hide_tasks) i++;
360 #endif  /* TASKS_ENABLED */
361 #ifdef CONTACTS_ENABLED
362     if (!config.hide_contacts) i++;
363 #endif  /* CONTACTS_ENABLED */
364 #ifdef NOTES_ENABLED
365     if (!config.hide_notes) i++;
366 #endif  /* NOTES_ENABLED */
367 
368     return i;
369 }
370 
371 /*------------------------------------------------------------------------------*/
372 
373 static void
374 select_tab (gint tab, GUI *appGUI)
375 {
376     gint i, n = 0;
377 
378     if (tab >= get_visible_tabs (appGUI)) return;
379 
380     for (i = PAGE_CALENDAR; i < NUMBER_OF_TABS; i++) {
381 
382         if (i == PAGE_CALENDAR && !config.hide_calendar) n++;
383 #ifdef TASKS_ENABLED
384         if (i == PAGE_TASKS && !config.hide_tasks) n++;
385 #endif  /* TASKS_ENABLED */
386 #ifdef CONTACTS_ENABLED
387         if (i == PAGE_CONTACTS && !config.hide_contacts) n++;
388 #endif  /* CONTACTS_ENABLED */
389 #ifdef NOTES_ENABLED
390         if (i == PAGE_NOTES && !config.hide_notes) n++;
391 #endif  /* NOTES_ENABLED */
392 
393         if (n == tab + 1) {
394             gtk_notebook_set_current_page (GTK_NOTEBOOK (appGUI->notebook), i);
395             break;
396         }
397     }
398 
399     gui_activate_find_fields (appGUI);
400 }
401 
402 /*------------------------------------------------------------------------------*/
403 
404 void
405 key_counter_add (gint value, GUI *appGUI) {
406 
407 GtkWidget *dialog;
408 GtkWidget *image;
409 gchar *tmpbuff;
410 
411     appGUI->key_counter += value;
412 
413     if (appGUI->key_counter == 57) {
414         tmpbuff = g_strdup_printf("<span size='xx-large'><b>%d times!</b></span>", config.run_counter);
415 
416         dialog = gtk_message_dialog_new_with_markup(GTK_WINDOW(appGUI->main_window),
417                 GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL,
418                 GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, tmpbuff, NULL);
419         gtk_window_set_title (GTK_WINDOW(dialog), _("Counter"));
420         image = gtk_image_new_from_icon_name(OSMO_STOCK_INFO_HELP, GTK_ICON_SIZE_DIALOG);
421         gtk_widget_show (image);
422         gtk_message_dialog_set_image(GTK_MESSAGE_DIALOG(dialog), image);
423         gtk_widget_show (dialog);
424         gtk_dialog_run(GTK_DIALOG(dialog));
425         gtk_widget_destroy(dialog);
426         g_free(tmpbuff);
427     } else if (appGUI->key_counter == 41) {
428         appGUI->cal->datecal_bio = TRUE;
429     }
430 }
431 
432 /*------------------------------------------------------------------------------*/
433 
434 gint
435 key_press_cb (GtkWidget *widget, GdkEventKey *event, GUI *appGUI)
436 {
437     gint page;
438 
439     page = gtk_notebook_get_current_page (GTK_NOTEBOOK(appGUI->notebook));
440 
441     /************************************************************************/
442     /*** CALENDAR PAGE                                                    ***/
443     /************************************************************************/
444 
445     if(page == PAGE_CALENDAR) {
446 
447         if (!config.day_notes_visible) {
448 
449             switch (event->keyval) {
450                 case GDK_KEY_Left:
451                     calendar_btn_prev_day(appGUI);
452                     return TRUE;
453                 case GDK_KEY_Right:
454                     calendar_btn_next_day(appGUI);
455                     return TRUE;
456                 case GDK_KEY_Up:
457                     if (event->state & GDK_CONTROL_MASK) {  /* CTRL + Up */
458                         utl_gui_sw_vscrollbar_move_position (appGUI->cal->day_info_scrolledwindow, SW_MOVE_UP);
459                         return TRUE;
460                     } else {
461                         calendar_btn_prev_week(appGUI);
462                         return TRUE;
463                     }
464                     return FALSE;
465                 case GDK_KEY_Down:
466                     if (event->state & GDK_CONTROL_MASK) {  /* CTRL + Up */
467                         utl_gui_sw_vscrollbar_move_position (appGUI->cal->day_info_scrolledwindow, SW_MOVE_DOWN);
468                         return TRUE;
469                     } else {
470                         calendar_btn_next_week(appGUI);
471                         return TRUE;
472                     }
473                     return FALSE;
474                 case GDK_KEY_Home:
475                     calendar_btn_prev_year(appGUI);
476                     return TRUE;
477                 case GDK_KEY_End:
478                     calendar_btn_next_year(appGUI);
479                     return TRUE;
480                 case GDK_KEY_Return:
481                     if (appGUI->calendar_only == FALSE) {
482                         gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON(appGUI->cal->notes_button),
483                                                            !gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(appGUI->cal->notes_button)));
484                     }
485                     return TRUE;
486                 case GDK_KEY_space:
487                     if (event->state & GDK_CONTROL_MASK) {  /* CTRL + Space */
488                         config.enable_day_mark = !config.enable_day_mark;
489                         cal_refresh_marks (appGUI);
490                         cal_set_day_info (appGUI);
491                         update_aux_calendars (appGUI);
492                         return TRUE;
493                     } else {
494                         calendar_set_today (appGUI);
495                         return TRUE;
496                     }
497                 case GDK_KEY_Delete:
498                     if (appGUI->calendar_only == FALSE) {
499                         calendar_clear_text_cb (NULL, appGUI);
500                     }
501                     return TRUE;
502                 case GDK_KEY_g:
503                     calendar_create_jumpto_window (appGUI);
504                     return TRUE;
505                 case GDK_KEY_f:
506                     calendar_create_fullyear_window (appGUI);
507                     return TRUE;
508                 case GDK_KEY_c:
509                     calendar_create_color_selector_window (TRUE, appGUI);
510                     key_counter_add (13, appGUI);
511                     return TRUE;
512                 case GDK_KEY_d:
513                     calendar_create_calc_window (appGUI);
514                     return TRUE;
515                 case GDK_KEY_a:
516                     if (!config.gui_layout) {
517                         gtk_expander_set_expanded (GTK_EXPANDER (appGUI->cal->aux_cal_expander),
518                                                    !gtk_expander_get_expanded (GTK_EXPANDER (appGUI->cal->aux_cal_expander)));
519                     }
520                     key_counter_add (5, appGUI);
521                     return TRUE;
522                 case GDK_KEY_b:
523                     if (appGUI->calendar_only == FALSE) {
524                         cal_notes_browser (appGUI);
525                     }
526                     key_counter_add (11, appGUI);
527                     return TRUE;
528                 case GDK_KEY_i:
529                     key_counter_add (9, appGUI);
530                     return TRUE;
531                 case GDK_KEY_o:
532                     key_counter_add (21, appGUI);
533                     return TRUE;
534             }
535 
536         }
537 
538         switch (event->keyval) {
539 
540             case GDK_KEY_Escape:
541                 if (appGUI->calendar_only == FALSE) {
542                     if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(appGUI->cal->notes_button)) == FALSE) {
543                         if (config.enable_systray == TRUE && appGUI->no_tray == FALSE && appGUI->calendar_only == FALSE) {
544                             gui_toggle_window_visibility (appGUI);
545                         }
546                     } else {
547                         gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(appGUI->cal->notes_button), FALSE);
548                     }
549                 }
550                 return TRUE;
551             case GDK_KEY_Left:
552                 if (event->state & GDK_MOD1_MASK) {  /* ALT + Left */
553                     calendar_btn_prev_day(appGUI);
554                     return TRUE;
555                 }
556                 return FALSE;
557             case GDK_KEY_Right:
558                 if (event->state & GDK_MOD1_MASK) {  /* ALT + Right */
559                     calendar_btn_next_day(appGUI);
560                     return TRUE;
561                 }
562                 return FALSE;
563             case GDK_KEY_Up:
564                 if (event->state & GDK_MOD1_MASK) {  /* ALT + Up */
565                     calendar_btn_prev_week(appGUI);
566                     return TRUE;
567                 }
568                 return FALSE;
569             case GDK_KEY_Down:
570                 if (event->state & GDK_MOD1_MASK) {  /* ALT + Down */
571                     calendar_btn_next_week(appGUI);
572                     return TRUE;
573                 }
574                 return FALSE;
575             case GDK_KEY_b:
576                 if (event->state & GDK_CONTROL_MASK) {  /* CTRL + b */
577                     g_signal_emit_by_name(G_OBJECT(appGUI->cal->ta_bold_button), "clicked");
578                     return TRUE;
579                 }
580                 return FALSE;
581 
582             case GDK_KEY_i:
583                 if (event->state & GDK_CONTROL_MASK) {  /* CTRL + i */
584                     g_signal_emit_by_name(G_OBJECT(appGUI->cal->ta_italic_button), "clicked");
585                     return TRUE;
586                 }
587                 return FALSE;
588 
589             case GDK_KEY_m:
590                 if (event->state & GDK_CONTROL_MASK) {  /* CTRL + m */
591                     g_signal_emit_by_name(G_OBJECT(appGUI->cal->ta_highlight_button), "clicked");
592                     return TRUE;
593                 }
594                 return FALSE;
595 
596             case GDK_KEY_u:
597                 if (event->state & GDK_CONTROL_MASK) {  /* CTRL + u */
598                     g_signal_emit_by_name(G_OBJECT(appGUI->cal->ta_underline_button), "clicked");
599                     return TRUE;
600                 }
601                 return FALSE;
602 
603             case GDK_KEY_t:
604                 if (event->state & GDK_CONTROL_MASK) {  /* CTRL + t */
605                     g_signal_emit_by_name(G_OBJECT(appGUI->cal->ta_strikethrough_button), "clicked");
606                     return TRUE;
607                 }
608                 return FALSE;
609         }
610 
611     }
612 
613 #ifdef TASKS_ENABLED
614 
615     /************************************************************************/
616     /*** TASKS PAGE                                                        ***/
617     /************************************************************************/
618 
619     if(page == PAGE_TASKS) {
620 
621             switch (event->keyval) {
622 
623                 case GDK_KEY_Escape:
624                     if(gtk_widget_is_focus(appGUI->tsk->tasks_find_entry) == FALSE) {
625                         if (config.enable_systray == TRUE && appGUI->no_tray == FALSE && appGUI->calendar_only == FALSE) {
626                             gui_toggle_window_visibility (appGUI);
627                         }
628                     } else {
629                         if (strlen(gtk_entry_get_text(GTK_ENTRY(appGUI->tsk->tasks_find_entry)))) {
630                             gtk_entry_set_text(GTK_ENTRY(appGUI->tsk->tasks_find_entry), "");
631                         } else {
632                             if (config.enable_systray == TRUE && appGUI->no_tray == FALSE && appGUI->calendar_only == FALSE) {
633                                 gui_toggle_window_visibility (appGUI);
634                             }
635                         }
636                     }
637                     return TRUE;
638                 case GDK_KEY_Return:
639                     if(gtk_widget_is_focus(appGUI->tsk->tasks_find_entry) == FALSE) {
640                         if (event->state & GDK_CONTROL_MASK) {  /* CTRL + Enter */
641                             if (gtk_tree_selection_count_selected_rows (appGUI->tsk->tasks_list_selection) == 1) {
642                                 tasks_add_edit_dialog_show (TRUE, 0, utl_time_get_current_seconds (), appGUI);
643                                 return TRUE;
644                             }
645                         }
646                         return TRUE;
647                     } else {
648                         gtk_widget_grab_focus(GTK_WIDGET(appGUI->tsk->tasks_list));
649                         return TRUE;
650                     }
651                 case GDK_KEY_space:     /* don't use space key for marking task as done */
652                     if(gtk_widget_is_focus(appGUI->tsk->tasks_find_entry) == FALSE) {
653                         return TRUE;
654                     } else {
655                         return FALSE;
656                     }
657                 case GDK_KEY_h:
658                     if(gtk_widget_is_focus(appGUI->tsk->tasks_find_entry) == FALSE) {
659                         if (event->state & GDK_CONTROL_MASK) {  /* CTRL + h */
660                             config.hide_completed = !config.hide_completed;
661                             gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER(appGUI->tsk->tasks_filter));
662                         }
663                         return TRUE;
664                     }
665                     return FALSE;
666                 case GDK_KEY_Delete:
667                     if (gtk_widget_is_focus(appGUI->tsk->tasks_find_entry) == FALSE) {
668                         if (gtk_tree_selection_count_selected_rows(appGUI->tsk->tasks_list_selection) > 0) {
669                             tasks_remove_dialog_show(appGUI);
670                             return TRUE;
671                         }
672                     }
673                     return FALSE;
674                 case GDK_KEY_Insert:
675                     if(gtk_widget_is_focus(appGUI->tsk->tasks_find_entry) == FALSE) {
676                         tasks_add_edit_dialog_show (FALSE, 0, utl_time_get_current_seconds (), appGUI);
677                         return TRUE;
678                     }
679                     return FALSE;
680                 case GDK_KEY_Left:
681                     if(gtk_widget_is_focus(appGUI->tsk->tasks_find_entry) == FALSE) {
682                         if (appGUI->tsk->filter_index > 0) {
683                             appGUI->tsk->filter_index--;
684                             gtk_combo_box_set_active(GTK_COMBO_BOX(appGUI->tsk->cf_combobox), appGUI->tsk->filter_index);
685                         }
686                         return TRUE;
687                     }
688                     return FALSE;
689                 case GDK_KEY_Right:
690                     if(gtk_widget_is_focus(appGUI->tsk->tasks_find_entry) == FALSE) {
691                         if (appGUI->tsk->filter_index < utl_gui_get_combobox_items(GTK_COMBO_BOX(appGUI->tsk->cf_combobox))-1) {
692                             appGUI->tsk->filter_index++;
693                             gtk_combo_box_set_active(GTK_COMBO_BOX(appGUI->tsk->cf_combobox), appGUI->tsk->filter_index);
694                         }
695                         return TRUE;
696                     }
697                     return FALSE;
698                 case GDK_KEY_y:
699                     key_counter_add (26, appGUI);
700                     return FALSE;
701                 case GDK_KEY_l:
702                     if (event->state & GDK_CONTROL_MASK) {  /* CTRL + l */
703                         gtk_widget_grab_focus(GTK_WIDGET(appGUI->tsk->tasks_find_entry));
704                         return TRUE;
705                     }
706                     return FALSE;
707             }
708     }
709 
710 #endif /* TASKS_ENABLED */
711 
712 #ifdef CONTACTS_ENABLED
713 
714     /************************************************************************/
715     /*** CONTACTS PAGE                                                    ***/
716     /************************************************************************/
717 
718     if(page == PAGE_CONTACTS) {
719 
720             switch (event->keyval) {
721 
722                 case GDK_KEY_Escape:
723                     if (gtk_widget_is_focus(appGUI->cnt->contacts_find_entry) == FALSE) {
724                         if (config.enable_systray == TRUE && appGUI->no_tray == FALSE && appGUI->calendar_only == FALSE) {
725                             gui_toggle_window_visibility (appGUI);
726                         }
727                     } else {
728                         if (strlen(gtk_entry_get_text(GTK_ENTRY(appGUI->cnt->contacts_find_entry)))) {
729                             gtk_entry_set_text(GTK_ENTRY(appGUI->cnt->contacts_find_entry), "");
730                         } else {
731                             if (config.enable_systray == TRUE && appGUI->no_tray == FALSE && appGUI->calendar_only == FALSE) {
732                                     gui_toggle_window_visibility (appGUI);
733                             }
734                         }
735                     }
736                     return TRUE;
737                 case GDK_KEY_Return:
738                     if(gtk_widget_is_focus(appGUI->cnt->contacts_find_entry) == FALSE) {
739                         if (event->state & GDK_CONTROL_MASK) {  /* CTRL + Enter */
740                             if (gtk_tree_selection_count_selected_rows (appGUI->cnt->contacts_list_selection) == 1) {
741                                 contacts_add_edit_dialog_show (TRUE, appGUI);
742                                 return TRUE;
743                             }
744                         }
745                         if (gtk_widget_is_focus(appGUI->cnt->contacts_find_entry) == FALSE) {
746                             utl_gui_sw_vscrollbar_move_position (appGUI->cnt->contacts_panel_scrolledwindow, SW_MOVE_DOWN);
747                             return TRUE;
748                         }
749                         return TRUE;
750                     } else {
751                         gtk_widget_grab_focus(GTK_WIDGET(appGUI->cnt->contacts_list));
752                         return TRUE;
753                     }
754                     return FALSE;
755 
756                 case GDK_KEY_BackSpace:
757                     if(gtk_widget_is_focus(appGUI->cnt->contacts_find_entry) == FALSE) {
758                         utl_gui_sw_vscrollbar_move_position (appGUI->cnt->contacts_panel_scrolledwindow, SW_MOVE_UP);
759                         return TRUE;
760                     }
761                     return FALSE;
762                 case GDK_KEY_Delete:
763                     if(gtk_widget_is_focus(appGUI->cnt->contacts_find_entry) == FALSE) {
764                         if (gtk_tree_selection_count_selected_rows(appGUI->cnt->contacts_list_selection) > 0) {
765                             contacts_remove_dialog_show(appGUI);
766                             return TRUE;
767                         }
768                     }
769                     return FALSE;
770                 case GDK_KEY_Insert:
771                     if(gtk_widget_is_focus(appGUI->cnt->contacts_find_entry) == FALSE) {
772                         contacts_add_edit_dialog_show (FALSE, appGUI);
773                         return TRUE;
774                     }
775                     return FALSE;
776                 case GDK_KEY_Down:
777                     if (event->state & GDK_CONTROL_MASK) {  /* CTRL + Down */
778                         if (config.find_mode < CONTACTS_FF_ALL_FIELDS) {
779                             config.find_mode++;
780                         }
781                         gtk_combo_box_set_active (GTK_COMBO_BOX (appGUI->cnt->contacts_find_combobox), config.find_mode);
782                         return TRUE;
783                     }
784                     return FALSE;
785                 case GDK_KEY_Up:
786                     if (event->state & GDK_CONTROL_MASK) {  /* CTRL + Up */
787                         if (config.find_mode > CONTACTS_FF_FIRST_NAME) {
788                             config.find_mode--;
789                         }
790                         gtk_combo_box_set_active (GTK_COMBO_BOX (appGUI->cnt->contacts_find_combobox), config.find_mode);
791                         return TRUE;
792                     }
793                     return FALSE;
794                 case GDK_KEY_l:
795                     if (event->state & GDK_CONTROL_MASK) {  /* CTRL + l */
796                         gtk_widget_grab_focus(GTK_WIDGET(appGUI->cnt->contacts_find_entry));
797                         return TRUE;
798                     }
799                     return FALSE;
800             }
801     }
802 
803 #endif /* CONTACTS_ENABLED */
804 
805     /************************************************************************/
806     /*** NOTES PAGE                                                       ***/
807     /************************************************************************/
808 
809 #ifdef NOTES_ENABLED
810     if(page == PAGE_NOTES) {
811         if (appGUI->nte->editor_active == FALSE) {
812 
813             /* SELECTOR */
814             switch (event->keyval) {
815 
816                 case GDK_KEY_Return:
817                     if(gtk_widget_is_focus(appGUI->nte->notes_find_entry) == FALSE) {
818                         if (gtk_tree_selection_count_selected_rows (appGUI->nte->notes_list_selection) == 1) {
819                             if (event->state & GDK_CONTROL_MASK) {  /* CTRL + Enter */
820                                 notes_edit_dialog_show(appGUI->nte->notes_list, appGUI->nte->notes_filter, appGUI);
821                             } else {
822                                 notes_enter_password (appGUI);
823                             }
824                             return TRUE;
825                         }
826                         return FALSE;
827                     } else {
828                         gtk_widget_grab_focus(GTK_WIDGET(appGUI->nte->notes_list));
829                         return TRUE;
830                     }
831                 case GDK_KEY_Delete:
832                     if (gtk_widget_is_focus(appGUI->nte->notes_find_entry) == FALSE) {
833                         if (gtk_tree_selection_count_selected_rows(appGUI->nte->notes_list_selection) > 0) {
834                             notes_remove_dialog_show(appGUI);
835                             return TRUE;
836                         }
837                     }
838                     return FALSE;
839                 case GDK_KEY_Insert:
840                     if(gtk_widget_is_focus(appGUI->nte->notes_find_entry) == FALSE) {
841                         notes_add_entry (appGUI);
842                         return TRUE;
843                     }
844                     return FALSE;
845                 case GDK_KEY_Left:
846                     if(gtk_widget_is_focus(appGUI->nte->notes_find_entry) == FALSE) {
847                         if (appGUI->nte->filter_index > 0) {
848                             appGUI->nte->filter_index--;
849                             gtk_combo_box_set_active(GTK_COMBO_BOX(appGUI->nte->cf_combobox), appGUI->nte->filter_index);
850                         }
851                         return TRUE;
852                     }
853                     return FALSE;
854                 case GDK_KEY_Right:
855                     if(gtk_widget_is_focus(appGUI->nte->notes_find_entry) == FALSE) {
856                         if (appGUI->nte->filter_index < utl_gui_get_combobox_items(GTK_COMBO_BOX(appGUI->nte->cf_combobox))-1) {
857                             appGUI->nte->filter_index++;
858                             gtk_combo_box_set_active(GTK_COMBO_BOX(appGUI->nte->cf_combobox), appGUI->nte->filter_index);
859                         }
860                         return TRUE;
861                     }
862                     return FALSE;
863                 case GDK_KEY_Escape:
864                     if(gtk_widget_is_focus(appGUI->nte->notes_find_entry) == FALSE) {
865                         if (config.enable_systray == TRUE && appGUI->no_tray == FALSE && appGUI->calendar_only == FALSE) {
866                             gui_toggle_window_visibility (appGUI);
867                         }
868                     } else {
869                         if (strlen(gtk_entry_get_text(GTK_ENTRY(appGUI->nte->notes_find_entry)))) {
870                             gtk_entry_set_text(GTK_ENTRY(appGUI->nte->notes_find_entry), "");
871                         } else {
872                             if (config.enable_systray == TRUE && appGUI->no_tray == FALSE && appGUI->calendar_only == FALSE) {
873                                 gui_toggle_window_visibility (appGUI);
874                             }
875                         }
876                     }
877                     return TRUE;
878                 case GDK_KEY_l:
879                     if (event->state & GDK_CONTROL_MASK) {  /* CTRL + l */
880                         gtk_widget_grab_focus(GTK_WIDGET(appGUI->nte->notes_find_entry));
881                         return TRUE;
882                     }
883                     return FALSE;
884             }
885 
886         } else {
887 
888             /* EDITOR */
889             switch (event->keyval) {
890 
891                 case GDK_KEY_w:
892                     if (event->state & GDK_CONTROL_MASK) {  /* CTRL + w */
893                         editor_close_cb (NULL, appGUI);
894                         return TRUE;
895                     }
896                     return FALSE;
897 
898                 case GDK_KEY_Escape:
899                     if (appGUI->nte->find_hbox_visible == FALSE) {
900                         editor_close_cb (NULL, appGUI);
901                         return TRUE;
902                     }
903                     return FALSE;
904 
905                 case GDK_KEY_b:
906                     if ((event->state & GDK_CONTROL_MASK) && !appGUI->nte->note_read_only) {  /* CTRL + b */
907                         g_signal_emit_by_name(G_OBJECT(appGUI->nte->bold_button), "clicked");
908                         return TRUE;
909                     }
910                     return FALSE;
911 
912                 case GDK_KEY_i:
913                     if ((event->state & GDK_CONTROL_MASK) && !appGUI->nte->note_read_only) {  /* CTRL + i */
914                         g_signal_emit_by_name(G_OBJECT(appGUI->nte->italic_button), "clicked");
915                         return TRUE;
916                     }
917                     return FALSE;
918 
919                 case GDK_KEY_m:
920                     if ((event->state & GDK_CONTROL_MASK) && !appGUI->nte->note_read_only) {  /* CTRL + m */
921                         g_signal_emit_by_name(G_OBJECT(appGUI->nte->highlight_button), "clicked");
922                         return TRUE;
923                     }
924                     return FALSE;
925 
926                 case GDK_KEY_u:
927                     if ((event->state & GDK_CONTROL_MASK) && !appGUI->nte->note_read_only) {  /* CTRL + u */
928                         g_signal_emit_by_name(G_OBJECT(appGUI->nte->underline_button), "clicked");
929                         return TRUE;
930                     }
931                     return FALSE;
932 
933                 case GDK_KEY_t:
934                     if ((event->state & GDK_CONTROL_MASK) && !appGUI->nte->note_read_only) {  /* CTRL + t */
935                         g_signal_emit_by_name(G_OBJECT(appGUI->nte->strikethrough_button), "clicked");
936                         return TRUE;
937                     }
938                     return FALSE;
939 
940                 case GDK_KEY_s:
941                     if ((event->state & GDK_CONTROL_MASK) && !appGUI->nte->note_read_only) {  /* CTRL + s */
942                         editor_save_buffer_cb (NULL, appGUI);
943                         return TRUE;
944                     }
945                     return FALSE;
946 
947                 case GDK_KEY_f:
948                     if (event->state & GDK_CONTROL_MASK) {  /* CTRL + f */
949                         editor_find_text_show_cb (NULL, appGUI);
950                         return TRUE;
951                     }
952                     return FALSE;
953 
954                 case GDK_KEY_n:
955                     if ((event->state & GDK_CONTROL_MASK) && !appGUI->nte->note_read_only) {  /* CTRL + n */
956                         clear_text_attributes_cb (NULL, appGUI);
957                         return TRUE;
958                     }
959                     return FALSE;
960 
961                 case GDK_KEY_o:
962                     if ((event->state & GDK_CONTROL_MASK) && !appGUI->nte->note_read_only) {  /* CTRL + o */
963                         open_url_links_cb (NULL, appGUI);
964                         return TRUE;
965                     }
966                     return FALSE;
967 
968                 case GDK_KEY_period:
969                     if ((event->state & GDK_CONTROL_MASK)) {  /* CTRL + . */
970                         text_info_cb (NULL, appGUI);
971                         return TRUE;
972                     }
973                     return FALSE;
974             }
975         }
976     }
977 #endif  /* NOTES_ENABLED */
978 
979     /************************************************************************/
980     /*** GLOBAL SHORTCUTS                                                 ***/
981     /************************************************************************/
982 
983     switch (event->keyval) {
984 
985         case GDK_KEY_Escape:
986             if (config.enable_systray == TRUE && appGUI->no_tray == FALSE && appGUI->calendar_only == FALSE) {
987                 gui_toggle_window_visibility (appGUI);
988             }
989             return FALSE;
990 
991         case GDK_KEY_q:
992             if (event->state & GDK_CONTROL_MASK) {  /* CTRL + Q */
993                 gui_quit_osmo (appGUI);
994             }
995             return FALSE;
996 
997         case GDK_KEY_Page_Up:
998 #ifdef NOTES_ENABLED
999             if (appGUI->nte->editor_active == FALSE) {
1000 #endif  /* NOTES_ENABLED */
1001                 if (event->state & GDK_CONTROL_MASK) {  /* CTRL + Page_Up */
1002                     set_visible_page(appGUI->current_tab, FALSE, appGUI);
1003                     return TRUE;
1004                 } else if (page == PAGE_CALENDAR) {
1005                     if (config.day_notes_visible) {
1006                         if (event->state & GDK_MOD1_MASK) {  /* ALT + Page_Up */
1007                             calendar_btn_prev_month(appGUI);
1008                             return TRUE;
1009                         }
1010                     } else {
1011                         calendar_btn_prev_month(appGUI);
1012                         return TRUE;
1013                     }
1014                 }
1015 #ifdef NOTES_ENABLED
1016             }
1017 #endif  /* NOTES_ENABLED */
1018             return FALSE;
1019 
1020         case GDK_KEY_Page_Down:
1021 #ifdef NOTES_ENABLED
1022             if (appGUI->nte->editor_active == FALSE) {
1023 #endif  /* NOTES_ENABLED */
1024                 if (event->state & GDK_CONTROL_MASK) {  /* CTRL + Page_Down */
1025                     set_visible_page(appGUI->current_tab, TRUE, appGUI);
1026                     return TRUE;
1027                 } else if (page == PAGE_CALENDAR) {
1028                     if (config.day_notes_visible) {
1029                         if (event->state & GDK_MOD1_MASK) {  /* ALT + Page_Down */
1030                             calendar_btn_next_month(appGUI);
1031                             return TRUE;
1032                         }
1033                     } else {
1034                         calendar_btn_next_month(appGUI);
1035                         return TRUE;
1036                     }
1037                 }
1038 #ifdef NOTES_ENABLED
1039             }
1040 #endif  /* NOTES_ENABLED */
1041             return FALSE;
1042         case GDK_KEY_F1:
1043             select_tab (0, appGUI);
1044             return TRUE;
1045         case GDK_KEY_1:
1046             if ((event->state & GDK_MOD1_MASK)) {  /* ALT + 1 */
1047 #if defined(TASKS_ENABLED) || defined(CONTACTS_ENABLED) || defined(NOTES_ENABLED)
1048                 if (event->state & GDK_CONTROL_MASK) {  /* CTRL + ALT + 1 */
1049                     opt_hide_modules (!config.hide_calendar,
1050                                       config.hide_tasks,
1051                                       config.hide_contacts,
1052                                       config.hide_notes,
1053                                       FALSE, appGUI);
1054                     select_tab (0, appGUI);
1055                 } else {
1056 #endif
1057                     select_tab (0, appGUI);
1058 #if defined(TASKS_ENABLED) || defined(CONTACTS_ENABLED) || defined(NOTES_ENABLED)
1059                 }
1060 #endif
1061                 return TRUE;
1062             }
1063             return FALSE;
1064         case GDK_KEY_F2:
1065             select_tab (1, appGUI);
1066             return TRUE;
1067         case GDK_KEY_2:
1068             if ((event->state & GDK_MOD1_MASK)) {  /* ALT + 2 */
1069 #ifdef TASKS_ENABLED
1070                 if (event->state & GDK_CONTROL_MASK) {  /* CTRL + ALT + 2 */
1071                     opt_hide_modules (config.hide_calendar,
1072                                       !config.hide_tasks,
1073                                       config.hide_contacts,
1074                                       config.hide_notes,
1075                                       FALSE, appGUI);
1076                     select_tab (0, appGUI);
1077                 } else {
1078 #endif  /* TASKS_ENABLED */
1079                     select_tab (1, appGUI);
1080 #ifdef TASKS_ENABLED
1081                 }
1082 #endif  /* TASKS_ENABLED */
1083                 return TRUE;
1084             }
1085             return FALSE;
1086         case GDK_KEY_F3:
1087             select_tab (2, appGUI);
1088             return TRUE;
1089         case GDK_KEY_3:
1090             if ((event->state & GDK_MOD1_MASK)) {  /* ALT + 3 */
1091 #ifdef CONTACTS_ENABLED
1092                 if (event->state & GDK_CONTROL_MASK) {  /* CTRL + ALT + 3 */
1093                     opt_hide_modules (config.hide_calendar,
1094                                       config.hide_tasks,
1095                                       !config.hide_contacts,
1096                                       config.hide_notes,
1097                                       FALSE, appGUI);
1098                     select_tab (0, appGUI);
1099                 } else {
1100 #endif  /* CONTACTS_ENABLED */
1101                     select_tab (2, appGUI);
1102 #ifdef CONTACTS_ENABLED
1103                 }
1104 #endif  /* CONTACTS_ENABLED */
1105                 return TRUE;
1106             }
1107             return FALSE;
1108         case GDK_KEY_F4:
1109             select_tab (3, appGUI);
1110             return TRUE;
1111         case GDK_KEY_4:
1112             if ((event->state & GDK_MOD1_MASK)) {  /* ALT + 4 */
1113 #ifdef NOTES_ENABLED
1114                 if (event->state & GDK_CONTROL_MASK) {  /* CTRL + ALT + 4 */
1115                     opt_hide_modules (config.hide_calendar,
1116                                       config.hide_tasks,
1117                                       config.hide_contacts,
1118                                       !config.hide_notes,
1119                                       FALSE, appGUI);
1120                     select_tab (0, appGUI);
1121                 } else {
1122 #endif  /* NOTES_ENABLED */
1123                    select_tab (3, appGUI);
1124 #ifdef NOTES_ENABLED
1125                 }
1126 #endif  /* NOTES_ENABLED */
1127                 return TRUE;
1128             }
1129             return FALSE;
1130         case GDK_KEY_F5:
1131             gtk_widget_show (GTK_WIDGET(opt_create_preferences_window (appGUI)));
1132             return TRUE;
1133         case GDK_KEY_F6:
1134             gtk_widget_show (GTK_WIDGET(opt_create_about_window (appGUI)));
1135             return TRUE;
1136 
1137         case GDK_KEY_F11:   /* full screen */
1138             gui_toggle_fullscreen (appGUI);
1139             return TRUE;
1140     }
1141 
1142     return FALSE;
1143 }
1144 
1145 /*------------------------------------------------------------------------------*/
1146 
1147 void
1148 notebook_sw_cb (GtkNotebook *notebook, GtkWidget *page, guint page_num, gpointer user_data) {
1149 
1150     GUI *appGUI = (GUI *)user_data;
1151 
1152 #ifdef NOTES_ENABLED
1153     if (appGUI->nte->editor_active == TRUE) {
1154         editor_close_cb (NULL, appGUI);
1155     }
1156 #endif  /* NOTES_ENABLED */
1157 
1158     appGUI->current_tab = page_num;
1159 }
1160 
1161 /*------------------------------------------------------------------------------*/
1162 
1163 gboolean
1164 trayicon_clicked_cb (GtkStatusIcon *status_icon, GdkEventButton *event, gpointer user_data) {
1165 
1166     GUI *appGUI = (GUI *)user_data;
1167 
1168     if (event->button == 1) {   /* LMB */
1169 
1170         gui_toggle_window_visibility (appGUI);
1171         return TRUE;
1172 
1173     } else if (event->button == 2) {    /* MMB */
1174 
1175         gtk_status_icon_set_from_icon_name (appGUI->osmo_trayicon, OSMO_STOCK_SYSTRAY_NORMAL);
1176         return TRUE;
1177     }
1178 
1179     return FALSE;
1180 }
1181 
1182 /*------------------------------------------------------------------------------*/
1183 
1184 void
1185 trayicon_popup_cb (GtkStatusIcon *status_icon, guint button, guint activate_time, gpointer user_data) {
1186 
1187     GUI *appGUI = (GUI *)user_data;
1188 
1189     gtk_menu_popup(GTK_MENU(appGUI->trayicon_popup_menu), NULL, NULL, NULL, NULL,
1190                    button, activate_time);
1191 }
1192 
1193 void
1194 systray_popup_menu_quit_selected_cb (gpointer user_data) {
1195     GUI *appGUI = (GUI *)user_data;
1196     gui_quit_osmo (appGUI);
1197 }
1198 
1199 void
1200 systray_popup_menu_show_calendar_selected_cb (gpointer user_data) {
1201     GUI *appGUI = (GUI *)user_data;
1202     if (appGUI->window_visible == FALSE) {
1203         gtk_widget_show (appGUI->main_window);
1204         appGUI->window_visible = TRUE;
1205     }
1206     gtk_window_deiconify (GTK_WINDOW(appGUI->main_window));
1207     gtk_status_icon_set_from_icon_name (appGUI->osmo_trayicon, OSMO_STOCK_SYSTRAY_NORMAL);
1208     gtk_notebook_set_current_page (GTK_NOTEBOOK (appGUI->notebook), PAGE_CALENDAR);
1209 }
1210 
1211 #ifdef TASKS_ENABLED
1212 void
1213 systray_popup_menu_show_tasks_selected_cb (gpointer user_data) {
1214     GUI *appGUI = (GUI *)user_data;
1215     if (appGUI->window_visible == FALSE) {
1216         gtk_widget_show (appGUI->main_window);
1217         appGUI->window_visible = TRUE;
1218     }
1219     gtk_window_deiconify (GTK_WINDOW(appGUI->main_window));
1220     gtk_status_icon_set_from_icon_name (appGUI->osmo_trayicon, OSMO_STOCK_SYSTRAY_NORMAL);
1221     gtk_notebook_set_current_page (GTK_NOTEBOOK (appGUI->notebook), PAGE_TASKS);
1222 }
1223 #endif  /* TASKS_ENABLED */
1224 
1225 #ifdef CONTACTS_ENABLED
1226 void
1227 systray_popup_menu_show_contacts_selected_cb (gpointer user_data) {
1228     GUI *appGUI = (GUI *)user_data;
1229     if (appGUI->window_visible == FALSE) {
1230         gtk_widget_show (appGUI->main_window);
1231         appGUI->window_visible = TRUE;
1232     }
1233     gtk_window_deiconify (GTK_WINDOW(appGUI->main_window));
1234     gtk_status_icon_set_from_icon_name (appGUI->osmo_trayicon, OSMO_STOCK_SYSTRAY_NORMAL);
1235     gtk_notebook_set_current_page (GTK_NOTEBOOK (appGUI->notebook), PAGE_CONTACTS);
1236 }
1237 #endif  /* CONTACTS_ENABLED */
1238 
1239 #ifdef NOTES_ENABLED
1240 void
1241 systray_popup_menu_show_notes_selected_cb (gpointer user_data) {
1242     GUI *appGUI = (GUI *)user_data;
1243     if (appGUI->window_visible == FALSE) {
1244         gtk_widget_show (appGUI->main_window);
1245         appGUI->window_visible = TRUE;
1246     }
1247     gtk_window_deiconify (GTK_WINDOW(appGUI->main_window));
1248     gtk_status_icon_set_from_icon_name (appGUI->osmo_trayicon, OSMO_STOCK_SYSTRAY_NORMAL);
1249     gtk_notebook_set_current_page (GTK_NOTEBOOK (appGUI->notebook), PAGE_NOTES);
1250 }
1251 #endif  /* NOTES_ENABLED */
1252 
1253 void
1254 systray_popup_menu_show_options_selected_cb (GUI *appGUI)
1255 {
1256     if (appGUI->window_visible == FALSE) {
1257         gtk_widget_show (appGUI->main_window);
1258         appGUI->window_visible = TRUE;
1259     }
1260     gtk_window_deiconify (GTK_WINDOW (appGUI->main_window));
1261     gtk_status_icon_set_from_icon_name (appGUI->osmo_trayicon, OSMO_STOCK_SYSTRAY_NORMAL);
1262     gtk_widget_show (opt_create_preferences_window (appGUI));
1263 }
1264 
1265 /*------------------------------------------------------------------------------*/
1266 
1267 void
1268 gui_systray_tooltip_update (GUI *appGUI)
1269 {
1270     gchar *tstr, *dstr, *text;
1271 
1272     if (appGUI->osmo_trayicon == NULL) return;
1273 
1274     dstr = utl_date_print_j (utl_date_get_current_julian (), DATE_FULL,
1275                              config.override_locale_settings);
1276 
1277     tstr = utl_time_print_default (utl_time_get_current_seconds (), FALSE);
1278 
1279     text = g_strdup_printf ("%s, %s", dstr, tstr);
1280     gtk_status_icon_set_tooltip_text (appGUI->osmo_trayicon, text);
1281 
1282     g_free (tstr);
1283     g_free (dstr);
1284     g_free (text);
1285 }
1286 
1287 /*------------------------------------------------------------------------------*/
1288 
1289 void
1290 gui_systray_update_icon (GUI *appGUI) {
1291 
1292 guint32 julian_day;
1293 gboolean flag = FALSE;
1294 
1295     if (appGUI->window_visible == TRUE) return;
1296 
1297     julian_day = utl_date_get_current_julian ();
1298 
1299     if (config.ignore_day_note_events == FALSE) {
1300         if (cal_check_note (julian_day, appGUI) == TRUE) {
1301             gtk_status_icon_set_from_icon_name (appGUI->osmo_trayicon, OSMO_STOCK_SYSTRAY_NOTE);
1302             flag = TRUE;
1303         }
1304     }
1305 
1306 #ifdef TASKS_ENABLED
1307     if (tsk_check_tasks (julian_day, julian_day, STATE_NONE, appGUI)) {
1308         gtk_status_icon_set_from_icon_name (appGUI->osmo_trayicon, OSMO_STOCK_SYSTRAY_TASK);
1309         flag = TRUE;
1310     }
1311 #endif  /* TASKS_ENABLED */
1312 
1313 #ifdef CONTACTS_ENABLED
1314     if (check_contacts(julian_day, appGUI) == TRUE) {
1315         gtk_status_icon_set_from_icon_name (appGUI->osmo_trayicon, OSMO_STOCK_SYSTRAY_BIRTHDAY);
1316         flag = TRUE;
1317     }
1318 #endif  /* CONTACTS_ENABLED */
1319 
1320     if (flag == FALSE) {
1321             gtk_status_icon_set_from_icon_name (appGUI->osmo_trayicon, OSMO_STOCK_SYSTRAY_NORMAL);
1322     }
1323 }
1324 /*------------------------------------------------------------------------------*/
1325 static GtkWidget *
1326 create_menu_item(const gchar *text, GtkWidget *image) {
1327     GtkWidget *menu_item = gtk_menu_item_new();
1328     GtkWidget *box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
1329     GtkWidget *label = gtk_label_new(text);
1330 
1331     gtk_widget_set_margin_left(label, 6);
1332     gtk_widget_set_halign(label, GTK_ALIGN_START);
1333     gtk_box_pack_start(GTK_BOX(box), image, FALSE, FALSE, 0);
1334     gtk_box_pack_end(GTK_BOX(box), label, TRUE, TRUE, 0);
1335     gtk_container_add(GTK_CONTAINER(menu_item), box);
1336     gtk_widget_show_all(menu_item);
1337 
1338     return menu_item;
1339 }
1340 
1341 /*------------------------------------------------------------------------------*/
1342 
1343 void
1344 gui_systray_initialize (GUI *appGUI) {
1345 
1346 GtkWidget   *menu_entry;
1347 GtkWidget   *systray_menu_separator;
1348 
1349     if (appGUI->calendar_only == TRUE) {
1350         return;
1351     }
1352 
1353     appGUI->trayicon_popup_menu = gtk_menu_new();
1354 
1355     appGUI->trayicon_menu_calendar_item = create_menu_item (_("Show calendar"),
1356             gtk_image_new_from_icon_name(OSMO_STOCK_SYSTRAY_MENU_CALENDAR, GTK_ICON_SIZE_MENU));
1357     gtk_menu_shell_append (GTK_MENU_SHELL(appGUI->trayicon_popup_menu), appGUI->trayicon_menu_calendar_item);
1358     g_signal_connect_swapped (G_OBJECT(appGUI->trayicon_menu_calendar_item), "activate",
1359                               G_CALLBACK(systray_popup_menu_show_calendar_selected_cb), appGUI);
1360     if (config.hide_calendar == FALSE) {
1361         gtk_widget_show (appGUI->trayicon_menu_calendar_item);
1362     }
1363 
1364 #ifdef TASKS_ENABLED
1365     appGUI->trayicon_menu_tasks_item = create_menu_item (_("Show tasks"),
1366             gtk_image_new_from_icon_name(OSMO_STOCK_SYSTRAY_MENU_TASKS, GTK_ICON_SIZE_MENU));
1367     gtk_menu_shell_append (GTK_MENU_SHELL(appGUI->trayicon_popup_menu), appGUI->trayicon_menu_tasks_item);
1368     g_signal_connect_swapped (G_OBJECT(appGUI->trayicon_menu_tasks_item), "activate",
1369                               G_CALLBACK(systray_popup_menu_show_tasks_selected_cb), appGUI);
1370 
1371     if (config.hide_tasks == FALSE) {
1372         gtk_widget_show (appGUI->trayicon_menu_tasks_item);
1373     }
1374 #endif  /* TASKS_ENABLED */
1375 
1376 #ifdef CONTACTS_ENABLED
1377     appGUI->trayicon_menu_contacts_item = create_menu_item (_("Show contacts"),
1378             gtk_image_new_from_icon_name(OSMO_STOCK_SYSTRAY_MENU_CONTACTS, GTK_ICON_SIZE_MENU));
1379     gtk_menu_shell_append (GTK_MENU_SHELL(appGUI->trayicon_popup_menu), appGUI->trayicon_menu_contacts_item);
1380     g_signal_connect_swapped (G_OBJECT(appGUI->trayicon_menu_contacts_item), "activate",
1381                               G_CALLBACK(systray_popup_menu_show_contacts_selected_cb), appGUI);
1382     if (config.hide_contacts == FALSE) {
1383         gtk_widget_show (appGUI->trayicon_menu_contacts_item);
1384     }
1385 #endif  /* CONTACTS_ENABLED */
1386 
1387 #ifdef NOTES_ENABLED
1388     appGUI->trayicon_menu_notes_item = create_menu_item (_("Show notes"),
1389             gtk_image_new_from_icon_name(OSMO_STOCK_SYSTRAY_MENU_NOTES, GTK_ICON_SIZE_MENU));
1390     gtk_menu_shell_append (GTK_MENU_SHELL(appGUI->trayicon_popup_menu), appGUI->trayicon_menu_notes_item);
1391     g_signal_connect_swapped (G_OBJECT(appGUI->trayicon_menu_notes_item), "activate",
1392                               G_CALLBACK(systray_popup_menu_show_notes_selected_cb), appGUI);
1393     if (config.hide_notes == FALSE) {
1394         gtk_widget_show (appGUI->trayicon_menu_notes_item);
1395     }
1396 #endif  /* NOTES_ENABLED */
1397 
1398     systray_menu_separator = gtk_separator_menu_item_new();
1399     gtk_menu_shell_append(GTK_MENU_SHELL(appGUI->trayicon_popup_menu), systray_menu_separator);
1400     gtk_widget_show(systray_menu_separator);
1401 
1402     menu_entry = create_menu_item (_("Show options"),
1403                 gtk_image_new_from_icon_name("preferences-system", GTK_ICON_SIZE_MENU));
1404     gtk_menu_shell_append(GTK_MENU_SHELL(appGUI->trayicon_popup_menu), menu_entry);
1405     g_signal_connect_swapped(G_OBJECT(menu_entry), "activate",
1406                              G_CALLBACK(systray_popup_menu_show_options_selected_cb), appGUI);
1407     gtk_widget_show(menu_entry);
1408 
1409     systray_menu_separator = gtk_separator_menu_item_new();
1410     gtk_menu_shell_append(GTK_MENU_SHELL(appGUI->trayicon_popup_menu), systray_menu_separator);
1411     gtk_widget_show(systray_menu_separator);
1412 
1413     menu_entry = create_menu_item (_("Quit"),
1414                 gtk_image_new_from_icon_name("application-exit", GTK_ICON_SIZE_MENU));
1415     gtk_menu_shell_append(GTK_MENU_SHELL(appGUI->trayicon_popup_menu), menu_entry);
1416     g_signal_connect_swapped(G_OBJECT(menu_entry), "activate",
1417                              G_CALLBACK(systray_popup_menu_quit_selected_cb), appGUI);
1418     gtk_widget_show(menu_entry);
1419 
1420     /* create tray icon */
1421 
1422     appGUI->osmo_trayicon = gtk_status_icon_new_from_icon_name(OSMO_STOCK_SYSTRAY_NORMAL);
1423     g_signal_connect(G_OBJECT(appGUI->osmo_trayicon), "button-release-event",
1424                      G_CALLBACK(trayicon_clicked_cb), appGUI);
1425 
1426     g_signal_connect(G_OBJECT(appGUI->osmo_trayicon), "popup-menu",
1427                      G_CALLBACK(trayicon_popup_cb), appGUI);
1428 
1429     appGUI->window_visible = TRUE;
1430 
1431     if (config.enable_systray == TRUE) {
1432         gtk_status_icon_set_visible (appGUI->osmo_trayicon, TRUE);
1433         while (g_main_context_iteration (NULL, FALSE));
1434 
1435         if (gtk_status_icon_is_embedded (appGUI->osmo_trayicon) == FALSE) {
1436             appGUI->no_tray = TRUE;
1437             gtk_status_icon_set_visible (appGUI->osmo_trayicon, FALSE);
1438             gtk_widget_show(appGUI->main_window);
1439         } else {
1440             appGUI->no_tray = FALSE;
1441             gtk_status_icon_set_visible (appGUI->osmo_trayicon, TRUE);
1442             if (config.start_minimised_in_systray) {
1443                 appGUI->window_visible = FALSE;
1444             } else {
1445                 gtk_widget_show (appGUI->main_window);
1446             }
1447         }
1448     } else {
1449         gtk_status_icon_set_visible (appGUI->osmo_trayicon, FALSE);
1450         gtk_widget_show (appGUI->main_window);
1451     }
1452 
1453     gui_systray_update_icon (appGUI);
1454     gui_systray_tooltip_update (appGUI);
1455 }
1456 
1457 /*------------------------------------------------------------------------------*/
1458 #ifndef WIN32
1459 static gboolean
1460 deliver_signal(gpointer data)
1461 {
1462     GUI *appGUI = data;
1463     gui_quit_osmo(appGUI);
1464     return G_SOURCE_CONTINUE;
1465 }
1466 
1467 static void
1468 register_signal_handler(GUI *appGUI) {
1469     if(g_unix_signal_add(SIGINT, deliver_signal, appGUI) <= 0
1470             || g_unix_signal_add(SIGTERM, deliver_signal, appGUI) <= 0
1471             || g_unix_signal_add(SIGHUP, deliver_signal, appGUI) <= 0) {
1472         g_warning("Failed to install the signal handler");
1473     }
1474 }
1475 #endif /* WIN32 */
1476 /*------------------------------------------------------------------------------*/
1477 
1478 gboolean
1479 gui_create_window (GUI *appGUI)
1480 {
1481     GdkScreen *screen;
1482     gint sw, sh;
1483     gint fdSTDERR, fdSTDERRn;
1484 
1485     /* disable STDERR temporary - to suppress messages from webkit */
1486     fdSTDERR = dup (STDERR_FILENO);
1487     fdSTDERRn = open("/dev/null", O_WRONLY);
1488     dup2 (fdSTDERRn, STDERR_FILENO);
1489     close (fdSTDERRn);
1490 
1491     appGUI->all_pages_added = FALSE;
1492 
1493     appGUI->cal->fd_day_name_font = pango_font_description_from_string(config.day_name_font);
1494     appGUI->cal->fd_cal_font = pango_font_description_from_string(config.calendar_font);
1495     appGUI->cal->fd_notes_font = pango_font_description_from_string(config.notes_font);
1496 
1497     appGUI->main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1498 
1499 #ifndef REV
1500     gtk_window_set_title (GTK_WINDOW (appGUI->main_window), "Osmo " VERSION_MAJOR "." VERSION_MINOR "." VERSION_MICRO);
1501 #else
1502     gtk_window_set_title (GTK_WINDOW (appGUI->main_window), "Osmo (development)");
1503 #endif
1504 
1505     gtk_widget_set_events(appGUI->main_window, GDK_BUTTON_PRESS_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
1506 
1507     gtk_window_set_icon_name(GTK_WINDOW(appGUI->main_window), OSMO_STOCK_LOGO);
1508 
1509     screen = gdk_screen_get_default ();
1510     if (screen != NULL) {
1511         sw = gdk_screen_get_width (screen);
1512         sh = gdk_screen_get_height (screen);
1513         if (config.window_x >= sw || config.window_x < 0)
1514             config.window_x = 0;
1515         if (config.window_y >= sh || config.window_y < 0)
1516             config.window_y = 0;
1517     }
1518 
1519     gtk_window_move (GTK_WINDOW (appGUI->main_window), config.window_x, config.window_y);
1520 
1521     gtk_widget_realize (appGUI->main_window);
1522 
1523     if (appGUI->calendar_only == FALSE) {
1524         gtk_window_set_default_size (GTK_WINDOW(appGUI->main_window), config.window_size_x, config.window_size_y);
1525     } else {
1526         gtk_window_set_default_size (GTK_WINDOW(appGUI->main_window), 500, -1);
1527     }
1528     gtk_window_set_resizable (GTK_WINDOW (appGUI->main_window), TRUE);
1529 
1530     g_signal_connect (G_OBJECT (appGUI->main_window), "delete-event",
1531                       G_CALLBACK(gui_window_close_cb), appGUI);
1532     g_signal_connect (G_OBJECT (appGUI->main_window), "key_press_event",
1533                       G_CALLBACK (key_press_cb), appGUI);
1534 
1535     osmo_register_theme_icons ();
1536     utl_gui_url_initialize (appGUI);
1537 
1538     appGUI->notebook = gtk_notebook_new ();
1539     gtk_widget_set_can_focus (appGUI->notebook, FALSE);
1540     gtk_widget_show (appGUI->notebook);
1541     gtk_notebook_set_tab_pos (GTK_NOTEBOOK(appGUI->notebook), config.tabs_position);
1542     gtk_container_add (GTK_CONTAINER(appGUI->main_window), appGUI->notebook);
1543     g_signal_connect (G_OBJECT(appGUI->notebook), "switch-page",
1544                       G_CALLBACK(notebook_sw_cb), appGUI);
1545 
1546     gtk_notebook_set_scrollable (GTK_NOTEBOOK(appGUI->notebook), FALSE);
1547 
1548     if (appGUI->calendar_only == TRUE) {
1549         gtk_notebook_set_show_tabs (GTK_NOTEBOOK(appGUI->notebook), FALSE);
1550     }
1551 
1552     appGUI->opt->calendar_ical_files_store =
1553         gtk_list_store_new (ICAL_NUMBER_OF_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING,
1554                             G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
1555                             G_TYPE_BOOLEAN);
1556     appGUI->opt->calendar_category_store = gtk_list_store_new (3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING);
1557 
1558     gui_create_calendar(appGUI->notebook, appGUI);
1559 
1560     if (appGUI->calendar_only == FALSE) {
1561 
1562 #ifdef TASKS_ENABLED
1563         appGUI->opt->tasks_category_store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN);
1564         gui_create_tasks (appGUI);
1565 #endif  /* TASKS_ENABLED */
1566 
1567 #ifdef CONTACTS_ENABLED
1568         appGUI->opt->contacts_group_store = gtk_list_store_new (1, G_TYPE_STRING);
1569         gui_create_contacts (appGUI);
1570 #endif  /* CONTACTS_ENABLED */
1571 
1572 #ifdef NOTES_ENABLED
1573         gui_create_notes (appGUI);
1574 #endif  /* NOTES_ENABLED */
1575 
1576     if (!config.gui_layout) {
1577         if (config.enable_auxilary_calendars == TRUE) {
1578             gtk_widget_show (appGUI->cal->aux_cal_expander);
1579         } else {
1580             gtk_widget_hide (appGUI->cal->aux_cal_expander);
1581         }
1582     }
1583 
1584         cal_read_notes (appGUI);
1585 
1586 #ifdef HAVE_LIBICAL
1587         ics_initialize_timezone ();
1588         read_ical_entries (appGUI);
1589 #endif  /* HAVE_LIBICAL */
1590 
1591 #ifdef TASKS_ENABLED
1592         read_tasks_entries (appGUI);
1593         set_categories (appGUI);
1594         refresh_tasks (appGUI);
1595 #endif  /* TASKS_ENABLED */
1596 
1597 #ifdef CONTACTS_ENABLED
1598         read_contacts_entries (appGUI);
1599         set_export_active (appGUI);
1600 #endif  /* CONTACTS_ENABLED */
1601 
1602 #ifdef NOTES_ENABLED
1603         appGUI->opt->notes_category_store = gtk_list_store_new (1, G_TYPE_STRING);
1604         read_notes_entries (appGUI);
1605 
1606         utl_gui_create_category_combobox (GTK_COMBO_BOX (appGUI->nte->cf_combobox),
1607                                           appGUI->opt->notes_category_store, FALSE);
1608 
1609         if (config.remember_category_in_notes == TRUE) {
1610             gtk_combo_box_set_active (GTK_COMBO_BOX(appGUI->nte->cf_combobox), config.current_category_in_notes);
1611         } else {
1612             gtk_combo_box_set_active (GTK_COMBO_BOX(appGUI->nte->cf_combobox), 0);
1613         }
1614 #endif  /* NOTES_ENABLED */
1615 #ifndef WIN32
1616         register_signal_handler(appGUI);
1617 #endif /* WIN32 */
1618 #ifdef TASKS_ENABLED
1619         refresh_tasks (appGUI);
1620         appGUI->tsk->notifications_enable = TRUE;
1621 #endif  /* TASKS_ENABLED */
1622 
1623         appGUI->number_of_tabs = NUMBER_OF_TABS;
1624 
1625         if(config.remember_latest_tab == TRUE) {
1626             appGUI->current_tab = config.latest_tab;
1627         } else {
1628             appGUI->current_tab = PAGE_CALENDAR;
1629         }
1630     } else {
1631         appGUI->number_of_tabs = 1;
1632         appGUI->current_tab = 0;
1633     }
1634 
1635     appGUI->all_pages_added = TRUE;
1636     cal_refresh_notes(appGUI);
1637 
1638     if (config.toolbar_exit_button == FALSE) {
1639         if (appGUI->calendar_only == FALSE) {
1640             gtk_widget_hide (GTK_WIDGET(appGUI->cal->quit_button));
1641 #ifdef CONTACTS_ENABLED
1642             gtk_widget_hide (GTK_WIDGET(appGUI->cnt->quit_toolbar_button));
1643 #endif /* CONTACTS_ENABLED */
1644 #ifdef NOTES_ENABLED
1645             gtk_widget_hide (GTK_WIDGET(appGUI->nte->quit_button));
1646 #endif /* NOTES_ENABLED */
1647 #ifdef TASKS_ENABLED
1648             gtk_widget_hide (GTK_WIDGET(appGUI->tsk->quit_button));
1649 #endif /* TASKS_ENABLED */
1650         }
1651     }
1652 
1653     if (config.fullscreen == TRUE) {
1654         gtk_window_fullscreen (GTK_WINDOW(appGUI->main_window));
1655     }
1656 
1657     if (appGUI->check_events == TRUE) {
1658         return create_event_checker_window (appGUI);
1659     } else {
1660         gui_systray_initialize (appGUI);
1661     }
1662 
1663     if (appGUI->calendar_only == TRUE) {
1664         gtk_widget_show (appGUI->main_window);
1665     }
1666 
1667     gtk_notebook_set_current_page(GTK_NOTEBOOK(appGUI->notebook), appGUI->current_tab);
1668 
1669     /* enable STDERR */
1670     dup2 (fdSTDERR, STDERR_FILENO);
1671     close (fdSTDERR);
1672 
1673     return TRUE;
1674 }
1675 
1676 /*------------------------------------------------------------------------------*/
1677 
1678 void
1679 gui_add_to_notebook (GtkWidget *widget, gchar *text, GUI *appGUI) {
1680 
1681 GtkWidget *label;
1682 
1683     label = gtk_label_new(NULL);
1684 
1685     if (config.tabs_position == GTK_POS_LEFT) {
1686         gtk_label_set_angle (GTK_LABEL(label), 90.0);
1687     } else if (config.tabs_position == GTK_POS_RIGHT) {
1688         gtk_label_set_angle (GTK_LABEL(label), -90.0);
1689     }
1690     gtk_label_set_markup (GTK_LABEL (label), text);
1691 
1692     gtk_notebook_append_page(GTK_NOTEBOOK(appGUI->notebook), widget, label);
1693 
1694 }
1695 
1696 /*------------------------------------------------------------------------------*/
1697 GtkToolItem *
1698 gui_create_toolbar_button(GUI *appGUI, const gchar *icon_name, const gchar *label,
1699         void(*click_callback) (GtkToolButton *, gpointer)) {
1700     GtkToolItem *button = gtk_tool_button_new (NULL, NULL);
1701     gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (button), icon_name);
1702     gtk_tool_button_set_label (GTK_TOOL_BUTTON (button), label);
1703     gtk_widget_set_tooltip_text(GTK_WIDGET(button), label);
1704     gtk_widget_show(GTK_WIDGET(button));
1705     g_signal_connect(button, "clicked", G_CALLBACK(click_callback), appGUI);
1706     return button;
1707 }
1708 
1709 /*------------------------------------------------------------------------------*/
1710 GtkToolItem *
1711 gui_create_toolbar_toggle_button(GUI *appGUI, const gchar *icon_name, const gchar *label,
1712         void(*toggle_callback) (GtkToggleToolButton *, gpointer)) {
1713     GtkToolItem *button = gtk_toggle_tool_button_new ();
1714     gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (button), icon_name);
1715     gtk_tool_button_set_label (GTK_TOOL_BUTTON (button), label);
1716     gtk_widget_set_tooltip_text(GTK_WIDGET(button), label);
1717     gtk_widget_show(GTK_WIDGET(button));
1718     g_signal_connect(button, "toggled", G_CALLBACK(toggle_callback), appGUI);
1719     return button;
1720 }
1721 
1722 /*------------------------------------------------------------------------------*/
1723 void
1724 gui_append_toolbar_spring(GtkToolbar *toolbar) {
1725     GValue expand = G_VALUE_INIT;
1726     GtkToolItem *spring = gtk_separator_tool_item_new();
1727     g_value_init(&expand, G_TYPE_BOOLEAN);
1728     g_value_set_boolean(&expand, TRUE);
1729     gtk_separator_tool_item_set_draw(GTK_SEPARATOR_TOOL_ITEM(spring), FALSE);
1730     gtk_container_child_set_property(GTK_CONTAINER(toolbar), GTK_WIDGET(spring), "expand", &expand);
1731     gtk_toolbar_insert(toolbar, spring, -1);
1732 }
1733 
1734 /*------------------------------------------------------------------------------*/
1735