/* Evolution calendar - Calendar properties dialogs * * Copyright (C) 2003 Novell, Inc. * * Author: Hans Petter Jansson * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License as published by the Free Software Foundation. * * 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. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "calendar-setup.h" #define GLADE_FILE_NAME "calendar-setup.glade" typedef struct { GladeXML *gui_xml; /* Main widgets */ GtkWidget *window; GtkWidget *druid; /* Source selection */ ESourceList *source_list; GtkWidget *group_optionmenu; /* ESource we're currently editing (if any) */ ESource *source; /* Source group we're creating/editing source in */ ESourceGroup *source_group; /* General page fields */ GtkWidget *name_entry; /* Location page fields */ GtkWidget *uri_entry; GtkWidget *refresh_spin; } SourceDialog; static gchar * print_uri_noproto (EUri *uri) { gchar *uri_noproto; if (uri->port != 0) uri_noproto = g_strdup_printf ( "%s%s%s%s%s%s%s:%d%s%s%s", uri->user ? uri->user : "", uri->authmech ? ";auth=" : "", uri->authmech ? uri->authmech : "", uri->passwd ? ":" : "", uri->passwd ? uri->passwd : "", uri->user ? "@" : "", uri->host ? uri->host : "", uri->port, uri->path ? uri->path : "", uri->query ? "?" : "", uri->query ? uri->query : ""); else uri_noproto = g_strdup_printf ( "%s%s%s%s%s%s%s%s%s%s", uri->user ? uri->user : "", uri->authmech ? ";auth=" : "", uri->authmech ? uri->authmech : "", uri->passwd ? ":" : "", uri->passwd ? uri->passwd : "", uri->user ? "@" : "", uri->host ? uri->host : "", uri->path ? uri->path : "", uri->query ? "?" : "", uri->query ? uri->query : ""); return uri_noproto; } static gboolean source_group_is_remote (ESourceGroup *group) { EUri *uri; gboolean is_remote = FALSE; uri = e_uri_new (e_source_group_peek_base_uri (group)); if (!uri) return FALSE; if (uri->protocol && uri->protocol [0] && strcmp (uri->protocol, "file")) is_remote = TRUE; e_uri_free (uri); return is_remote; } static gboolean source_is_remote (ESource *source) { gchar *uri_str; EUri *uri; gboolean is_remote = FALSE; uri_str = e_source_get_uri (source); if (!uri_str) return FALSE; uri = e_uri_new (uri_str); g_free (uri_str); if (!uri) return FALSE; if (uri->protocol && uri->protocol [0] && strcmp (uri->protocol, "file")) is_remote = TRUE; e_uri_free (uri); return is_remote; } static gboolean validate_remote_uri (const gchar *source_location, gboolean interactive, GtkWidget *parent) { EUri *uri; if (!source_location || !strlen (source_location)) { if (interactive) e_notice (parent, GTK_MESSAGE_ERROR, _("You must specify a location to get the calendar from.")); return FALSE; } uri = e_uri_new (source_location); if (!uri) { if (interactive) e_notice (parent, GTK_MESSAGE_ERROR, _("The source location '%s' is not well-formed."), source_location); return FALSE; } /* Make sure we're in agreement with the protocol. Note that EUri sets it * to 'file' if none was specified in the input URI. We don't want to * silently translate an explicit file:// into http:// though. */ if (uri->protocol && strcmp (uri->protocol, "http") && strcmp (uri->protocol, "webcal")) { e_uri_free (uri); if (interactive) e_notice (parent, GTK_MESSAGE_ERROR, _("The source location '%s' is not a webcal source."), source_location); return FALSE; } e_uri_free (uri); return TRUE; } static void source_group_menu_add_groups (GtkMenuShell *menu_shell, ESourceList *source_list) { GSList *groups, *sl; groups = e_source_list_peek_groups (source_list); for (sl = groups; sl; sl = g_slist_next (sl)) { GtkWidget *menu_item; ESourceGroup *group = sl->data; menu_item = gtk_menu_item_new_with_label (e_source_group_peek_name (group)); gtk_widget_show (menu_item); gtk_menu_shell_append (menu_shell, menu_item); } } static ESource * create_new_source_with_group (GtkWindow *parent, ESourceGroup *group, const char *source_name, const char *source_location, ECalSourceType source_type) { ESource *source; ECal *cal; if (e_source_group_peek_source_by_name (group, source_name)) { e_notice (parent, GTK_MESSAGE_ERROR, _("Source with name '%s' already exists in the selected group"), source_name); return NULL; } if (source_group_is_remote (group)) { EUri *uri; gchar *relative_uri; /* Remote source */ if (!source_location || !strlen (source_location)) { e_notice (parent, GTK_MESSAGE_ERROR, _("The group '%s' is remote. You must specify a location " "to get the calendar from"), e_source_group_peek_name (group)); return NULL; } if (!validate_remote_uri (source_location, TRUE, GTK_WIDGET (parent))) return NULL; /* Our relative_uri is everything but protocol, which is supplied by parent group */ uri = e_uri_new (source_location); relative_uri = print_uri_noproto (uri); e_uri_free (uri); /* Create source */ source = e_source_new (source_name, relative_uri); g_free (relative_uri); } else { /* Local source */ source = e_source_new (source_name, source_name); e_source_set_relative_uri (source, e_source_peek_uid (source)); } e_source_group_add_source (group, source, -1); /* create the calendar in the backend */ cal = e_cal_new (source, source_type); if (!e_cal_open (cal, FALSE, NULL)) { e_source_group_remove_source (group, source); g_object_unref (source); } g_object_unref (cal); return source; } static void source_dialog_destroy (SourceDialog *source_dialog) { g_object_unref (source_dialog->gui_xml); if (source_dialog->source) g_object_unref (source_dialog->source); g_free (source_dialog); } static void source_to_dialog (SourceDialog *source_dialog) { ESource *source = source_dialog->source; g_signal_handlers_block_matched (source_dialog->name_entry, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, source_dialog); /* These are calendar specific so make sure we have them */ if (source_dialog->uri_entry) g_signal_handlers_block_matched (source_dialog->uri_entry, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, source_dialog); if (source_dialog->refresh_spin) g_signal_handlers_block_matched (source_dialog->refresh_spin, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, source_dialog); gtk_entry_set_text (GTK_ENTRY (source_dialog->name_entry), source ? e_source_peek_name (source) : ""); if (source && source_is_remote (source)) { gchar *uri_str; const gchar *refresh_str; uri_str = e_source_get_uri (source); gtk_entry_set_text (GTK_ENTRY (source_dialog->uri_entry), uri_str); g_free (uri_str); refresh_str = e_source_get_property (source, "refresh"); gtk_spin_button_set_value (GTK_SPIN_BUTTON (source_dialog->refresh_spin), refresh_str ? atoi (refresh_str) : 30); } else { if (source_dialog->uri_entry) gtk_entry_set_text (GTK_ENTRY (source_dialog->uri_entry), ""); if (source_dialog->refresh_spin) gtk_spin_button_set_value (GTK_SPIN_BUTTON (source_dialog->refresh_spin), 30); } g_signal_handlers_unblock_matched (source_dialog->name_entry, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, source_dialog); if (source_dialog->uri_entry) g_signal_handlers_unblock_matched (source_dialog->uri_entry, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, source_dialog); if (source_dialog->refresh_spin) g_signal_handlers_unblock_matched (source_dialog->refresh_spin, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, source_dialog); } static void dialog_to_source (SourceDialog *source_dialog) { ESource *source = source_dialog->source; g_return_if_fail (source != NULL); e_source_set_name (source, gtk_entry_get_text (GTK_ENTRY (source_dialog->name_entry))); if (source_is_remote (source)) { EUri *uri; gchar *relative_uri; gchar *refresh_str; /* Our relative_uri is everything but protocol, which is supplied by parent group */ uri = e_uri_new (gtk_entry_get_text (GTK_ENTRY (source_dialog->uri_entry))); if (!uri) { g_warning ("Invalid remote URI!"); return; } relative_uri = print_uri_noproto (uri); e_source_set_relative_uri (source, relative_uri); g_free (relative_uri); e_uri_free (uri); refresh_str = g_strdup_printf ("%d", gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (source_dialog->refresh_spin))); e_source_set_property (source, "refresh", refresh_str); g_free (refresh_str); } } static gboolean general_page_verify (SourceDialog *source_dialog) { const gchar *name; if (!source_dialog->source_group && !source_dialog->source) return FALSE; name = gtk_entry_get_text (GTK_ENTRY (source_dialog->name_entry)); if (!name || !name [0]) return FALSE; return TRUE; } static gboolean remote_page_verify (SourceDialog *source_dialog) { const gchar *uri; uri = gtk_entry_get_text (GTK_ENTRY (source_dialog->uri_entry)); if (!uri || !uri [0]) return FALSE; if (!validate_remote_uri (uri, FALSE, NULL)) return FALSE; return TRUE; } static gboolean source_dialog_is_valid (SourceDialog *source_dialog) { if (!general_page_verify (source_dialog)) return FALSE; if (((source_dialog->source && source_is_remote (source_dialog->source)) || (source_dialog->source_group && source_group_is_remote (source_dialog->source_group))) && !remote_page_verify (source_dialog)) return FALSE; return TRUE; } static void editor_set_buttons_sensitive (SourceDialog *source_dialog, gboolean sensitive) { gtk_widget_set_sensitive (glade_xml_get_widget (source_dialog->gui_xml, "ok-button"), sensitive); } static void general_page_modified (SourceDialog *source_dialog) { if (source_dialog->druid) { gnome_druid_set_buttons_sensitive (GNOME_DRUID (source_dialog->druid), TRUE, /* Back */ general_page_verify (source_dialog), /* Next */ TRUE, /* Cancel */ FALSE); /* Help */ } else { editor_set_buttons_sensitive (source_dialog, source_dialog_is_valid (source_dialog)); } } static void remote_page_modified (SourceDialog *source_dialog) { if (source_dialog->druid) { gnome_druid_set_buttons_sensitive (GNOME_DRUID (source_dialog->druid), TRUE, /* Back */ remote_page_verify (source_dialog), /* Next */ TRUE, /* Cancel */ FALSE); /* Help */ } else { editor_set_buttons_sensitive (source_dialog, source_dialog_is_valid (source_dialog)); } } static void source_group_changed (SourceDialog *source_dialog) { source_dialog->source_group = g_slist_nth (e_source_list_peek_groups (source_dialog->source_list), gtk_option_menu_get_history (GTK_OPTION_MENU (source_dialog->group_optionmenu)))->data; } static void general_page_prepare (GtkWidget *page, GtkWidget *druid, SourceDialog *source_dialog) { general_page_modified (source_dialog); gtk_widget_grab_focus (source_dialog->name_entry); } static void remote_page_prepare (GtkWidget *page, GtkWidget *druid, SourceDialog *source_dialog) { remote_page_modified (source_dialog); gtk_widget_grab_focus (source_dialog->uri_entry); } static gboolean general_page_forward (GtkWidget *page, GtkWidget *widget, SourceDialog *source_dialog) { GtkWidget *finish_page = glade_xml_get_widget (source_dialog->gui_xml, "finish-page"); if (!source_group_is_remote (source_dialog->source_group)) { gnome_druid_set_page (GNOME_DRUID (source_dialog->druid), GNOME_DRUID_PAGE (finish_page)); return TRUE; } return FALSE; } static gboolean finish_page_back (GtkWidget *page, GtkWidget *widget, SourceDialog *source_dialog) { GtkWidget *general_page = glade_xml_get_widget (source_dialog->gui_xml, "general-page"); if (!source_group_is_remote (source_dialog->source_group)) { gnome_druid_set_page (GNOME_DRUID (source_dialog->druid), GNOME_DRUID_PAGE (general_page)); return TRUE; } return FALSE; } static void new_calendar_finish (SourceDialog *source_dialog) { source_dialog->source = create_new_source_with_group (GTK_WINDOW (source_dialog->window), source_dialog->source_group, gtk_entry_get_text (GTK_ENTRY (source_dialog->name_entry)), gtk_entry_get_text (GTK_ENTRY (source_dialog->uri_entry)), E_CAL_SOURCE_TYPE_EVENT); dialog_to_source (source_dialog); gtk_widget_destroy (source_dialog->window); } static void new_calendar_cancel (SourceDialog *source_dialog) { gtk_widget_destroy (source_dialog->window); } gboolean calendar_setup_new_calendar (GtkWindow *parent) { SourceDialog *source_dialog = g_new0 (SourceDialog, 1); GtkWidget *page; source_dialog->gui_xml = glade_xml_new (EVOLUTION_GLADEDIR "/" GLADE_FILE_NAME, "calendar-druid-window", NULL); if (!source_dialog->gui_xml) { g_warning (G_STRLOC ": Cannot load Glade file."); g_free (source_dialog); return FALSE; } source_dialog->window = glade_xml_get_widget (source_dialog->gui_xml, "calendar-druid-window"); source_dialog->druid = glade_xml_get_widget (source_dialog->gui_xml, "druid"); /* General page */ page = glade_xml_get_widget (source_dialog->gui_xml, "general-page"); source_dialog->name_entry = glade_xml_get_widget (source_dialog->gui_xml, "name-entry"); g_signal_connect_swapped (source_dialog->name_entry, "changed", G_CALLBACK (general_page_modified), source_dialog); g_signal_connect_after (page, "prepare", G_CALLBACK (general_page_prepare), source_dialog); g_signal_connect_after (page, "next", G_CALLBACK (general_page_forward), source_dialog); source_dialog->source_list = e_source_list_new_for_gconf_default ("/apps/evolution/calendar/sources"); source_dialog->group_optionmenu = glade_xml_get_widget (source_dialog->gui_xml, "group-optionmenu"); if (!GTK_IS_MENU (gtk_option_menu_get_menu (GTK_OPTION_MENU (source_dialog->group_optionmenu)))) { GtkWidget *menu = gtk_menu_new (); gtk_option_menu_set_menu (GTK_OPTION_MENU (source_dialog->group_optionmenu), menu); gtk_widget_show (menu); } /* NOTE: This assumes that we have sources. If they don't exist, they're set up * on startup of the calendar component. */ source_group_menu_add_groups (GTK_MENU_SHELL (gtk_option_menu_get_menu ( GTK_OPTION_MENU (source_dialog->group_optionmenu))), source_dialog->source_list); gtk_option_menu_set_history (GTK_OPTION_MENU (source_dialog->group_optionmenu), 0); source_dialog->source_group = e_source_list_peek_groups (source_dialog->source_list)->data; g_signal_connect_swapped (source_dialog->group_optionmenu, "changed", G_CALLBACK (source_group_changed), source_dialog); /* Remote page */ page = glade_xml_get_widget (source_dialog->gui_xml, "remote-page"); source_dialog->uri_entry = glade_xml_get_widget (source_dialog->gui_xml, "uri-entry"); source_dialog->refresh_spin = glade_xml_get_widget (source_dialog->gui_xml, "refresh-spin"); g_signal_connect_swapped (source_dialog->uri_entry, "changed", G_CALLBACK (remote_page_modified), source_dialog); g_signal_connect_swapped (source_dialog->refresh_spin, "changed", G_CALLBACK (remote_page_modified), source_dialog); g_signal_connect_after (page, "prepare", G_CALLBACK (remote_page_prepare), source_dialog); /* Finish page */ page = glade_xml_get_widget (source_dialog->gui_xml, "finish-page"); g_signal_connect_swapped (page, "finish", G_CALLBACK (new_calendar_finish), source_dialog); g_signal_connect_after (page, "back", G_CALLBACK (finish_page_back), source_dialog); g_signal_connect_swapped (source_dialog->druid, "cancel", G_CALLBACK (new_calendar_cancel), source_dialog); g_object_weak_ref (G_OBJECT (source_dialog->window), (GWeakNotify) source_dialog_destroy, source_dialog); /* Prepare and show dialog */ source_to_dialog (source_dialog); gtk_window_set_type_hint (GTK_WINDOW (source_dialog->window), GDK_WINDOW_TYPE_HINT_DIALOG); gtk_window_set_modal (GTK_WINDOW (source_dialog->window), TRUE); gtk_widget_show_all (source_dialog->window); return TRUE; } static void edit_calendar_finish (SourceDialog *source_dialog) { dialog_to_source (source_dialog); gtk_widget_destroy (source_dialog->window); } static void edit_calendar_cancel (SourceDialog *source_dialog) { gtk_widget_destroy (source_dialog->window); } gboolean calendar_setup_edit_calendar (GtkWindow *parent, ESource *source) { SourceDialog *source_dialog = g_new0 (SourceDialog, 1); g_return_val_if_fail (source != NULL, FALSE); source_dialog->gui_xml = glade_xml_new (EVOLUTION_GLADEDIR "/" GLADE_FILE_NAME, "calendar-editor-window", NULL); if (!source_dialog->gui_xml) { g_warning (G_STRLOC ": Cannot load Glade file."); g_free (source_dialog); return FALSE; } source_dialog->source = source; g_object_ref (source); source_dialog->window = glade_xml_get_widget (source_dialog->gui_xml, "calendar-editor-window"); /* General page */ source_dialog->name_entry = glade_xml_get_widget (source_dialog->gui_xml, "name-entry"); g_signal_connect_swapped (source_dialog->name_entry, "changed", G_CALLBACK (general_page_modified), source_dialog); g_signal_connect_swapped (source_dialog->name_entry, "activate", G_CALLBACK (edit_calendar_finish), source_dialog); /* Remote page */ source_dialog->uri_entry = glade_xml_get_widget (source_dialog->gui_xml, "uri-entry"); source_dialog->refresh_spin = glade_xml_get_widget (source_dialog->gui_xml, "refresh-spin"); g_signal_connect_swapped (source_dialog->uri_entry, "changed", G_CALLBACK (remote_page_modified), source_dialog); g_signal_connect_swapped (source_dialog->refresh_spin, "changed", G_CALLBACK (remote_page_modified), source_dialog); /* Finishing */ g_signal_connect_swapped (glade_xml_get_widget (source_dialog->gui_xml, "ok-button"), "clicked", G_CALLBACK (edit_calendar_finish), source_dialog); g_signal_connect_swapped (glade_xml_get_widget (source_dialog->gui_xml, "cancel-button"), "clicked", G_CALLBACK (edit_calendar_cancel), source_dialog); g_object_weak_ref (G_OBJECT (source_dialog->window), (GWeakNotify) source_dialog_destroy, source_dialog); /* Prepare and show dialog */ source_to_dialog (source_dialog); gtk_window_set_type_hint (GTK_WINDOW (source_dialog->window), GDK_WINDOW_TYPE_HINT_DIALOG); gtk_window_set_modal (GTK_WINDOW (source_dialog->window), TRUE); gtk_widget_show_all (source_dialog->window); if (!source_is_remote (source_dialog->source)) gtk_widget_hide (glade_xml_get_widget (source_dialog->gui_xml, "remote-page")); return TRUE; } static void new_task_list_finish (SourceDialog *source_dialog) { source_dialog->source = create_new_source_with_group (GTK_WINDOW (source_dialog->window), source_dialog->source_group, gtk_entry_get_text (GTK_ENTRY (source_dialog->name_entry)), NULL, E_CAL_SOURCE_TYPE_TODO); dialog_to_source (source_dialog); gtk_widget_destroy (source_dialog->window); } static void new_task_list_cancel (SourceDialog *source_dialog) { gtk_widget_destroy (source_dialog->window); } gboolean calendar_setup_new_task_list (GtkWindow *parent) { SourceDialog *source_dialog = g_new0 (SourceDialog, 1); GtkWidget *page; source_dialog->gui_xml = glade_xml_new (EVOLUTION_GLADEDIR "/" GLADE_FILE_NAME, "task-list-druid-window", NULL); if (!source_dialog->gui_xml) { g_warning (G_STRLOC ": Cannot load Glade file."); g_free (source_dialog); return FALSE; } source_dialog->window = glade_xml_get_widget (source_dialog->gui_xml, "task-list-druid-window"); source_dialog->druid = glade_xml_get_widget (source_dialog->gui_xml, "druid"); /* General page */ page = glade_xml_get_widget (source_dialog->gui_xml, "general-page"); source_dialog->name_entry = glade_xml_get_widget (source_dialog->gui_xml, "name-entry"); g_signal_connect_swapped (source_dialog->name_entry, "changed", G_CALLBACK (general_page_modified), source_dialog); g_signal_connect_after (page, "prepare", G_CALLBACK (general_page_prepare), source_dialog); source_dialog->source_list = e_source_list_new_for_gconf_default ("/apps/evolution/tasks/sources"); source_dialog->group_optionmenu = glade_xml_get_widget (source_dialog->gui_xml, "group-optionmenu"); if (!GTK_IS_MENU (gtk_option_menu_get_menu (GTK_OPTION_MENU (source_dialog->group_optionmenu)))) { GtkWidget *menu = gtk_menu_new (); gtk_option_menu_set_menu (GTK_OPTION_MENU (source_dialog->group_optionmenu), menu); gtk_widget_show (menu); } /* NOTE: This assumes that we have sources. If they don't exist, they're set up * on startup of the calendar component. */ source_group_menu_add_groups (GTK_MENU_SHELL (gtk_option_menu_get_menu ( GTK_OPTION_MENU (source_dialog->group_optionmenu))), source_dialog->source_list); gtk_option_menu_set_history (GTK_OPTION_MENU (source_dialog->group_optionmenu), 0); source_dialog->source_group = e_source_list_peek_groups (source_dialog->source_list)->data; g_signal_connect_swapped (source_dialog->group_optionmenu, "changed", G_CALLBACK (source_group_changed), source_dialog); /* Finish page */ page = glade_xml_get_widget (source_dialog->gui_xml, "finish-page"); g_signal_connect_swapped (page, "finish", G_CALLBACK (new_task_list_finish), source_dialog); g_signal_connect_swapped (source_dialog->druid, "cancel", G_CALLBACK (new_task_list_cancel), source_dialog); g_object_weak_ref (G_OBJECT (source_dialog->window), (GWeakNotify) source_dialog_destroy, source_dialog); /* Prepare and show dialog */ source_to_dialog (source_dialog); gtk_window_set_type_hint (GTK_WINDOW (source_dialog->window), GDK_WINDOW_TYPE_HINT_DIALOG); gtk_window_set_modal (GTK_WINDOW (source_dialog->window), TRUE); gtk_widget_show_all (source_dialog->window); return TRUE; } static void edit_task_list_finish (SourceDialog *source_dialog) { dialog_to_source (source_dialog); gtk_widget_destroy (source_dialog->window); } static void edit_task_list_cancel (SourceDialog *source_dialog) { gtk_widget_destroy (source_dialog->window); } gboolean calendar_setup_edit_task_list (GtkWindow *parent, ESource *source) { SourceDialog *source_dialog = g_new0 (SourceDialog, 1); g_return_val_if_fail (source != NULL, FALSE); source_dialog->gui_xml = glade_xml_new (EVOLUTION_GLADEDIR "/" GLADE_FILE_NAME, "task-list-editor-window", NULL); if (!source_dialog->gui_xml) { g_warning (G_STRLOC ": Cannot load Glade file."); g_free (source_dialog); return FALSE; } source_dialog->source = source; g_object_ref (source); source_dialog->window = glade_xml_get_widget (source_dialog->gui_xml, "task-list-editor-window"); /* General page */ source_dialog->name_entry = glade_xml_get_widget (source_dialog->gui_xml, "name-entry"); g_signal_connect_swapped (source_dialog->name_entry, "changed", G_CALLBACK (general_page_modified), source_dialog); g_signal_connect_swapped (source_dialog->name_entry, "activate", G_CALLBACK (edit_calendar_finish), source_dialog); /* Finishing */ g_signal_connect_swapped (glade_xml_get_widget (source_dialog->gui_xml, "ok-button"), "clicked", G_CALLBACK (edit_task_list_finish), source_dialog); g_signal_connect_swapped (glade_xml_get_widget (source_dialog->gui_xml, "cancel-button"), "clicked", G_CALLBACK (edit_task_list_cancel), source_dialog); g_object_weak_ref (G_OBJECT (source_dialog->window), (GWeakNotify) source_dialog_destroy, source_dialog); /* Prepare and show dialog */ source_to_dialog (source_dialog); gtk_window_set_type_hint (GTK_WINDOW (source_dialog->window), GDK_WINDOW_TYPE_HINT_DIALOG); gtk_window_set_modal (GTK_WINDOW (source_dialog->window), TRUE); gtk_widget_show_all (source_dialog->window); return TRUE; }