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