Logo Search packages:      
Sourcecode: dates version File versions

dates_gtk.c

/* -*- mode:C; tab-width:4; -*- */
/* 
 *  Author: Tomas Frydrych <tf@o-hand.com>
 *
 *  Copyright (c) 2005 - 2006 OpenedHand Ltd - http://o-hand.com
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 */

#include <gtk/gtk.h>
#include <string.h>

#include "dates_platform.h"
#include "dates_types.h"
#include "dates_callbacks.h"

#ifdef USE_OWL
#include "owlcolourbutton.h"
#endif

#ifdef WITH_HILDON
#include <hildon-widgets/hildon-color-button.h>
#endif

#ifndef DATES_PLATFORM_create_main_window
/* the default implementation assumes that menu is GtkMenuBar */
#ifdef DATES_MENU_WITHOUT_BAR
#error Cannot use default create_main_window () if DATES_MENU_WITHOUT_BAR is defined !!!
#endif
static GtkWidget *
create_main_window (DatesData * d, GtkWidget * toolbar,
                              GtkWidget * menu, GtkAccelGroup * accel_group)
{
      GtkWidget *main_vbox;
      GtkWidget *find_hbox;
      GtkWidget *find_label;
      GtkWidget *find_entry;
      GtkWidget *find_close_button;
      GtkWidget *image;
      GtkWidget *scrolled_window;

      d->main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
      gtk_window_set_title (GTK_WINDOW (d->main_window), _("Dates"));
      gtk_window_set_default_size (GTK_WINDOW (d->main_window), 480, 360);

      main_vbox = gtk_vbox_new (FALSE, 0);
      gtk_widget_show (main_vbox);
      gtk_container_add (GTK_CONTAINER (d->main_window), main_vbox);

      gtk_widget_show (menu);
      gtk_box_pack_start (GTK_BOX (main_vbox), menu, FALSE, FALSE, 0);

      gtk_box_pack_end (GTK_BOX (main_vbox), toolbar, FALSE, FALSE, 0);
      gtk_container_set_border_width (GTK_CONTAINER (toolbar), 3);


      d->header_eventbox = gtk_event_box_new ();
      gtk_box_pack_start (GTK_BOX (main_vbox), d->header_eventbox,
                                    FALSE, FALSE, 0);

      d->header_label = gtk_label_new (_("<big><b>Dates</b></big>"));
      gtk_widget_show (d->header_label);
      gtk_container_add (GTK_CONTAINER (d->header_eventbox), d->header_label);
      gtk_label_set_use_markup (GTK_LABEL (d->header_label), TRUE);

      gtk_widget_show (GTK_WIDGET (d->view));
      scrolled_window = gtk_scrolled_window_new (NULL, NULL);
      gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
                                    GTK_POLICY_NEVER,
                                    GTK_POLICY_AUTOMATIC);

      gtk_container_add (GTK_CONTAINER (scrolled_window), GTK_WIDGET (d->view));
      gtk_widget_show (scrolled_window);

      gtk_box_pack_start (GTK_BOX (main_vbox), scrolled_window,
                                    TRUE, TRUE, 0);
      
      GTK_WIDGET_SET_FLAGS (d->view, GTK_CAN_FOCUS);
      GTK_WIDGET_UNSET_FLAGS (d->view, GTK_CAN_DEFAULT);

      find_hbox = gtk_hbox_new (FALSE, 6);
      gtk_box_pack_start (GTK_BOX (main_vbox), find_hbox, FALSE, TRUE, 0);
      gtk_container_set_border_width (GTK_CONTAINER (find_hbox), 3);

      find_label = gtk_label_new (_("Find:"));
      gtk_widget_show (find_label);
      gtk_box_pack_start (GTK_BOX (find_hbox), find_label, FALSE, FALSE, 0);

      find_entry = gtk_entry_new ();
      gtk_widget_show (find_entry);
      gtk_box_pack_start (GTK_BOX (find_hbox), find_entry, TRUE, TRUE, 0);
      gtk_entry_set_activates_default (GTK_ENTRY (find_entry), TRUE);

      find_close_button = gtk_button_new ();
      gtk_widget_show (find_close_button);
      gtk_box_pack_start (GTK_BOX (find_hbox), find_close_button,
                                    FALSE, FALSE, 0);
      
      GTK_WIDGET_SET_FLAGS (find_close_button, GTK_CAN_DEFAULT);
      gtk_button_set_focus_on_click (GTK_BUTTON (find_close_button), FALSE);

      image = gtk_image_new_from_stock ("gtk-close", GTK_ICON_SIZE_MENU);
      gtk_widget_show (image);
      gtk_container_add (GTK_CONTAINER (find_close_button), image);

      gtk_widget_grab_focus (GTK_WIDGET (d->view));
      gtk_window_add_accel_group (GTK_WINDOW (d->main_window), accel_group);

      /* Set nice colours for full-screen date header */
      gtk_widget_set_state (d->header_eventbox, GTK_STATE_SELECTED);
      gtk_widget_set_state (d->header_label, GTK_STATE_SELECTED);
      
      g_signal_connect (G_OBJECT (d->main_window), "window_state_event",
                                G_CALLBACK (dates_window_state_cb), d);
      g_signal_connect (G_OBJECT (d->main_window), "key_press_event",
                                G_CALLBACK (dates_key_press_cb), d);

      return d->main_window;
}
#endif


#ifndef DATES_PLATFORM_create_details_dialog
static GtkWidget *
create_details_dialog (DatesData * d)
{
      GtkWidget *vbox;
      GtkWidget *notebook;
      GtkWidget *summary_table;
      GtkWidget *details_calendar_label;
      GtkWidget *label;
      GtkWidget *alignment;
      GtkWidget *hbox;
      GtkWidget *details_start_button;
      GtkWidget *details_end_button;
      GtkWidget *details_table;
      GtkWidget *scrolledwindow1;
#if 0 /* Not hooked up yet */
      GtkWidget *recur_table;
      GtkWidget *recur_repeats_label;
      GtkWidget *recur_combobox;
      GtkWidget *recur_on_label;
      GtkWidget *recur_until_label;
      GtkWidget *recur_until_button;
      GtkWidget *repeats_time_label;
      GtkWidget *recur_week_hbox;
      GtkWidget *togglebutton;
      GtkWidget *recur_except_button;
      GtkWidget *image;
#endif
      GtkWidget *details_cancel_button;
      GtkWidget *details_ok_button;

      d->details_dialog = gtk_dialog_new ();
      gtk_window_set_title (GTK_WINDOW (d->details_dialog), _("Details"));
      gtk_window_set_modal (GTK_WINDOW (d->details_dialog), TRUE);
      gtk_window_set_icon_name (GTK_WINDOW (d->details_dialog), "gtk-edit");
      gtk_window_set_skip_taskbar_hint (GTK_WINDOW (d->details_dialog), TRUE);
      gtk_window_set_skip_pager_hint (GTK_WINDOW (d->details_dialog), TRUE);
      gtk_window_set_type_hint (GTK_WINDOW (d->details_dialog),
                                            GDK_WINDOW_TYPE_HINT_DIALOG);
      gtk_dialog_set_has_separator (GTK_DIALOG (d->details_dialog), FALSE);

      vbox = GTK_DIALOG (d->details_dialog)->vbox;
      gtk_widget_show (vbox);

      notebook = gtk_notebook_new ();

      d->details_notebook = notebook;

      gtk_widget_show (notebook);
      gtk_box_pack_start (GTK_BOX (vbox), notebook, TRUE, TRUE, 0);

      summary_table = gtk_table_new (3, 2, FALSE);
      gtk_widget_show (summary_table);
      gtk_container_add (GTK_CONTAINER (notebook), summary_table);
      gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (notebook), summary_table,
                                                            TRUE, TRUE, GTK_PACK_START);
      gtk_container_set_border_width (GTK_CONTAINER (summary_table), 12);
      gtk_table_set_row_spacings (GTK_TABLE (summary_table), 6);
      gtk_table_set_col_spacings (GTK_TABLE (summary_table), 6);

      details_calendar_label = gtk_label_new (_("Calendar:"));
      gtk_widget_show (details_calendar_label);
      gtk_table_attach (GTK_TABLE (summary_table), details_calendar_label,
                                0, 1, 0, 1,
                                (GtkAttachOptions) (GTK_FILL),
                                (GtkAttachOptions) (0), 0, 0);
      
      gtk_misc_set_alignment (GTK_MISC (details_calendar_label), 0, 0.5);

      d->details_calendar_combobox = gtk_combo_box_new_text ();
      gtk_widget_show (d->details_calendar_combobox);
      gtk_table_attach (GTK_TABLE (summary_table), d->details_calendar_combobox,
                                1, 2, 0, 1,
                                (GtkAttachOptions) (GTK_FILL),
                                (GtkAttachOptions) (GTK_FILL), 0, 0);
      gtk_combo_box_set_focus_on_click (GTK_COMBO_BOX (d->details_calendar_combobox),
                                                        FALSE);

      label = gtk_label_new (_("Summary:"));
      gtk_widget_show (label);
      gtk_table_attach (GTK_TABLE (summary_table), label, 0, 1, 1, 2,
                                (GtkAttachOptions) (GTK_FILL),
                                (GtkAttachOptions) (0), 0, 0);
      gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);

      d->details_summary_entry = gtk_entry_new ();
      gtk_widget_show (d->details_summary_entry);
      gtk_table_attach (GTK_TABLE (summary_table), d->details_summary_entry,
                                1, 2, 1, 2,
                                (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
                                (GtkAttachOptions) (0), 0, 0);
      gtk_entry_set_activates_default (GTK_ENTRY (d->details_summary_entry),
                                                       TRUE);

      label = gtk_label_new (_("Time:"));
      gtk_widget_show (label);
      gtk_table_attach (GTK_TABLE (summary_table), label, 0, 1, 2, 3,
                                (GtkAttachOptions) (GTK_FILL),
                                (GtkAttachOptions) (0), 0, 0);
      gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);

      alignment = gtk_alignment_new (0.5, 0.5, 0, 1);
      gtk_widget_show (alignment);
      gtk_table_attach (GTK_TABLE (summary_table), alignment, 1, 2, 2, 3,
                                (GtkAttachOptions) (GTK_FILL),
                                (GtkAttachOptions) (GTK_FILL), 0, 0);

      hbox = gtk_hbox_new (FALSE, 6);
      gtk_widget_show (hbox);
      gtk_container_add (GTK_CONTAINER (alignment), hbox);

      details_start_button = gtk_button_new ();
      gtk_widget_show (details_start_button);
      gtk_box_pack_start (GTK_BOX (hbox), details_start_button, TRUE, TRUE, 0);

      d->details_start_label = gtk_label_new (_("Start"));
      gtk_widget_show (d->details_start_label);
      gtk_container_add (GTK_CONTAINER (details_start_button),
                                 d->details_start_label);
      gtk_label_set_use_markup (GTK_LABEL (d->details_start_label), TRUE);
      gtk_label_set_justify (GTK_LABEL (d->details_start_label),
                                       GTK_JUSTIFY_CENTER);
      gtk_misc_set_padding (GTK_MISC (d->details_start_label), 3, 3);

      label = gtk_label_new (_("to"));
      gtk_widget_show (label);
      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);

      details_end_button = gtk_button_new ();
      gtk_widget_show (details_end_button);
      gtk_box_pack_start (GTK_BOX (hbox), details_end_button, TRUE, TRUE, 0);

      d->details_end_label = gtk_label_new (_("End"));
      gtk_widget_show (d->details_end_label);
      gtk_container_add (GTK_CONTAINER (details_end_button),
                                 d->details_end_label);
      gtk_label_set_justify (GTK_LABEL (d->details_end_label),
                                       GTK_JUSTIFY_CENTER);
      gtk_misc_set_padding (GTK_MISC (d->details_end_label), 3, 3);

      label = gtk_label_new (_("Summary"));
      gtk_widget_show (label);
      gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook),
                                                gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 0),
                                                label);

      details_table = gtk_table_new (1, 2, FALSE);
      gtk_widget_show (details_table);
      gtk_container_add (GTK_CONTAINER (notebook), details_table);
      gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (notebook), details_table,
                                                            TRUE, TRUE, GTK_PACK_START);
      gtk_container_set_border_width (GTK_CONTAINER (details_table), 12);
      gtk_table_set_row_spacings (GTK_TABLE (details_table), 6);
      gtk_table_set_col_spacings (GTK_TABLE (details_table), 6);

      label = gtk_label_new (_("Details:"));
      gtk_widget_show (label);
      gtk_table_attach (GTK_TABLE (details_table), label, 0, 1, 0, 1,
                                (GtkAttachOptions) (GTK_FILL),
                                (GtkAttachOptions) (0), 0, 0);
      gtk_misc_set_alignment (GTK_MISC (label), 0, 0);

      scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
      gtk_widget_show (scrolledwindow1);
      gtk_table_attach (GTK_TABLE (details_table), scrolledwindow1, 1, 2, 0, 1,
                                (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
                                (GtkAttachOptions) (GTK_EXPAND | GTK_SHRINK | GTK_FILL),
                                0, 0);
      gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow1),
                                                      GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
      gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(scrolledwindow1),
                                                             GTK_SHADOW_IN);

      d->details_textview = gtk_text_view_new ();
      gtk_widget_show (d->details_textview);
      gtk_container_add (GTK_CONTAINER (scrolledwindow1), d->details_textview);
      gtk_text_view_set_accepts_tab (GTK_TEXT_VIEW (d->details_textview), FALSE);
      gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (d->details_textview),
                                                 GTK_WRAP_WORD);

      label = gtk_label_new (_("Details"));
      gtk_widget_show (label);
      gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook),
                                                gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 1),
                                                label);
#if 0 /* not hooked up yet */
      recur_table = gtk_table_new (4, 2, FALSE);
      gtk_widget_show (recur_table);
      gtk_container_add (GTK_CONTAINER (notebook), recur_table);
      gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (notebook), recur_table,
                                                            TRUE, TRUE, GTK_PACK_START);
      gtk_container_set_border_width (GTK_CONTAINER (recur_table), 12);
      gtk_table_set_row_spacings (GTK_TABLE (recur_table), 6);
      gtk_table_set_col_spacings (GTK_TABLE (recur_table), 6);

      recur_repeats_label = gtk_label_new (_("Repeats:"));
      gtk_widget_show (recur_repeats_label);
      gtk_table_attach (GTK_TABLE (recur_table), recur_repeats_label, 0, 1, 0, 1,
                                (GtkAttachOptions) (GTK_FILL),
                                (GtkAttachOptions) (0), 0, 0);
      gtk_label_set_justify (GTK_LABEL (recur_repeats_label), GTK_JUSTIFY_RIGHT);
      gtk_misc_set_alignment (GTK_MISC (recur_repeats_label), 0, 0.5);

      recur_combobox = gtk_combo_box_new_text ();
      gtk_widget_show (recur_combobox);
      gtk_table_attach (GTK_TABLE (recur_table), recur_combobox, 1, 2, 0, 1,
                                (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
                                (GtkAttachOptions) (GTK_FILL), 0, 0);
      gtk_widget_set_sensitive (recur_combobox, FALSE);
      gtk_combo_box_append_text (GTK_COMBO_BOX (recur_combobox), _("None"));
      gtk_combo_box_append_text (GTK_COMBO_BOX (recur_combobox), _("Every Day"));
      gtk_combo_box_append_text (GTK_COMBO_BOX (recur_combobox),
                                             _("Every Week"));
      gtk_combo_box_append_text (GTK_COMBO_BOX (recur_combobox),
                                             _("Every Fortnight"));
      gtk_combo_box_append_text (GTK_COMBO_BOX (recur_combobox),
                                             _("Every Month"));
      gtk_combo_box_append_text (GTK_COMBO_BOX (recur_combobox),
                                             _("Every Year"));
      gtk_combo_box_append_text (GTK_COMBO_BOX (recur_combobox),
                                             _("Custom"));

      recur_on_label = gtk_label_new (_("On:"));
      gtk_table_attach (GTK_TABLE (recur_table), recur_on_label, 0, 1, 1, 2,
                                (GtkAttachOptions) (GTK_FILL),
                                (GtkAttachOptions) (0), 0, 0);
      gtk_misc_set_alignment (GTK_MISC (recur_on_label), 0, 0.5);

      recur_until_label = gtk_label_new (_("Until:"));
      gtk_table_attach (GTK_TABLE (recur_table), recur_until_label, 0, 1, 2, 3,
                                (GtkAttachOptions) (GTK_FILL),
                                (GtkAttachOptions) (0), 0, 0);
      gtk_label_set_justify (GTK_LABEL (recur_until_label), GTK_JUSTIFY_RIGHT);
      gtk_misc_set_alignment (GTK_MISC (recur_until_label), 0, 0.5);

      recur_until_button = gtk_button_new ();
      gtk_table_attach (GTK_TABLE (recur_table), recur_until_button, 1, 2, 2, 3,
                                (GtkAttachOptions) (GTK_FILL),
                                (GtkAttachOptions) (0), 0, 0);

      repeats_time_label = gtk_label_new (_("Forever"));
      gtk_widget_show (repeats_time_label);
      gtk_container_add (GTK_CONTAINER (recur_until_button), repeats_time_label);

      recur_week_hbox = gtk_hbox_new (TRUE, 0);
      gtk_table_attach (GTK_TABLE (recur_table), recur_week_hbox, 1, 2, 1, 2,
                                (GtkAttachOptions) (0),
                                (GtkAttachOptions) (GTK_FILL), 0, 0);

      togglebutton = gtk_toggle_button_new_with_mnemonic (_("Sun"));
      gtk_widget_show (togglebutton);
      gtk_box_pack_start (GTK_BOX (recur_week_hbox), togglebutton,
                                    TRUE, TRUE, 0);

      togglebutton = gtk_toggle_button_new_with_mnemonic (_("Mon"));
      gtk_widget_show (togglebutton);
      gtk_box_pack_start (GTK_BOX (recur_week_hbox), togglebutton,
                                    TRUE, TRUE, 0);

      togglebutton = gtk_toggle_button_new_with_mnemonic (_("Tue"));
      gtk_widget_show (togglebutton);
      gtk_box_pack_start (GTK_BOX (recur_week_hbox), togglebutton,
                                    TRUE, TRUE, 0);

      togglebutton = gtk_toggle_button_new_with_mnemonic (_("Wed"));
      gtk_widget_show (togglebutton);
      gtk_box_pack_start (GTK_BOX (recur_week_hbox), togglebutton,
                                    TRUE, TRUE, 0);

      togglebutton = gtk_toggle_button_new_with_mnemonic (_("Thu"));
      gtk_widget_show (togglebutton);
      gtk_box_pack_start (GTK_BOX (recur_week_hbox), togglebutton,
                                    TRUE, TRUE, 0);

      togglebutton = gtk_toggle_button_new_with_mnemonic (_("Fri"));
      gtk_widget_show (togglebutton);
      gtk_box_pack_start (GTK_BOX (recur_week_hbox), togglebutton,
                                    TRUE, TRUE, 0);

      togglebutton = gtk_toggle_button_new_with_mnemonic (_("Sat"));
      gtk_widget_show (togglebutton);
      gtk_box_pack_start (GTK_BOX (recur_week_hbox), togglebutton,
                                    TRUE, TRUE, 0);

      alignment = gtk_alignment_new (1, 1, 0, 0);
      gtk_widget_show (alignment);
      gtk_table_attach (GTK_TABLE (recur_table), alignment, 0, 2, 3, 4,
                                (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
                                (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);

      recur_except_button = gtk_button_new ();
      gtk_widget_show (recur_except_button);
      gtk_container_add (GTK_CONTAINER (alignment), recur_except_button);
      gtk_widget_set_sensitive (recur_except_button, FALSE);

      alignment = gtk_alignment_new (0.5, 0.5, 0, 0);
      gtk_widget_show (alignment);
      gtk_container_add (GTK_CONTAINER (recur_except_button), alignment);

      hbox = gtk_hbox_new (FALSE, 2);
      gtk_widget_show (hbox);
      gtk_container_add (GTK_CONTAINER (alignment), hbox);

      image = gtk_image_new_from_stock ("gtk-remove", GTK_ICON_SIZE_BUTTON);
      gtk_widget_show (image);
      gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);

      label = gtk_label_new_with_mnemonic (_("_Exceptions"));
      gtk_widget_show (label);
      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);

      label = gtk_label_new (_("Repeats"));
      gtk_widget_show (label);
      gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook),
                                                gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 2),
                                                label);
#endif
      d->details_delete_button = gtk_dialog_add_button (GTK_DIALOG (d->details_dialog),
                  "gtk-delete", GTK_RESPONSE_CLOSE);

      details_cancel_button = gtk_dialog_add_button (GTK_DIALOG (d->details_dialog),
                  "gtk-cancel", GTK_RESPONSE_CANCEL);

      details_ok_button = gtk_dialog_add_button (GTK_DIALOG (d->details_dialog),
                  "gtk-ok", GTK_RESPONSE_OK);

      gtk_widget_grab_focus (d->details_summary_entry);
      gtk_widget_grab_default (details_ok_button);
  
      g_signal_connect (G_OBJECT (d->details_dialog), "delete_event",
                                G_CALLBACK (dates_details_close_cb),
                                d);
      g_signal_connect (G_OBJECT (d->details_calendar_combobox), "changed",
                                G_CALLBACK (dates_calendar_combo_changed_cb),
                                d);
      g_signal_connect (G_OBJECT (details_start_button), "clicked",
                                G_CALLBACK (dates_details_time_start_cb),
                                d);
      g_signal_connect (G_OBJECT (details_end_button), "clicked",
                                G_CALLBACK (dates_details_time_end_cb),
                                d);
      g_signal_connect (G_OBJECT (d->details_delete_button), "clicked",
                                G_CALLBACK (dates_delete_cb),
                                d);
      g_signal_connect (G_OBJECT (details_cancel_button), "clicked",
                                G_CALLBACK (dates_details_cancel_cb),
                                d);
      g_signal_connect (G_OBJECT (details_ok_button), "clicked",
                                G_CALLBACK (dates_details_ok_cb),
                                d);

      return d->details_dialog;
}
#endif


#ifndef DATES_PLATFORM_create_time_dialog
static GtkWidget *
create_time_dialog (DatesData * d)
{
      GtkWidget *dialog_vbox2;
      GtkWidget *vbox1;
      GtkWidget *time_separator_label;
      GtkWidget *hour_button;
      GtkWidget *hour_up_button;
      GtkWidget *hour_up;
      GtkWidget *hour_down_button;
      GtkWidget *hour_down;
      GtkWidget *lminute_up_button;
      GtkWidget *lminute_up;
      GtkWidget *lminute_down_button;
      GtkWidget *lminute_down;
      GtkWidget *rminute_up_button;
      GtkWidget *rminute_up;
      GtkWidget *rminute_down_button;
      GtkWidget *rminute_down;
      GtkWidget *time_closebutton;

      d->time_dialog = gtk_dialog_new ();
      gtk_window_set_title (GTK_WINDOW (d->time_dialog), _("Time"));
      gtk_window_set_modal (GTK_WINDOW (d->time_dialog), TRUE);
      gtk_window_set_resizable (GTK_WINDOW (d->time_dialog), FALSE);
      gtk_window_set_icon_name (GTK_WINDOW (d->time_dialog), "stock_calendar");
      gtk_window_set_skip_taskbar_hint (GTK_WINDOW (d->time_dialog), TRUE);
      gtk_window_set_skip_pager_hint (GTK_WINDOW (d->time_dialog), TRUE);
      gtk_window_set_type_hint (GTK_WINDOW (d->time_dialog),
                                            GDK_WINDOW_TYPE_HINT_DIALOG);
      gtk_dialog_set_has_separator (GTK_DIALOG (d->time_dialog), FALSE);

      dialog_vbox2 = GTK_DIALOG (d->time_dialog)->vbox;
      gtk_widget_show (dialog_vbox2);

      vbox1 = gtk_vbox_new (FALSE, 12);
      gtk_widget_show (vbox1);
      gtk_box_pack_start (GTK_BOX (dialog_vbox2), vbox1, TRUE, TRUE, 0);
      gtk_container_set_border_width (GTK_CONTAINER (vbox1), 6);

      d->time_calendar = gtk_calendar_new ();
      gtk_widget_show (d->time_calendar);
      gtk_box_pack_start (GTK_BOX (vbox1), d->time_calendar, TRUE, TRUE, 0);
      gtk_calendar_display_options (GTK_CALENDAR (d->time_calendar),
                                                  GTK_CALENDAR_SHOW_HEADING
                                                  | GTK_CALENDAR_SHOW_DAY_NAMES);

      d->time_table = gtk_table_new (3, 5, FALSE);
      gtk_widget_show (d->time_table);
      gtk_box_pack_start (GTK_BOX (vbox1), d->time_table, TRUE, TRUE, 0);
      gtk_table_set_col_spacings (GTK_TABLE (d->time_table), 6);

      time_separator_label = gtk_label_new (_("<b>:</b>"));
      gtk_widget_show (time_separator_label);
      gtk_table_attach (GTK_TABLE (d->time_table), time_separator_label,
                                1, 2, 1, 2,
                                (GtkAttachOptions) (GTK_FILL),
                                (GtkAttachOptions) (GTK_FILL), 0, 0);
      gtk_label_set_use_markup (GTK_LABEL (time_separator_label), TRUE);

      hour_button = gtk_button_new_with_mnemonic (_("AM"));
      gtk_table_attach (GTK_TABLE (d->time_table), hour_button, 4, 5, 1, 2,
                                (GtkAttachOptions) (GTK_FILL),
                                (GtkAttachOptions) (0), 0, 0);

      d->lminute_entry = gtk_entry_new ();
      gtk_widget_show (d->lminute_entry);
      gtk_table_attach (GTK_TABLE (d->time_table), d->lminute_entry, 2, 3, 1, 2,
                                (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
                                (GtkAttachOptions) (0), 0, 0);
      gtk_entry_set_max_length (GTK_ENTRY (d->lminute_entry), 1);
      gtk_entry_set_activates_default (GTK_ENTRY (d->lminute_entry), TRUE);
      gtk_entry_set_width_chars (GTK_ENTRY (d->lminute_entry), 1);

      d->rminute_entry = gtk_entry_new ();
      gtk_widget_show (d->rminute_entry);
      gtk_table_attach (GTK_TABLE (d->time_table), d->rminute_entry, 3, 4, 1, 2,
                                (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
                                (GtkAttachOptions) (0), 0, 0);
      gtk_entry_set_max_length (GTK_ENTRY (d->rminute_entry), 1);
      gtk_entry_set_activates_default (GTK_ENTRY (d->rminute_entry), TRUE);
      gtk_entry_set_width_chars (GTK_ENTRY (d->rminute_entry), 1);

      hour_up_button = gtk_button_new ();
      gtk_widget_show (hour_up_button);
      gtk_table_attach (GTK_TABLE (d->time_table), hour_up_button, 0, 1, 0, 1,
                                (GtkAttachOptions) (GTK_FILL),
                                (GtkAttachOptions) (0), 0, 0);

      hour_up = gtk_arrow_new (GTK_ARROW_UP, GTK_SHADOW_OUT);
      gtk_widget_show (hour_up);
      gtk_container_add (GTK_CONTAINER (hour_up_button), hour_up);

      hour_down_button = gtk_button_new ();
      gtk_widget_show (hour_down_button);
      gtk_table_attach (GTK_TABLE (d->time_table), hour_down_button, 0, 1, 2, 3,
                                (GtkAttachOptions) (GTK_FILL),
                                (GtkAttachOptions) (0), 0, 0);

      hour_down = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_OUT);
      gtk_widget_show (hour_down);
      gtk_container_add (GTK_CONTAINER (hour_down_button), hour_down);

      lminute_up_button = gtk_button_new ();
      gtk_widget_show (lminute_up_button);
      gtk_table_attach (GTK_TABLE (d->time_table), lminute_up_button, 2, 3, 0, 1,
                                (GtkAttachOptions) (GTK_FILL),
                                (GtkAttachOptions) (0), 0, 0);

      lminute_up = gtk_arrow_new (GTK_ARROW_UP, GTK_SHADOW_OUT);
      gtk_widget_show (lminute_up);
      gtk_container_add (GTK_CONTAINER (lminute_up_button), lminute_up);

      lminute_down_button = gtk_button_new ();
      gtk_widget_show (lminute_down_button);
      gtk_table_attach (GTK_TABLE (d->time_table), lminute_down_button,
                                2, 3, 2, 3,
                                (GtkAttachOptions) (GTK_FILL),
                                (GtkAttachOptions) (0), 0, 0);

      lminute_down = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_OUT);
      gtk_widget_show (lminute_down);
      gtk_container_add (GTK_CONTAINER (lminute_down_button), lminute_down);

      rminute_up_button = gtk_button_new ();
      gtk_widget_show (rminute_up_button);
      gtk_table_attach (GTK_TABLE (d->time_table), rminute_up_button, 3, 4, 0, 1,
                                (GtkAttachOptions) (GTK_FILL),
                                (GtkAttachOptions) (0), 0, 0);

      rminute_up = gtk_arrow_new (GTK_ARROW_UP, GTK_SHADOW_OUT);
      gtk_widget_show (rminute_up);
      gtk_container_add (GTK_CONTAINER (rminute_up_button), rminute_up);

      rminute_down_button = gtk_button_new ();
      gtk_widget_show (rminute_down_button);
      gtk_table_attach (GTK_TABLE (d->time_table), rminute_down_button,
                                3, 4, 2, 3,
                                (GtkAttachOptions) (GTK_FILL),
                                (GtkAttachOptions) (0), 0, 0);

      rminute_down = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_OUT);
      gtk_widget_show (rminute_down);
      gtk_container_add (GTK_CONTAINER (rminute_down_button), rminute_down);

      d->hour_entry = gtk_entry_new ();
      gtk_widget_show (d->hour_entry);
      gtk_table_attach (GTK_TABLE (d->time_table), d->hour_entry, 0, 1, 1, 2,
                                (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
                                (GtkAttachOptions) (0), 0, 0);
      gtk_entry_set_max_length (GTK_ENTRY (d->hour_entry), 2);
      gtk_entry_set_activates_default (GTK_ENTRY (d->hour_entry), TRUE);
      gtk_entry_set_width_chars (GTK_ENTRY (d->hour_entry), 2);

      d->time_forever_checkbutton =
            gtk_check_button_new_with_mnemonic (_("Forever"));
      
      gtk_widget_show (d->time_forever_checkbutton);
      gtk_box_pack_start (GTK_BOX (vbox1), d->time_forever_checkbutton,
                                    FALSE, FALSE, 0);

      time_closebutton = gtk_dialog_add_button (GTK_DIALOG (d->time_dialog),
                  "gtk-close", GTK_RESPONSE_CLOSE);

      gtk_widget_grab_focus (time_closebutton);
      gtk_widget_grab_default (time_closebutton);
  
      g_signal_connect (G_OBJECT (d->lminute_entry), "insert_text",
                                G_CALLBACK (dates_details_time_entry_changed),
                                d);
      g_signal_connect (G_OBJECT (d->rminute_entry), "insert_text",
                                G_CALLBACK (dates_details_time_entry_changed),
                                d);
      g_signal_connect (G_OBJECT (hour_up_button), "clicked",
                                G_CALLBACK (dates_details_time_hour_cb),
                                d);
      g_signal_connect (G_OBJECT (hour_down_button), "clicked",
                                G_CALLBACK (dates_details_time_hour_cb),
                                d);
      g_signal_connect (G_OBJECT (lminute_up_button), "clicked",
                                G_CALLBACK (dates_details_time_lminute_cb),
                                d);
      g_signal_connect (G_OBJECT (lminute_down_button), "clicked",
                                G_CALLBACK (dates_details_time_lminute_cb),
                                d);
      g_signal_connect (G_OBJECT (rminute_up_button), "clicked",
                                G_CALLBACK (dates_details_time_rminute_cb),
                                d);
      g_signal_connect (G_OBJECT (rminute_down_button), "clicked",
                                G_CALLBACK (dates_details_time_rminute_cb),
                                d);
      g_signal_connect (G_OBJECT (d->hour_entry), "insert_text",
                                G_CALLBACK (dates_details_time_entry_changed),
                                d);

      return d->time_dialog;
}
#endif


#ifndef DATES_PLATFORM_repeats_dialog
static GtkWidget *
create_repeats_dialog (DatesData * d)
{
      /* TODO */
      d->repeats_dialog = NULL;
      return d->repeats_dialog;
}
#endif

#define DATES_RESPONSE_DELETE 1

#ifndef DATES_PLATFORM_new_calendar_dialog
static void
entry_changed (GtkEditable *editable, gpointer user_data)
{
      /* 
       * User data is the okay button. We want to set it insensitive if the
       * contents of the text entry is empty.
       */
      GtkWidget *button = GTK_WIDGET (user_data);
      gchar *text = NULL;

      text = g_strdup(gtk_entry_get_text (GTK_ENTRY (editable)));

      g_strstrip (text);

      if (strlen (text) == 0)
            gtk_widget_set_sensitive (button, FALSE);
      else
            gtk_widget_set_sensitive (button, TRUE);

      g_free (text);
}

static void
combo_box_changed (GtkComboBox *widget, gpointer user_data)
{
      /* The user_data is the hbox for the URI. We need to decide whether to
       * show or hide it */
      GtkTreeModel *model;
      GtkTreeIter iter;
      GtkWidget *hbox = *((GtkWidget **)user_data);

      model = gtk_combo_box_get_model (widget);

      if (gtk_combo_box_get_active_iter (widget, &iter))
      {
            ESourceGroup *group;
            const gchar *base_uri;
            gtk_tree_model_get (model, &iter, 1, &group, -1);

            base_uri = e_source_group_peek_base_uri (group);
            
            if (strncmp (base_uri, "webcal://", 9) == 0)
            {
                  gtk_widget_show_all (GTK_WIDGET (hbox));
            } else {
                  gtk_widget_hide_all (GTK_WIDGET (hbox));
            }
      }
}

void
calendar_do_new_dialog (GtkWindow *parent, DatesData *d)
{
      GtkWidget *dialog = NULL;
      GtkWidget *frame = NULL;
      GtkWidget *name_entry = NULL;
      GtkWidget *uri_entry = NULL;
      GtkWidget *vbox = NULL;
      GtkWidget *hbox = NULL;
      GtkWidget *uri_hbox = NULL;
      GtkWidget *label = NULL;
      GtkWidget *type_combo = NULL;
      GtkWidget *color_button = NULL;
      GtkWidget *okay_button = NULL;

      GtkSizeGroup *horizontal_size;

      GSList *group_list = NULL;
      GSList *cur_entry = NULL;

      GtkListStore *type_store = NULL;
      GtkCellRenderer *renderer = NULL;

      GdkColor colour;

      const gchar *uri = NULL;

      gint res; /* result for the dialog */

      /* Create the dialog */
      dialog = gtk_dialog_new_with_buttons (_("New calendar"), 
                parent, 
                GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
                GTK_STOCK_CANCEL,
                GTK_RESPONSE_CANCEL,
                NULL);

      /* 
       * Add the OK button separately so that we can keep a pointer to the
       * widget
       */
      okay_button = gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_OK);

      /* Make it insentive by default */
      gtk_widget_set_sensitive (okay_button, FALSE);

      /* Create the frame */
      frame = gtk_frame_new (NULL);

      /* Create the label */
      label = gtk_label_new (_("<b>Calendar</b>"));

      /* Turn on the markup for the label */
      gtk_label_set_use_markup (GTK_LABEL (label), TRUE);

      /* Set this to be the label for the frame */
      gtk_frame_set_label_widget (GTK_FRAME (frame), label);

      /* Remove the shadow */
      gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);

      /* Set a border of 12 (HIG) */
      gtk_container_set_border_width (GTK_CONTAINER (frame), 12);

      /* Place the alignment inside the dialog */
      gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), frame);

      /* Create the vbox for inside the frame */
      vbox = gtk_vbox_new (FALSE, 6);

      /* Set a border of 12 (HIG) */
      gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);

      /* Place the vbox inside the frame */
      gtk_container_add (GTK_CONTAINER (frame), vbox);

      /* Create a size group for the labels on the left hand side */
      horizontal_size = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);

      /* Stuff for the type */

      /* Create hbox for the type */
      hbox = gtk_hbox_new (FALSE, 6);

      /* Create the label for the type */
      label = gtk_label_new (_("Type:"));

      /* Align the text in the label to the left */
      gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);

      /* Add the label to the size group */
      gtk_size_group_add_widget (horizontal_size, label);

      /* Add the label to the hbox */
      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);

      /* Create the model for the combo box */
      type_store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_POINTER);

      /* Get the list of groups from the list of sources */
      group_list = e_source_list_peek_groups (d->source_list);

      /* Create the combo for the type */
      type_combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL(type_store));

      for (cur_entry = group_list; cur_entry != NULL; cur_entry = g_slist_next (cur_entry))
      {
            ESourceGroup *group = (ESourceGroup *)(cur_entry->data);
            const gchar *base_uri = e_source_group_peek_base_uri (group);

            if (strncmp (base_uri, "webcal://", 9) == 0 || 
                        strncmp (base_uri, "file://", 7) == 0)
            {
                  GtkTreeIter iter;
                  gtk_list_store_append (type_store, &iter);
                  gtk_list_store_set (type_store, &iter, 
                              0, e_source_group_peek_name (group),
                              1, group,
                              -1);

                  if (strncmp (base_uri, "file://", 7) == 0)
                        gtk_combo_box_set_active_iter (GTK_COMBO_BOX (type_combo), &iter);
            }
      }

      /* Create a renderer for the column */
      renderer = gtk_cell_renderer_text_new ();
      gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (type_combo), renderer, TRUE);
      gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (type_combo), renderer,
                  "text", 0,
                  NULL);

      g_signal_connect (type_combo, "changed", (GCallback)combo_box_changed, &uri_hbox);

      /* Add the combo */
      gtk_box_pack_start (GTK_BOX (hbox), type_combo, TRUE, TRUE, 0);

      /* Add the hbox to the vbox */
      gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);

      /* Stuff for the name label/entry */

      /* Create the hbox for the name */
      hbox = gtk_hbox_new (FALSE, 6);

      /* Create the label for the name */
      label = gtk_label_new_with_mnemonic (_("_Name:"));

      /* Align the text in the label to the left */
      gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);

      /* Create the text entry for the name of the calendar */
      name_entry = gtk_entry_new ();

      /* Mark the mnemonic for the label to the entry widget */
      gtk_label_set_mnemonic_widget (GTK_LABEL(label), name_entry);

      /* Add the label to the hbox */
      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);

      /* Add the entry to the hbox */
      gtk_box_pack_start (GTK_BOX (hbox), name_entry, TRUE, TRUE, 0);

      /* 
       * Connect a signal handler onto the entry's changed signal to
       * control whether to turn on the OK button.
       */
      g_signal_connect (name_entry, "changed", (GCallback)entry_changed, okay_button);

      /* Add the label to the size group */
      gtk_size_group_add_widget (horizontal_size, label);

      /* Add the hbox to the vbox */
      gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);


      /* Create the hbox for the colour */
      hbox = gtk_hbox_new (FALSE, 6);

      /* Create the label for the name */
      label = gtk_label_new_with_mnemonic (_("_Colour:"));

      /* Align the text in the label to the left */
      gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);

      /* Create a new colour button */
#ifdef USE_OWL
      color_button = owl_colour_button_new ();
#else

#ifdef WITH_HILDON
      color_button = hildon_color_button_new ();
#else
      color_button = gtk_color_button_new ();
#endif
#endif
      /* Add the label to the hbox */
      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);

      /* Add the label to the size group */
      gtk_size_group_add_widget (horizontal_size, label);
      

      /* Add the color button to the hbox */
      gtk_box_pack_start (GTK_BOX (hbox), color_button, TRUE, TRUE, 0);

      /* Add the hbox to the vbox */
      gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);

      /* Make the internal vbox visible */
      gtk_widget_show_all (GTK_DIALOG (dialog)->vbox);

      /* Stuff for the uri. Note that we show everything else before this
       * since we want to control the visibility based on combo */

      /* Create the hbox for the uri */
      uri_hbox = gtk_hbox_new (FALSE, 6);

      /* Create the label for the uri */
      label = gtk_label_new_with_mnemonic (_("_Location:"));

      /* Align the text in the label to the left */
      gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);

      /* Create the text entry for the uri of the calendar */
      uri_entry = gtk_entry_new ();

      /* Mark the mnemonic for the label to the entry widget */
      gtk_label_set_mnemonic_widget (GTK_LABEL(label), uri_entry);

      /* Add the label to the hbox */
      gtk_box_pack_start (GTK_BOX (uri_hbox), label, FALSE, FALSE, 0);

      /* Add the label to the size group */
      gtk_size_group_add_widget (horizontal_size, label);

      /* Add the entry to the hbox */
      gtk_box_pack_start (GTK_BOX (uri_hbox), uri_entry, TRUE, TRUE, 0);

      /* Add the hbox to the vbox */
      gtk_box_pack_start (GTK_BOX (vbox), uri_hbox, TRUE, TRUE, 0);


      /* Make the dialog non-resizeable */
      gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);

      /* Show the dialog and capture the response */
      res = gtk_dialog_run (GTK_DIALOG (dialog));

      switch (res)
      {
            case GTK_RESPONSE_OK:
            {
                  ESource *source;
                  const gchar *name =  NULL;
                  ESourceGroup *group;
                  GtkTreeIter iter;
                  GError *error = NULL;
                  const gchar *relative_uri;
                  guint32 new_colour;

#ifdef WITH_HILDON
                  GdkColor *hildon_color;
#endif

                  /* Get the name from the text entry */
                  name = gtk_entry_get_text (GTK_ENTRY(name_entry));

                  /* Get the appropriate group from the combo box */
                  if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX(type_combo), &iter))
                  {
                        gtk_tree_model_get (GTK_TREE_MODEL(type_store), &iter, 1, &group, -1);
                  }
                  
                  if (strncmp (e_source_group_peek_base_uri (group), "webcal://", 9) == 0)
                  {
                        /* Get the uri from the text entry */
                        uri = gtk_entry_get_text (GTK_ENTRY(uri_entry));

                        if (strncmp (uri, "webcal://", 9) == 0)
                        {
                              relative_uri = &uri[9];
                        } else {
                              if (strncmp (uri, "http://", 7) == 0)
                              {
                                    relative_uri = &uri[7];
                              } else {
                                    relative_uri = uri;
                              }
                        }
                  } else {
                        relative_uri = e_cal_component_gen_uid ();
                  }

                  /* Create a new source to use */
                  source = e_source_new (name, relative_uri);

#ifdef USE_OWL
                  new_colour = owl_colour_button_get_colour (OWL_COLOUR_BUTTON (color_button));
#else

#ifdef WITH_HILDON
                  hildon_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON(color_button));
                  colour = *hildon_color;
#else
                  gtk_color_button_get_color (GTK_COLOR_BUTTON(color_button), &colour);
#endif
                  new_colour = (guint8)(colour.red >> 8);
                  new_colour <<= 8;
                  new_colour |= (guint8)(colour.green >> 8);
                  new_colour <<= 8;
                  new_colour |= (guint8)(colour.blue >> 8);
                  new_colour <<= 8;
#endif

                  /* Set the colour */
                  e_source_set_color (source, new_colour);

                  /* Set the group for the source */
                  e_source_set_group (source, group);
                  e_source_group_add_source (group, source, 0);

                  /* 
                   * We must sync our list of sources with the version
                   * in gconf.
                   */
                  if (!e_source_list_sync (d->source_list, &error))
                  {
                        g_warning ("Error syncing ESourceList: %s",
                                 error->message);
                        g_error_free (error);
                  }
            }
      }

      gtk_widget_destroy (dialog);
}
#endif

#ifndef DATES_PLATFORM_calendar_edit_dialog

/* 
 * We need to explicitly hook into the response signal to deal with the delete
 * case since if the user hits cancel we need to stop the signal in its tracks
 * so that the user can use the other buttons in the dialog if they decide to
 * cancel the delete.
 */
static void
calendar_do_edit_dialog_response_cb (GtkDialog *dialog, gint response_id, gpointer user_data)
{
      if (response_id == DATES_RESPONSE_DELETE)
      {
            GtkWidget *delete_dialog;
            gint res;
            gchar *prompt = NULL;

            gchar *name = (gchar *)user_data;

            prompt = g_strdup_printf (_("Are you sure you want to delete the calendar named '%s'?"), name);

            delete_dialog = gtk_message_dialog_new (GTK_WINDOW(dialog),
                        GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
                        GTK_MESSAGE_WARNING,
                        GTK_BUTTONS_NONE,
                        prompt);

            g_free (prompt);

            gtk_dialog_add_buttons (GTK_DIALOG (delete_dialog), 
                        GTK_STOCK_CANCEL,
                        GTK_RESPONSE_CANCEL,
                        GTK_STOCK_DELETE,
                        DATES_RESPONSE_DELETE,
                        NULL);

            res = gtk_dialog_run (GTK_DIALOG (delete_dialog));

            if (res == DATES_RESPONSE_DELETE)
            {
                  /* Let gtk_dialog_run return and then deal with stuff there */
                  return;
            } else {
                  /* 
                   * Stop the 'response' signal in its tracks
                   * and therefore continue to keep the other
                   * buttons in them main dialog responsive
                   */
                  g_signal_stop_emission_by_name (dialog, "response");
                  gtk_widget_destroy (delete_dialog);
            }
      }

}

void
calendar_do_edit_dialog (GtkWindow *parent, ESource *source, DatesData *d)
{
      GtkWidget *dialog = NULL;
      GtkWidget *frame = NULL;
      GtkWidget *name_entry = NULL;
      GtkWidget *uri_entry = NULL;
      GtkWidget *vbox = NULL;
      GtkWidget *hbox = NULL;
      GtkWidget *label = NULL;
      GtkWidget *type_label = NULL;
      GtkWidget *color_button = NULL;
      GtkWidget *okay_button = NULL;

      GtkSizeGroup *horizontal_size;

      ESourceGroup *group;

      GdkColor colour;
      guint32 raw_colour;

      const gchar *name = NULL;
      const gchar *uri = NULL;
      gchar *type = NULL;

      gboolean remote = FALSE;

      gint res; /* result for the dialog */

      /* 
       * Check if this is the system calendar or not. We shouldn't let it be
       * deleted.
       */
      if (strncmp (e_source_peek_relative_uri (source), "system", 6) == 0)
      {
            /* Create the dialog */
            dialog = gtk_dialog_new_with_buttons (_("Edit calendar"), 
                      parent, 
                      GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
                      GTK_STOCK_CANCEL,
                      GTK_RESPONSE_CANCEL,
                      NULL);
      } else {
            /* Create the dialog */
            dialog = gtk_dialog_new_with_buttons (_("Edit calendar"), 
                      parent, 
                      GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
                      GTK_STOCK_DELETE,
                      DATES_RESPONSE_DELETE,
                      GTK_STOCK_CANCEL,
                      GTK_RESPONSE_CANCEL,
                      NULL);
      }

      /* 
       * Add the OK button separately so that we can keep a pointer to the
       * widget
       */
      okay_button = gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_OK);

      /* Get the group for the source */
      group = e_source_peek_group (source);

      /* Create the frame */
      frame = gtk_frame_new (NULL);

      /* Create the label */
      label = gtk_label_new (_("<b>Calendar</b>"));

      /* Turn on the markup for the label */
      gtk_label_set_use_markup (GTK_LABEL (label), TRUE);

      /* Set this to be the label for the frame */
      gtk_frame_set_label_widget (GTK_FRAME (frame), label);

      /* Remove the shadow */
      gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);

      /* Set a border of 12 (HIG) */
      gtk_container_set_border_width (GTK_CONTAINER (frame), 12);

      /* Place the alignment inside the dialog */
      gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), frame);

      /* Create the vbox for inside the frame */
      vbox = gtk_vbox_new (FALSE, 6);

      /* Set a border of 12 (HIG) */
      gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);

      /* Place the vbox inside the frame */
      gtk_container_add (GTK_CONTAINER (frame), vbox);

      /* Create a size group for the labels on the left hand side */
      horizontal_size = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);

      /* Stuff for the type */

      /* Create hbox for the type */
      hbox = gtk_hbox_new (FALSE, 6);

      /* Create the label for the type */
      label = gtk_label_new (_("Type:"));

      /* Align the text in the label to the left */
      gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);

      /* Grab the type from the group name */
      type = g_strdup_printf ("<b>%s</b>", e_source_group_peek_name (group));

      /* Create a second label for the type string itself */
      type_label = gtk_label_new (type);

      /* Turn on the markup for the label */
      gtk_label_set_use_markup (GTK_LABEL (type_label), TRUE);

      /* Align the text in the label to the left */
      gtk_misc_set_alignment (GTK_MISC (type_label), 0, 0.5);

      /* Add the label to the size group */
      gtk_size_group_add_widget (horizontal_size, label);

      /* Add the two labels to the hbox */
      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
      gtk_box_pack_start (GTK_BOX (hbox), type_label, TRUE, TRUE, 0);

      /* Add the hbox to the vbox */
      gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);

      /* Stuff for the name label/entry */

      /* Create the hbox for the name */
      hbox = gtk_hbox_new (FALSE, 6);

      /* Create the label for the name */
      label = gtk_label_new_with_mnemonic (_("_Name:"));

      /* Align the text in the label to the left */
      gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);

      /* Create the text entry for the name of the calendar */
      name_entry = gtk_entry_new ();

      /* Mark the mnemonic for the label to the entry widget */
      gtk_label_set_mnemonic_widget (GTK_LABEL(label), name_entry);

      /* Add the label to the hbox */
      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);

      /* Add the entry to the hbox */
      gtk_box_pack_start (GTK_BOX (hbox), name_entry, TRUE, TRUE, 0);

      /* Add the label to the size group */
      gtk_size_group_add_widget (horizontal_size, label);

      /* Add the hbox to the vbox */
      gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);

      /* Get the name from the source */
      name = e_source_peek_name (source);

      /* Set the entry to the name */
      gtk_entry_set_text (GTK_ENTRY (name_entry), name);

      /* 
       * Connect a signal handler onto the entry's changed signal to
       * control whether to turn on the OK button.
       */
      g_signal_connect (name_entry, "changed", (GCallback)entry_changed, okay_button);

      /* Stuff for the colour button */

      /* Create the hbox for the colour */
      hbox = gtk_hbox_new (FALSE, 6);

      /* Create the label for the name */
      label = gtk_label_new_with_mnemonic (_("_Colour:"));

      /* Align the text in the label to the left */
      gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);

      /* Get the colour from the the source */
      e_source_get_color (source, &raw_colour);

      /* Munge this into something usable */
      colour.red = (guint16)(((raw_colour & 0xff0000) >> 16) << 8);
      colour.green = (guint16)(((raw_colour & 0xff00) >> 8) << 8);
      colour.blue = (guint16)(((raw_colour & 0xff) << 8));

      /* Now we need to allocate the colour */
      gdk_colormap_alloc_color (gdk_colormap_get_system (), &colour, TRUE, TRUE);

#ifdef USE_OWL
      color_button = owl_colour_button_new ();
      owl_colour_button_set_colour (OWL_COLOUR_BUTTON (color_button), raw_colour << 8);
#else

#ifdef WITH_HILDON
      color_button = hildon_color_button_new_with_color (&colour);
#else
      color_button = gtk_color_button_new_with_color (&colour);
#endif
#endif

      /* Add the label to the hbox */
      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);

      /* Add the label to the size group */
      gtk_size_group_add_widget (horizontal_size, label);
      

      /* Add the color button to the hbox */
      gtk_box_pack_start (GTK_BOX (hbox), color_button, TRUE, TRUE, 0);

      /* Add the hbox to the vbox */
      gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);

      /* Stuff for the uri label/entry */

      /* 
       * We only want to show the URI iff the source is from a webcal://
       * based group
       */

      if (strncmp (e_source_group_peek_base_uri (group), "webcal://", 9) == 0)
      {
            remote = TRUE;
            
            /* Create the hbox for the uri */
            hbox = gtk_hbox_new (FALSE, 6);

            /* Create the label for the uri */
            label = gtk_label_new_with_mnemonic (_("_Location:"));

            /* Align the text in the label to the left */
            gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);

            /* Create the text entry for the uri of the calendar */
            uri_entry = gtk_entry_new ();

            /* Mark the mnemonic for the label to the entry widget */
            gtk_label_set_mnemonic_widget (GTK_LABEL(label), uri_entry);

            /* Add the label to the hbox */
            gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);

            /* Add the label to the size group */
            gtk_size_group_add_widget (horizontal_size, label);

            /* Add the entry to the hbox */
            gtk_box_pack_start (GTK_BOX (hbox), uri_entry, TRUE, TRUE, 0);

            /* Add the hbox to the vbox */
            gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);

            /* Get the URI */
            uri = g_strdup_printf ("%s%s", e_source_group_peek_base_uri (group), 
                        e_source_peek_relative_uri (source));

            /* Set the entry to the uri */
            gtk_entry_set_text (GTK_ENTRY (uri_entry), uri);
      }

      /* Make the internal vbox visible */
      gtk_widget_show_all (GTK_DIALOG (dialog)->vbox);

      /* Make the dialog non-resizeable */
      gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);

      /* Connect a signal handler to the response signal to deal with
       * bringing up a confirmation dialog for the delete button.
       */

      g_signal_connect (dialog, "response", 
                  G_CALLBACK(calendar_do_edit_dialog_response_cb), (gpointer)name);

      /* Show the dialog and capture the response */
      res = gtk_dialog_run (GTK_DIALOG (dialog));

      switch (res)
      {
            case GTK_RESPONSE_OK:
            {
                  /* 
                   * Next we need to pack the GDK colour into guint32
                   * for eds
                   */
                  guint32 new_colour = 0;

                  GError *error = NULL;
#ifdef USE_OWL
                  new_colour = owl_colour_button_get_colour (OWL_COLOUR_BUTTON (color_button));
#else
#ifdef WITH_HILDON
                  GdkColor *hildon_color;
                  hildon_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON(color_button));
                  colour = *hildon_color;
#else
                  gtk_color_button_get_color (GTK_COLOR_BUTTON(color_button), &colour);
#endif                  
                  new_colour = (guint8)(colour.red >> 8);
                  new_colour <<= 8;
                  new_colour |= (guint8)(colour.green >> 8);
                  new_colour <<= 8;
                  new_colour |= (guint8)(colour.blue >> 8);
                  new_colour <<= 8;
#endif
                  /* Update the colour */
                  e_source_set_color (source, new_colour);

                  /* And the name */
                  e_source_set_name (source, (gtk_entry_get_text (GTK_ENTRY (name_entry))));

                  if (remote)
                  {
                        const gchar *new_uri = gtk_entry_get_text (GTK_ENTRY(uri_entry));

                        /* e_source_set_absolute_uri doesn't work. */

                        /* Support webcal links */
                        if (strncmp (new_uri, "webcal://", 9) == 0)
                        {
                              e_source_set_relative_uri (source, &new_uri[9]);
                        } else {
                              /* But also support http links */
                              if (strncmp (new_uri, "http://", 7) == 0)
                              {
                                    e_source_set_relative_uri (source, &new_uri[7]);
                              } else {
                                    e_source_set_relative_uri (source, new_uri);
                              }
                        }
                  }

                  gtk_widget_destroy (dialog);

                  /* 
                   * We must sync our list of sources with the version
                   * in gconf.
                   */
                  if (!e_source_list_sync (d->source_list, &error))
                  {
                        g_warning ("Error syncing ESourceList: %s",
                                 error->message);
                        g_error_free (error);
                  }


                  break;
            }

            case DATES_RESPONSE_DELETE:
            {
                  GError *error = NULL;
                  /* Delete this one */
                  e_source_list_remove_source_by_uid (d->source_list,e_source_peek_uid (source));

                  /* 
                   * We must sync our list of sources with the version
                   * in gconf.
                   */
                  if (!e_source_list_sync (d->source_list, &error))
                  {
                        g_warning ("Error syncing ESourceList: %s",
                                 error->message);
                        g_error_free (error);
                  }

                  gtk_widget_destroy (dialog);

                  break;
            }
            default:
                  gtk_widget_destroy (dialog);
                  break;
      }

      g_free (type);
}

#endif

#ifndef DATES_PLATFORM_calendars_dialog

enum {
      CALENDARS_DLG_NEW,
      CALENDARS_DLG_EDIT,
      CALENDARS_DLG_DELETE,
      CALENDARS_DLG_CLOSE     
};

static void
calendars_response_cb (GtkDialog *dialog, gint id, gpointer data)
{
      DatesData * d = data;

      switch (id)
      {
            case CALENDARS_DLG_NEW:
                  calendar_do_new_dialog (GTK_WINDOW(d->main_window), d);
                  break;
            case CALENDARS_DLG_EDIT:
            {
                  GtkTreeSelection *selection = NULL; 
                  GtkTreeIter iter;
                  GtkTreeModel *model = NULL;
                  
                  /* First get the selection from the tree view */
                  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(d->cal_tree_view));
                  
                  /* If there is something selected */
                  if (gtk_tree_selection_get_selected (selection, &model, &iter))
                  {
                        ECal *ecal;
                        ESource *source;
                        gtk_tree_model_get (model, &iter, COL_CALPTR, &ecal, -1);
                        
                        if (ecal != NULL)
                        {
                              source = e_cal_get_source (ecal);
                              calendar_do_edit_dialog (GTK_WINDOW(d->main_window), source, d);
                        }
                  }
                  break;
            }
            case CALENDARS_DLG_CLOSE:
            case GTK_RESPONSE_NONE:
            case GTK_RESPONSE_DELETE_EVENT:
                  dates_platform_calendars_dlg (d, FALSE);
                  break;

            default:
                  g_debug ("Unknown/unimplemented response signal %d", id);
      }

}

static GtkWidget *
create_calendars_dialog (DatesData * d)
{
      GtkWidget *vbox2;
      GtkWidget *scrolledwindow2;
      GtkWidget *cal_new_button;
      GtkWidget *cal_edit_button;
      GtkWidget *cal_close_button;

      d->calendars_dialog = gtk_dialog_new ();
      gtk_window_set_title (GTK_WINDOW (d->calendars_dialog), Q_("Calendars"));
      gtk_window_set_position (GTK_WINDOW (d->calendars_dialog),
                                           GTK_WIN_POS_CENTER_ON_PARENT);
      gtk_window_set_modal (GTK_WINDOW (d->calendars_dialog), TRUE);
      gtk_window_set_default_size (GTK_WINDOW (d->calendars_dialog), -1, 256);
      gtk_window_set_skip_taskbar_hint (GTK_WINDOW (d->calendars_dialog), TRUE);
      gtk_window_set_skip_pager_hint (GTK_WINDOW (d->calendars_dialog), TRUE);
      gtk_window_set_type_hint (GTK_WINDOW (d->calendars_dialog),
                                            GDK_WINDOW_TYPE_HINT_DIALOG);
      gtk_dialog_set_has_separator (GTK_DIALOG (d->calendars_dialog), FALSE);

      vbox2 = GTK_DIALOG (d->calendars_dialog)->vbox;
      gtk_widget_show (vbox2);

      scrolledwindow2 = gtk_scrolled_window_new (NULL, NULL);
      gtk_widget_show (scrolledwindow2);
      gtk_box_pack_start (GTK_BOX (vbox2), scrolledwindow2, TRUE, TRUE, 6);
      GTK_WIDGET_UNSET_FLAGS (scrolledwindow2, GTK_CAN_FOCUS);
      gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow2),
                                                      GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
      gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow2),
                                                             GTK_SHADOW_IN);

      d->cal_tree_view = gtk_tree_view_new ();

#ifdef WITH_HILDON
      /* Disable the Hildon "feature" that breaks the behaviour of first
       * Toggle in the view
       */
      g_object_set(G_OBJECT(d->cal_tree_view),
                         "allow-checkbox-mode", FALSE, NULL);     
#endif
      
      gtk_widget_show (d->cal_tree_view);
      gtk_container_add (GTK_CONTAINER (scrolledwindow2), d->cal_tree_view);
      GTK_WIDGET_UNSET_FLAGS (d->cal_tree_view, GTK_CAN_FOCUS);
      gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (d->cal_tree_view),
                                                         FALSE);

      cal_new_button = gtk_dialog_add_button (GTK_DIALOG (d->calendars_dialog),
                  "gtk-new", CALENDARS_DLG_NEW);

      cal_edit_button = gtk_dialog_add_button (GTK_DIALOG (d->calendars_dialog),
                  "gtk-edit", CALENDARS_DLG_EDIT);

/*
      cal_delete_button = gtk_button_new_from_stock ("gtk-delete");
      gtk_widget_show (cal_delete_button);
      gtk_dialog_add_action_widget (GTK_DIALOG (d->calendars_dialog),
                                                  cal_delete_button, CALENDARS_DLG_DELETE);
      GTK_WIDGET_UNSET_FLAGS (cal_delete_button, GTK_CAN_FOCUS);
      GTK_WIDGET_SET_FLAGS (cal_delete_button, GTK_CAN_DEFAULT);
      gtk_widget_grab_default (cal_delete_button);
*/    

      cal_close_button = gtk_button_new_from_stock ("gtk-close");
      gtk_widget_show (cal_close_button);
      gtk_dialog_add_action_widget (GTK_DIALOG (d->calendars_dialog),
                                                  cal_close_button, CALENDARS_DLG_CLOSE);
      
      GTK_WIDGET_UNSET_FLAGS (cal_close_button, GTK_CAN_FOCUS);
      GTK_WIDGET_SET_FLAGS (cal_close_button, GTK_CAN_DEFAULT);

      g_signal_connect (G_OBJECT (d->calendars_dialog), "delete_event",
                                G_CALLBACK (gtk_widget_hide), d);
      
      g_signal_connect (G_OBJECT (d->calendars_dialog), "response",
                                G_CALLBACK (calendars_response_cb), d);

      return d->calendars_dialog;
}
#endif


#ifndef DATES_PLATFORM_create_exceptions_dialog
static GtkWidget *
create_exceptions_dialog (DatesData *d)
{
      GtkWidget *dialog_vbox3;
      GtkWidget *exceptions_table;
      GtkWidget *recurrences_help_image;
      GtkWidget *recurrences_help_label;
      GtkWidget *recurrences_calendar;
      GtkWidget *repeats_close_button;

      d->exceptions_dialog = gtk_dialog_new ();
      gtk_window_set_title (GTK_WINDOW (d->exceptions_dialog), _("Repeats"));
      gtk_window_set_modal (GTK_WINDOW (d->exceptions_dialog), TRUE);
      gtk_window_set_type_hint (GTK_WINDOW (d->exceptions_dialog),
                                            GDK_WINDOW_TYPE_HINT_DIALOG);
      gtk_dialog_set_has_separator (GTK_DIALOG (d->exceptions_dialog), FALSE);

      dialog_vbox3 = GTK_DIALOG (d->exceptions_dialog)->vbox;
      gtk_widget_show (dialog_vbox3);

      exceptions_table = gtk_table_new (2, 2, FALSE);
      gtk_widget_show (exceptions_table);
      gtk_box_pack_start (GTK_BOX (dialog_vbox3), exceptions_table,
                                    TRUE, TRUE, 0);
      gtk_container_set_border_width (GTK_CONTAINER (exceptions_table), 12);
      gtk_table_set_row_spacings (GTK_TABLE (exceptions_table), 6);
      gtk_table_set_col_spacings (GTK_TABLE (exceptions_table), 6);

      recurrences_help_image = gtk_image_new_from_stock ("gtk-dialog-info",
                                                                                 GTK_ICON_SIZE_DND);
      gtk_widget_show (recurrences_help_image);
      gtk_table_attach (GTK_TABLE (exceptions_table), recurrences_help_image,
                                0, 1, 0, 1,
                                (GtkAttachOptions) (GTK_FILL),
                                (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);

      recurrences_help_label = gtk_label_new (_("<i>You can toggle a repeat\n"
                                                                    "by double-clicking a date\n"
                                                                    "on the calendar.</i>"));
      gtk_widget_show (recurrences_help_label);
      gtk_table_attach (GTK_TABLE (exceptions_table), recurrences_help_label,
                                1, 2, 0, 1,
                                (GtkAttachOptions) (GTK_FILL),
                                (GtkAttachOptions) (0), 0, 0);
      gtk_label_set_use_markup (GTK_LABEL (recurrences_help_label), TRUE);
      gtk_label_set_line_wrap (GTK_LABEL (recurrences_help_label), TRUE);

      recurrences_calendar = gtk_calendar_new ();
      gtk_widget_show (recurrences_calendar);
      gtk_table_attach (GTK_TABLE (exceptions_table), recurrences_calendar,
                                0, 2, 1, 2,
                                (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
                                (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
      gtk_calendar_display_options (GTK_CALENDAR (recurrences_calendar),
                                                  GTK_CALENDAR_SHOW_HEADING
                                                  | GTK_CALENDAR_SHOW_DAY_NAMES);

      repeats_close_button = gtk_dialog_add_button (GTK_DIALOG (d->exceptions_dialog),
                  "gtk-close", GTK_RESPONSE_CLOSE);

      return d->exceptions_dialog;
}
#endif

#ifndef DATES_PLATFORM_create_toolbar
static GtkWidget *
create_toolbar (DatesData *  d)
{
      GtkWidget * toolbar;
      GtkWidget * image;

      toolbar = gtk_hbox_new (FALSE, 3);
      gtk_widget_show (toolbar);

      d->TBNew = gtk_button_new_from_stock ("gtk-new");
      gtk_widget_show (d->TBNew);
      gtk_box_pack_start (GTK_BOX (toolbar), d->TBNew, FALSE, FALSE, 0);
      gtk_button_set_focus_on_click (GTK_BUTTON (d->TBNew), FALSE);

      d->TBEdit = gtk_button_new_from_stock ("gtk-edit");
      gtk_box_pack_start (GTK_BOX (toolbar), d->TBEdit, FALSE, FALSE, 0);
      gtk_widget_set_sensitive (d->TBEdit, FALSE);
      gtk_widget_show (d->TBEdit);
      gtk_button_set_focus_on_click (GTK_BUTTON (d->TBEdit), FALSE);

      d->TBDelete = gtk_button_new_from_stock ("gtk-delete");
      gtk_box_pack_start (GTK_BOX (toolbar), d->TBDelete, FALSE, FALSE, 0);
      gtk_widget_set_sensitive (d->TBDelete, FALSE);
      gtk_widget_show (d->TBDelete);
      gtk_button_set_focus_on_click (GTK_BUTTON (d->TBDelete), FALSE);

      d->TBBack = gtk_button_new ();
      gtk_box_pack_start (GTK_BOX (toolbar), d->TBBack, FALSE, FALSE, 0);
      gtk_widget_show (d->TBBack);
      gtk_button_set_focus_on_click (GTK_BUTTON (d->TBBack), FALSE);
      image = gtk_image_new_from_stock ("gtk-go-back", GTK_ICON_SIZE_BUTTON);
      gtk_button_set_image (GTK_BUTTON (d->TBBack), image);

      d->TBToday = gtk_button_new_with_mnemonic (_("_Today"));
      gtk_widget_show (d->TBToday);
      gtk_box_pack_start (GTK_BOX (toolbar), d->TBToday, FALSE, FALSE, 0);
      gtk_button_set_focus_on_click (GTK_BUTTON (d->TBToday), FALSE);
      image = gtk_image_new_from_stock ("gtk-home", GTK_ICON_SIZE_BUTTON);
      gtk_button_set_image (GTK_BUTTON (d->TBToday), image);

      d->TBForward = gtk_button_new ();
      gtk_widget_show (d->TBForward);
      gtk_box_pack_start (GTK_BOX (toolbar), d->TBForward, FALSE, FALSE, 0);
      gtk_button_set_focus_on_click (GTK_BUTTON (d->TBForward), FALSE);
      image = gtk_image_new_from_stock ("gtk-go-forward", GTK_ICON_SIZE_BUTTON);
      gtk_button_set_image (GTK_BUTTON (d->TBForward), image);

      d->TBZoomOut = gtk_button_new ();
      gtk_widget_show (d->TBZoomOut);
      gtk_box_pack_start (GTK_BOX (toolbar), d->TBZoomOut, FALSE, FALSE, 0);
      gtk_button_set_focus_on_click (GTK_BUTTON (d->TBZoomOut), FALSE);
      image = gtk_image_new_from_stock ("gtk-zoom-out", GTK_ICON_SIZE_BUTTON);
      gtk_button_set_image (GTK_BUTTON (d->TBZoomOut), image);

      d->TBZoomIn = gtk_button_new ();
      gtk_widget_show (d->TBZoomIn);
      gtk_box_pack_start (GTK_BOX (toolbar), d->TBZoomIn, FALSE, FALSE, 0);
      gtk_button_set_focus_on_click (GTK_BUTTON (d->TBZoomIn), FALSE);
      image = gtk_image_new_from_stock ("gtk-zoom-in", GTK_ICON_SIZE_BUTTON);
      gtk_button_set_image (GTK_BUTTON (d->TBZoomIn), image);

      g_signal_connect (G_OBJECT (d->TBNew), "clicked",
                                G_CALLBACK (dates_new_cb),
                                d);
      g_signal_connect (G_OBJECT (d->TBEdit), "clicked",
                                G_CALLBACK (dates_edit_cb),
                                d);
      g_signal_connect (G_OBJECT (d->TBDelete), "clicked",
                                G_CALLBACK (dates_delete_cb),
                                d);
      g_signal_connect (G_OBJECT (d->TBBack), "clicked",
                                G_CALLBACK (dates_back_cb),
                                d);
      g_signal_connect (G_OBJECT (d->TBToday), "clicked",
                                G_CALLBACK (dates_today_cb),
                                d);
      g_signal_connect (G_OBJECT (d->TBForward), "clicked",
                                G_CALLBACK (dates_forward_cb),
                                d);
      g_signal_connect (G_OBJECT (d->TBZoomOut), "clicked",
                                G_CALLBACK (dates_zoom_out_cb),
                                d);
      g_signal_connect (G_OBJECT (d->TBZoomIn), "clicked",
                                G_CALLBACK (dates_zoom_in_cb),
                                d);
      return toolbar;
}
#endif


#ifndef DATES_PLATFORM_create_main_menu
static GtkWidget *
create_main_menu (DatesData * d, GtkAccelGroup ** accel_group)
{
      GtkWidget     * menuitem1;
      GtkWidget     * menuitem1_menu;
      GtkWidget     * sources_menuitem;
      GtkWidget     * separatormenuitem1;
      GtkWidget     * quit_menuitem;

/*
      GtkWidget     * menuitem2;
      GtkWidget     * menuitem2_menu;
      GtkWidget     * cut_menuitem;
      GtkWidget     * copy_menuitem;
      GtkWidget     * paste_menuitem;
*/
      GtkWidget     * menuitem3;
      GtkWidget     * menuitem3_menu;
      GtkWidget     * back_menuitem;
      GtkWidget     * forward_menuitem;
      GtkWidget     * menuitem4;
      GtkWidget     * menuitem4_menu;
      GtkWidget     * about_menuitem;
      GtkWidget     * import_menuitem;
      
      *accel_group = gtk_accel_group_new ();

#ifndef DATES_MENU_WITHOUT_BAR
      d->main_menu = gtk_menu_bar_new ();
#else
      d->main_menu = gtk_menu_new ();
#endif
      menuitem1 = gtk_menu_item_new_with_mnemonic (_("_Calendar"));
      gtk_widget_show (menuitem1);
#ifndef DATES_MENU_WITHOUT_BAR
      gtk_container_add (GTK_CONTAINER (d->main_menu), menuitem1);
#else
      gtk_menu_shell_append (GTK_MENU_SHELL (d->main_menu), menuitem1);
#endif
      menuitem1_menu = gtk_menu_new ();
      gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem1), menuitem1_menu);

      sources_menuitem = gtk_image_menu_item_new_from_stock ("gtk-properties",
                                                                                       *accel_group);
      gtk_widget_show (sources_menuitem);
      gtk_container_add (GTK_CONTAINER (menuitem1_menu), sources_menuitem);

      import_menuitem = gtk_menu_item_new_with_mnemonic (_("_Import"));
      gtk_widget_show (import_menuitem);
      gtk_container_add (GTK_CONTAINER (menuitem1_menu), import_menuitem);

      separatormenuitem1 = gtk_separator_menu_item_new ();
      gtk_widget_show (separatormenuitem1);
      gtk_container_add (GTK_CONTAINER (menuitem1_menu), separatormenuitem1);
      gtk_widget_set_sensitive (separatormenuitem1, FALSE);

      quit_menuitem = gtk_image_menu_item_new_from_stock ("gtk-quit",
                                                                                    *accel_group);
      gtk_widget_show (quit_menuitem);
      gtk_container_add (GTK_CONTAINER (menuitem1_menu), quit_menuitem);

      /* Edit menu commented out. Might be useful later... */
      /*
      menuitem2 = gtk_menu_item_new_with_mnemonic (_("_Edit"));
      gtk_widget_show (menuitem2);
#ifndef DATES_MENU_WITHOUT_BAR
      gtk_container_add (GTK_CONTAINER (d->main_menu), menuitem2);
#else
      gtk_menu_shell_append (GTK_MENU_SHELL (d->main_menu), menuitem2);
#endif

      menuitem2_menu = gtk_menu_new ();
      gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem2), menuitem2_menu);

      cut_menuitem = gtk_image_menu_item_new_from_stock ("gtk-cut",
                                                                                 *accel_group);
      gtk_widget_show (cut_menuitem);
      gtk_container_add (GTK_CONTAINER (menuitem2_menu), cut_menuitem);
      gtk_widget_set_sensitive (cut_menuitem, FALSE);

      copy_menuitem = gtk_image_menu_item_new_from_stock ("gtk-copy",
                                                                                    *accel_group);
      gtk_widget_show (copy_menuitem);
      gtk_container_add (GTK_CONTAINER (menuitem2_menu), copy_menuitem);
      gtk_widget_set_sensitive (copy_menuitem, FALSE);

      paste_menuitem = gtk_image_menu_item_new_from_stock ("gtk-paste",
                                                                                     *accel_group);
      gtk_widget_show (paste_menuitem);
      gtk_container_add (GTK_CONTAINER (menuitem2_menu), paste_menuitem);
      gtk_widget_set_sensitive (paste_menuitem, FALSE);
      */

      menuitem3 = gtk_menu_item_new_with_mnemonic (_("_View"));
      gtk_widget_show (menuitem3);
#ifndef DATES_MENU_WITHOUT_BAR
      gtk_container_add (GTK_CONTAINER (d->main_menu), menuitem3);
#else
      gtk_menu_shell_append (GTK_MENU_SHELL (d->main_menu), menuitem3);
#endif

      menuitem3_menu = gtk_menu_new ();
      gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem3), menuitem3_menu);

      back_menuitem = gtk_image_menu_item_new_from_stock ("gtk-go-back",
                                                                                    *accel_group);
      gtk_widget_show (back_menuitem);
      gtk_container_add (GTK_CONTAINER (menuitem3_menu), back_menuitem);

      forward_menuitem = gtk_image_menu_item_new_from_stock ("gtk-go-forward",
                                                                                       *accel_group);
      gtk_widget_show (forward_menuitem);
      gtk_container_add (GTK_CONTAINER (menuitem3_menu), forward_menuitem);

      d->MIZoomOut = gtk_image_menu_item_new_from_stock ("gtk-zoom-out",
                                                                                          *accel_group);
      gtk_widget_show (d->MIZoomOut);
      gtk_container_add (GTK_CONTAINER (menuitem3_menu), d->MIZoomOut);

      d->MIZoomIn = gtk_image_menu_item_new_from_stock ("gtk-zoom-in",
                                                                                       *accel_group);
      gtk_widget_show (d->MIZoomIn);
      gtk_container_add (GTK_CONTAINER (menuitem3_menu), d->MIZoomIn);

      menuitem4 = gtk_menu_item_new_with_mnemonic (_("_Help"));
      gtk_widget_show (menuitem4);
#ifndef DATES_MENU_WITHOUT_BAR
      gtk_container_add (GTK_CONTAINER (d->main_menu), menuitem4);
#else
      gtk_menu_shell_append (GTK_MENU_SHELL (d->main_menu), menuitem4);
#endif

      menuitem4_menu = gtk_menu_new ();
      gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem4), menuitem4_menu);

      about_menuitem = gtk_image_menu_item_new_from_stock ("gtk-about",
                                                                                     *accel_group);
      gtk_widget_show (about_menuitem);
      gtk_container_add (GTK_CONTAINER (menuitem4_menu), about_menuitem);

      g_signal_connect (G_OBJECT (sources_menuitem), "activate",
                                G_CALLBACK (dates_calendars_dialog_cb),
                                d);
      g_signal_connect (G_OBJECT (quit_menuitem), "activate",
                                G_CALLBACK (gtk_main_quit),
                                d);
      g_signal_connect (G_OBJECT (back_menuitem), "activate",
                                G_CALLBACK (dates_back_cb),
                                d);
      g_signal_connect (G_OBJECT (forward_menuitem), "activate",
                                G_CALLBACK (dates_forward_cb),
                                d);
      g_signal_connect (G_OBJECT (d->MIZoomOut), "activate",
                                G_CALLBACK (dates_zoom_out_cb),
                                d);
      g_signal_connect (G_OBJECT (d->MIZoomIn), "activate",
                                G_CALLBACK (dates_zoom_in_cb),
                                d);
      g_signal_connect (G_OBJECT (about_menuitem), "activate",
                                G_CALLBACK (dates_about_cb),
                                d);

      g_signal_connect (G_OBJECT (import_menuitem), "activate",
                  G_CALLBACK (dates_import_cb),
                  d);
      
      return d->main_menu;
}
#endif


#ifndef DATES_PLATFORM_dates_platform_create_ui
void
dates_platform_create_ui (DatesData * d)
{
      GtkAccelGroup * accel = NULL;
      GtkWidget     * toolbar= create_toolbar (d);
    GtkWidget     * menu = create_main_menu (d, &accel);
      
      create_main_window (d, toolbar, menu, accel);
    create_details_dialog (d);
      create_time_dialog (d);
    create_repeats_dialog (d);
    create_calendars_dialog (d);
    create_exceptions_dialog (d);

      g_signal_connect (G_OBJECT (d->main_window), "destroy",
                                G_CALLBACK (gtk_main_quit),
                                NULL);
      
}
#endif

#ifndef DATES_PLATFORM_dates_platform_init
void
dates_platform_init (DatesData * d)
{
}
#endif

#ifndef DATES_PLATFORM_dates_platform_pre_show
void
dates_platform_pre_show (DatesData *d)
{
}
#endif

#ifndef DATES_PLATFORM_dates_platform_details_dlg
void dates_platform_details_dlg (DatesData *d, gboolean show)
{


      if (show)
      {
            if (d->event_type == NEW_EVENT)
                  gtk_widget_hide (d->details_delete_button);
            else
                  gtk_widget_show (d->details_delete_button);
      
            gtk_widget_show_all (
                        gtk_notebook_get_nth_page (GTK_NOTEBOOK (d->details_notebook), 0));
            gtk_notebook_set_current_page (GTK_NOTEBOOK (d->details_notebook), 0);
            gtk_widget_show (d->details_dialog);

      }
      else
            gtk_widget_hide (d->details_dialog);
}
#endif

#ifndef DATES_PLATFORM_dates_platform_time_dlg
void dates_platform_time_dlg (DatesData *d, gboolean show)
{
      if (show)
      {
            gtk_dialog_run (GTK_DIALOG (d->time_dialog));
            gtk_widget_hide (d->time_dialog);
      }
      else
            gtk_widget_hide (d->time_dialog);
}
#endif

#ifndef DATES_PLATFORM_dates_platform_repeats_dlg
void dates_platform_repeats_dlg (DatesData *d, gboolean show)
{
      if (show)
      {
            gtk_dialog_run (GTK_DIALOG (d->repeats_dialog));
            gtk_widget_hide (d->repeats_dialog);
      }
      else
            gtk_widget_hide (d->repeats_dialog);
}
#endif

#ifndef DATES_PLATFORM_dates_platform_calendars_dlg
void dates_platform_calendars_dlg (DatesData *d, gboolean show)
{
      if (show)
      {
            gtk_dialog_run (GTK_DIALOG (d->calendars_dialog));
      }
      else
            gtk_widget_hide (d->calendars_dialog);
}
#endif

#ifndef DATES_PLATFORM_dates_platform_exceptions_dlg
void dates_platform_exceptions_dlg (DatesData *d, gboolean show)
{
}
#endif

#ifndef DATES_PLATFORM_dates_platform_cal_open
void dates_platform_cal_open (DatesData * d)
{
}
#endif

#ifndef DATES_PLATFORM_import_dialog
void dates_platform_import_dialog (DatesData *d)
{
  GtkWidget *open_dialog;
  guint res;
  gchar *filename = NULL;
  GError *error = NULL;
  GtkWidget *vbox;
  GtkWidget *combo;
  GtkWidget *hbox;
  GtkWidget *label;
  GtkWidget *hseparator;
  GtkTreeModel *cal_filter;
  GtkCellRenderer *renderer;
  GtkTreeIter iter, default_iter;
  ECal *target_cal = NULL;

  cal_filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (d->cal_list_store), NULL);
  gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (cal_filter), COL_NOTREADONLY);

  /* 
   * Check that there is at least one writable calendar, else, throw up
   * warning message.
   */
  if (gtk_tree_model_get_iter_first (cal_filter, &iter))
  {
    /*
     * Hack an hbox into the top of the GtkFileChooserDialog. Done this way
     * rather than with a GtkFileChooserWidget to avoid some horrible faffing
     * about with sizing.
     */

    open_dialog = gtk_file_chooser_dialog_new ("Import calendar", GTK_WINDOW (d->main_window), 
        GTK_FILE_CHOOSER_ACTION_OPEN,
        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
        GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
        NULL);

    vbox = gtk_vbox_new (FALSE, 6);
    gtk_box_pack_start (GTK_BOX(GTK_DIALOG (open_dialog)->vbox),vbox, FALSE, FALSE, 6);

    hbox = gtk_hbox_new (FALSE, 6);
    gtk_widget_show (hbox);

    label = gtk_label_new_with_mnemonic (_("Target _calendar:"));
    gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 6);
    gtk_widget_show (label);

    combo = gtk_combo_box_new_with_model (cal_filter);
    gtk_box_pack_start (GTK_BOX (hbox), combo, TRUE, TRUE, 6);
    gtk_widget_show (combo);

    renderer = gtk_cell_renderer_text_new ();
    gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
    gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer,
        "text", 0,
        NULL);

    gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 6);

    hseparator = gtk_hseparator_new ();
    gtk_box_pack_start (GTK_BOX (vbox), hseparator, FALSE, FALSE, 6);
    gtk_widget_show (hseparator);

    gtk_box_reorder_child (GTK_BOX (GTK_DIALOG (open_dialog)->vbox), vbox, 0);

    gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (open_dialog)->vbox), 12);

    /* 
     * Want to find the iter for the default calendar, if there isn't one just
     * use the first iter.
     */
    default_iter = iter;

    do
    {
      ECal *cal;

      gtk_tree_model_get (cal_filter, &iter, COL_CALPTR, &cal, -1);

      /* Check if default calendar */
      if (cal == d->dcal)
      {
        default_iter = iter;
        break;
      }

    } while (gtk_tree_model_iter_next (cal_filter, &iter));

    /* We want to make sure we have a default iter */
    gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo), &iter);

    /* If there are multiple potential calendars then show the vbox */
    if (gtk_tree_model_iter_n_children (cal_filter, NULL) > 1)
      gtk_widget_show (vbox);

    res = gtk_dialog_run (GTK_DIALOG (open_dialog));

    switch (res)
    {
      case GTK_RESPONSE_ACCEPT:
        filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (open_dialog));

        /* Get the selected calendar */
        if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter))
        {
          gtk_tree_model_get (cal_filter, &iter, COL_CALPTR, &target_cal, -1);
        }

        gtk_widget_destroy (open_dialog);

        /* Try and import, if it fails then pop up an error dialog */
        if (filename && 
            target_cal &&
            !dates_import_calendar_data_from_file (target_cal, filename, &error)
            && error != NULL)
        {
          GtkWidget *error_dialog;
          error_dialog = gtk_message_dialog_new (GTK_WINDOW (d->main_window), 
              GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL,
              GTK_MESSAGE_ERROR,
              GTK_BUTTONS_OK, 
              _("Error when importing: %s"), error->message);

          gtk_dialog_run (GTK_DIALOG (error_dialog));
          gtk_widget_destroy (error_dialog);
        }

        g_free (filename);
        break;
      default:
        gtk_widget_destroy (open_dialog);
        break;
    }
  } else {
    GtkWidget *error_dialog;

    error_dialog = gtk_message_dialog_new (GTK_WINDOW (d->main_window), 
        GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL,
        GTK_MESSAGE_ERROR,
        GTK_BUTTONS_OK, 
        _("No writable calendars to import into."));

    gtk_dialog_run (GTK_DIALOG (error_dialog));
    gtk_widget_destroy (error_dialog);
  }
}
#endif

Generated by  Doxygen 1.6.0   Back to index