From ca603236ed6d7a43bc4587b70d6163ee1d95e310 Mon Sep 17 00:00:00 2001 From: JP Rosevear Date: Tue, 19 Jun 2001 19:24:08 +0000 Subject: itip/imip send dialog 2001-06-19 JP Rosevear * gui/dialogs/send-comp.c: itip/imip send dialog * gui/dialogs/send-comp.h: new proto * gui/dialogs/recurrence-page.c (recurrence_page_set_dates): only use the weekday picker if visible * gui/dialogs/meeting-page.c: just show the meeting list * gui/dialogs/event-editor.c (event_editor_edit_comp): remove the meeting page if no attendees (schedule_meeting_cmd): schedule a meeting menu item (refresh_meeting_cmd): refresh meeting request menu item (cancel_meeting_cmd): ditto for cancel (forward_cmd): send as attachment * gui/dialogs/comp-editor.c (comp_editor_remove_page): remove page from dialog (comp_editor_show_page): show a given page (comp_editor_get_current_comp): return a cal component representing the current widget state (comp_editor_save_comp): save the cal component (comp_editor_delete_comp): delete the cal component (comp_editor_send_comp): send the cal component (comp_editor_merge_ui): merge xml in to the bonobo gui (setup_widgets): use a bonobo window instead of a gtk window, add menus again (save_as_cmd): save to file on disk - still broken (save_close_cmd): close menu command (save_close_cmd): save and close menu command * gui/dialogs/comp-editor.h: new protos * gui/dialogs/cancel-comp.c (cancel_component_dialog): itip/imip cancellation dialog * gui/dialogs/cancel-comp.h: new proto * gui/dialogs/Makefile.am: build new files * gui/dialogs/comp-editor-page.c (comp_editor_page_notify_needs_send): emit needs_send signal * gui/dialogs/comp-editor-page.h: new signal protos * gui/itip-utils.c (itip_send_comp): new function to send cal components * gui/itip-utils.h: new proto * gui/e-itip-control.c (pstream_load): trim using cal-component wrapper stuff (accept_button_clicked_cb): use itip_send_comp (tentative_button_clicked_cb): ditto (decline_button_clicked_cb): ditto * gui/Makefile.am: compile select name idl stuff * cal-util/cal-component.c (cal_component_get_organizer): get the organizer (cal_component_set_organizer): set the organizer (cal_component_get_recurid): get the recurrence id (cal_component_set_recurid): set the recurrence id (set_attendee_list): actually set the attendee list (get_attendee_list): build the attendee list * cal-util/cal-component.h: new protos svn path=/trunk/; revision=10299 --- calendar/gui/dialogs/comp-editor.c | 461 +++++++++++++++++++++++++++++++++---- 1 file changed, 421 insertions(+), 40 deletions(-) (limited to 'calendar/gui/dialogs/comp-editor.c') diff --git a/calendar/gui/dialogs/comp-editor.c b/calendar/gui/dialogs/comp-editor.c index 2d894f3ff2..5347a40df3 100644 --- a/calendar/gui/dialogs/comp-editor.c +++ b/calendar/gui/dialogs/comp-editor.c @@ -23,9 +23,18 @@ #include #endif +#include +#include +#include #include +#include +#include +#include +#include #include #include "save-comp.h" +#include "delete-comp.h" +#include "send-comp.h" #include "comp-editor.h" @@ -43,11 +52,15 @@ struct _CompEditorPrivate { /* Toplevel window for the dialog */ GtkWidget *window; - + BonoboUIComponent *uic; + /* Notebook to hold the pages */ GtkNotebook *notebook; + GtkWidget *filesel; + gboolean changed; + gboolean needs_send; }; @@ -56,15 +69,37 @@ static void comp_editor_class_init (CompEditorClass *class); static void comp_editor_init (CompEditor *editor); static void comp_editor_destroy (GtkObject *object); +static void real_edit_comp (CompEditor *editor, CalComponent *comp); +static void save_comp (CompEditor *editor); +static void delete_comp (CompEditor *editor); +static void close_dialog (CompEditor *editor); + +static void page_changed_cb (GtkWidget *widget, gpointer data); +static void page_needs_send_cb (GtkWidget *widget, gpointer data); static void page_summary_changed_cb (GtkWidget *widget, const char *summary, gpointer data); static void page_dates_changed_cb (GtkWidget *widget, CompEditorPageDates *dates, gpointer data); -static void page_changed_cb (GtkWidget *widget, gpointer data); + +static void save_close_cmd (GtkWidget *widget, gpointer data); +static void save_as_cmd (GtkWidget *widget, gpointer data); +static void delete_cmd (GtkWidget *widget, gpointer data); +static void close_cmd (GtkWidget *widget, gpointer data); static void save_clicked_cb (GtkWidget *widget, gpointer data); static void close_clicked_cb (GtkWidget *widget, gpointer data); static void help_clicked_cb (GtkWidget *widget, gpointer data); static gint delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data); +static BonoboUIVerb verbs [] = { + BONOBO_UI_UNSAFE_VERB ("FileSaveAndClose", save_close_cmd), + BONOBO_UI_UNSAFE_VERB ("FileSaveAs", save_as_cmd), + BONOBO_UI_UNSAFE_VERB ("FileDelete", delete_cmd), + BONOBO_UI_UNSAFE_VERB ("FileClose", close_cmd), + + BONOBO_UI_VERB_END +}; + +#define CLASS(page) (COMP_EDITOR_CLASS (GTK_OBJECT (page)->klass)) + static GtkObjectClass *parent_class; @@ -95,14 +130,16 @@ comp_editor_get_type (void) /* Class initialization function for the calendar component editor */ static void -comp_editor_class_init (CompEditorClass *class) +comp_editor_class_init (CompEditorClass *klass) { GtkObjectClass *object_class; - object_class = (GtkObjectClass *) class; + object_class = (GtkObjectClass *) klass; parent_class = gtk_type_class (GTK_TYPE_OBJECT); + klass->edit_comp = real_edit_comp; + object_class->destroy = comp_editor_destroy; } @@ -111,6 +148,7 @@ static void setup_widgets (CompEditor *editor) { CompEditorPrivate *priv; + BonoboUIContainer *container; GtkWidget *vbox; GtkWidget *bbox; GtkWidget *pixmap; @@ -119,23 +157,29 @@ setup_widgets (CompEditor *editor) priv = editor->priv; /* Window and basic vbox */ - - priv->window = gtk_window_new (GTK_WINDOW_DIALOG); + priv->window = bonobo_window_new ("event-editor", "iCalendar Editor"); gtk_signal_connect (GTK_OBJECT (priv->window), "delete_event", GTK_SIGNAL_FUNC (delete_event_cb), editor); + priv->uic = bonobo_ui_component_new ("comp-editor"); + container = bonobo_ui_container_new (); + bonobo_ui_container_set_win (container, BONOBO_WINDOW (priv->window)); + bonobo_ui_component_set_container (priv->uic, BONOBO_OBJREF (container)); + + bonobo_ui_component_add_verb_list_with_data (priv->uic, verbs, editor); + bonobo_ui_util_set_ui (priv->uic, EVOLUTION_DATADIR "/gnome/gui", + "evolution-comp-editor.xml", "evolution-calendar"); + vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL); gtk_container_set_border_width (GTK_CONTAINER (vbox), GNOME_PAD_SMALL); - gtk_container_add (GTK_CONTAINER (priv->window), vbox); + bonobo_window_set_contents (BONOBO_WINDOW (priv->window), vbox); /* Notebook */ - priv->notebook = GTK_NOTEBOOK (gtk_notebook_new ()); gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (priv->notebook), TRUE, TRUE, 0); /* Buttons */ - bbox = gtk_hbutton_box_new (); gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END); gtk_box_pack_start (GTK_BOX (vbox), bbox, FALSE, FALSE, 0); @@ -170,6 +214,7 @@ comp_editor_init (CompEditor *editor) priv->pages = NULL; priv->changed = FALSE; + priv->needs_send = FALSE; } /* Destroy handler for the calendar component editor */ @@ -199,7 +244,7 @@ comp_editor_destroy (GtkObject *object) /** * comp_editor_append_page: * @editor: A component editor - * @page: Top level widget of the page + * @page: A component editor page * @label: Label of the page * * Appends a page to the editor notebook with the given label @@ -212,7 +257,7 @@ comp_editor_append_page (CompEditor *editor, CompEditorPrivate *priv; GtkWidget *page_widget; GtkWidget *label_widget; - + g_return_if_fail (editor != NULL); g_return_if_fail (IS_COMP_EDITOR (editor)); g_return_if_fail (page != NULL); @@ -221,9 +266,15 @@ comp_editor_append_page (CompEditor *editor, priv = editor->priv; - /* Only allow adding the pages while a component has not been set */ - g_return_if_fail (priv->comp == NULL); - + /* If we are editing something, fill the widgets with current info */ + if (priv->comp != NULL) { + CalComponent *comp; + + comp = comp_editor_get_current_comp (editor); + comp_editor_page_fill_widgets (page, comp); + gtk_object_unref (GTK_OBJECT (comp)); + } + page_widget = comp_editor_page_get_widget (page); g_assert (page_widget != NULL); @@ -233,12 +284,67 @@ comp_editor_append_page (CompEditor *editor, gtk_notebook_append_page (priv->notebook, page_widget, label_widget); /* Listen for things happening on the page */ + gtk_signal_connect (GTK_OBJECT (page), "needs_send", + GTK_SIGNAL_FUNC (page_needs_send_cb), editor); + gtk_signal_connect (GTK_OBJECT (page), "changed", + GTK_SIGNAL_FUNC (page_changed_cb), editor); gtk_signal_connect (GTK_OBJECT (page), "summary_changed", GTK_SIGNAL_FUNC (page_summary_changed_cb), editor); gtk_signal_connect (GTK_OBJECT (page), "dates_changed", GTK_SIGNAL_FUNC (page_dates_changed_cb), editor); - gtk_signal_connect (GTK_OBJECT (page), "changed", - GTK_SIGNAL_FUNC (page_changed_cb), editor); + +} + +/** + * comp_editor_remove_page: + * @editor: A component editor + * @page: A component editor page + * + * Removes the page from the component editor + **/ +void +comp_editor_remove_page (CompEditor *editor, CompEditorPage *page) +{ + CompEditorPrivate *priv; + GtkWidget *page_widget; + gint page_num; + + g_return_if_fail (editor != NULL); + g_return_if_fail (IS_COMP_EDITOR (editor)); + g_return_if_fail (page != NULL); + g_return_if_fail (IS_COMP_EDITOR_PAGE (page)); + + priv = editor->priv; + + page_widget = comp_editor_page_get_widget (page); + page_num = gtk_notebook_page_num (priv->notebook, page_widget); + gtk_notebook_remove_page (priv->notebook, page_num); +} + +/** + * comp_editor_show_page: + * @editor: + * @page: + * + * + **/ +void +comp_editor_show_page (CompEditor *editor, CompEditorPage *page) +{ + CompEditorPrivate *priv; + GtkWidget *page_widget; + gint page_num; + + g_return_if_fail (editor != NULL); + g_return_if_fail (IS_COMP_EDITOR (editor)); + g_return_if_fail (page != NULL); + g_return_if_fail (IS_COMP_EDITOR_PAGE (page)); + + priv = editor->priv; + + page_widget = comp_editor_page_get_widget (page); + page_num = gtk_notebook_page_num (priv->notebook, page_widget); + gtk_notebook_set_page (priv->notebook, page_num); } /** @@ -368,15 +474,8 @@ fill_widgets (CompEditor *editor) comp_editor_page_fill_widgets (l->data, priv->comp); } -/** - * comp_editor_edit_comp: - * @editor: A component editor - * @comp: A calendar component - * - * Starts the editor editing the given component - **/ -void -comp_editor_edit_comp (CompEditor *editor, CalComponent *comp) +static void +real_edit_comp (CompEditor *editor, CalComponent *comp) { CompEditorPrivate *priv; @@ -394,9 +493,124 @@ comp_editor_edit_comp (CompEditor *editor, CalComponent *comp) priv->comp = cal_component_clone (comp); set_title_from_comp (editor); - fill_widgets (editor); + fill_widgets (editor); } + +/** + * comp_editor_edit_comp: + * @editor: A component editor + * @comp: A calendar component + * + * Starts the editor editing the given component + **/ +void +comp_editor_edit_comp (CompEditor *editor, CalComponent *comp) +{ + CompEditorClass *klass; + + g_return_if_fail (editor != NULL); + g_return_if_fail (IS_COMP_EDITOR (editor)); + g_return_if_fail (comp != NULL); + g_return_if_fail (IS_CAL_COMPONENT (comp)); + + klass = COMP_EDITOR_CLASS (GTK_OBJECT (editor)->klass); + + if (klass->edit_comp) + klass->edit_comp (editor, comp); +} + +CalComponent * +comp_editor_get_current_comp (CompEditor *editor) +{ + CompEditorPrivate *priv; + CalComponent *comp; + GList *l; + + g_return_val_if_fail (editor != NULL, NULL); + g_return_val_if_fail (IS_COMP_EDITOR (editor), NULL); + + priv = editor->priv; + + comp = cal_component_clone (priv->comp); + for (l = priv->pages; l != NULL; l = l->next) + comp_editor_page_fill_component (l->data, comp); + + return comp; +} + +/** + * comp_editor_save_comp: + * @editor: + * + * + **/ +void +comp_editor_save_comp (CompEditor *editor) +{ + save_comp (editor); +} + +/** + * comp_editor_delete_comp: + * @editor: + * + * + **/ +void +comp_editor_delete_comp (CompEditor *editor) +{ + delete_comp (editor); +} + +/** + * comp_editor_send_comp: + * @editor: + * @method: + * + * + **/ +void +comp_editor_send_comp (CompEditor *editor, CalComponentItipMethod method) +{ + CalComponent *comp; + + comp = comp_editor_get_current_comp (editor); + + cal_component_commit_sequence (comp); + itip_send_comp (method, comp); + + gtk_object_unref (GTK_OBJECT (comp)); +} + +/** + * comp_editor_merge_ui: + * @editor: + * @filename: + * @verbs: + * + * + **/ +void +comp_editor_merge_ui (CompEditor *editor, const char *filename, BonoboUIVerb *verbs) +{ + CompEditorPrivate *priv; + BonoboUIEngine *engine; + BonoboUINode *node; + + g_return_if_fail (editor != NULL); + g_return_if_fail (IS_COMP_EDITOR (editor)); + + priv = editor->priv; + + engine = bonobo_window_get_ui_engine (BONOBO_WINDOW (priv->window)); + node = bonobo_ui_util_new_ui (priv->uic, filename, "", + "evolution-calendar"); + g_assert (node != NULL); + + bonobo_ui_engine_xml_merge_tree (engine, "/", node, "comp-editor"); + bonobo_ui_component_add_verb_list_with_data (priv->uic, verbs, editor); +} /* Brings attention to a window by raising it and giving it focus */ static void @@ -438,17 +652,35 @@ save_comp (CompEditor *editor) for (l = priv->pages; l != NULL; l = l->next) comp_editor_page_fill_component (l->data, priv->comp); + if (priv->needs_send && send_component_dialog (priv->comp)) { + cal_component_commit_sequence (priv->comp); + itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, priv->comp); + } + if (!cal_client_update_object (priv->client, priv->comp)) g_message ("save_comp (): Could not update the object!"); else priv->changed = FALSE; } +static void +delete_comp (CompEditor *editor) +{ + CompEditorPrivate *priv; + const char *uid; + + priv = editor->priv; + + cal_component_get_uid (priv->comp, &uid); + cal_client_remove_object (priv->client, uid); + close_dialog (editor); +} + static gboolean prompt_to_save_changes (CompEditor *editor) { CompEditorPrivate *priv; - + priv = editor->priv; if (!priv->changed) @@ -465,7 +697,6 @@ prompt_to_save_changes (CompEditor *editor) case 2: /* Cancel */ default: return FALSE; - break; } } @@ -482,6 +713,144 @@ close_dialog (CompEditor *editor) gtk_object_destroy (GTK_OBJECT (editor)); } +/* Menu Commands */ +static void +save_close_cmd (GtkWidget *widget, gpointer data) +{ + CompEditor *editor = COMP_EDITOR (data); + + save_comp (editor); + close_dialog (editor); +} + +static void +save_as_ok (GtkWidget *widget, gpointer data) +{ + CompEditor *editor = COMP_EDITOR (data); + CompEditorPrivate *priv; + char *path; + int fd, ret = 0; + + priv = editor->priv; + + path = gtk_file_selection_get_filename (GTK_FILE_SELECTION (priv->filesel)); + + fd = open (path, O_RDONLY); + if (fd != -1) { + GtkWidget *dlg; + GtkWidget *text; + + close (fd); + + dlg = gnome_dialog_new (_("Overwrite file?"), + GNOME_STOCK_BUTTON_YES, + GNOME_STOCK_BUTTON_NO, + NULL); + text = gtk_label_new (_("A file by that name already exists.\nOverwrite it?")); + gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dlg)->vbox), text, TRUE, TRUE, 4); + gtk_window_set_policy (GTK_WINDOW (dlg), FALSE, TRUE, FALSE); + gtk_widget_show (text); + + ret = gnome_dialog_run_and_close (GNOME_DIALOG (dlg)); + } + + if (ret == 0) { + gchar *ical_string; + + icalcomponent *top_level; + icalcomponent *icalcomp; + icalproperty *prop; + + top_level = icalcomponent_new (ICAL_VCALENDAR_COMPONENT); + + /* RFC 2445, section 4.7.1 */ + prop = icalproperty_new_calscale ("GREGORIAN"); + icalcomponent_add_property (top_level, prop); + + /* RFC 2445, section 4.7.3 */ + prop = icalproperty_new_prodid ("-//Ximian//NONSGML Evolution Calendar//EN"); + icalcomponent_add_property (top_level, prop); + + /* RFC 2445, section 4.7.4. This is the iCalendar spec version, *NOT* + * the product version! Do not change this! + */ + prop = icalproperty_new_version ("2.0"); + icalcomponent_add_property (top_level, prop); + + icalcomp = cal_component_get_icalcomponent (priv->comp); + g_assert (icalcomp != NULL); + + icalcomponent_add_component (top_level, icalcomp); + + ical_string = icalcomponent_as_ical_string (top_level); + + fd = open (path, O_WRONLY); + if (fd == -1) { + g_warning ("Couldn't save item"); + gtk_main_quit (); + return; + } + + write (fd, ical_string, strlen (ical_string)); + close (fd); + + gtk_main_quit (); + } +} + +static void +save_as_cmd (GtkWidget *widget, gpointer data) +{ + CompEditor *editor = COMP_EDITOR (data); + CompEditorPrivate *priv; + GtkFileSelection *fs; + char *path; + + priv = editor->priv; + + fs = GTK_FILE_SELECTION (gtk_file_selection_new (_("Save As..."))); + path = g_strdup_printf ("%s/", g_get_home_dir ()); + gtk_file_selection_set_filename (fs, path); + g_free (path); + + gtk_signal_connect (GTK_OBJECT (fs->ok_button), "clicked", + GTK_SIGNAL_FUNC (save_as_ok), editor); + gtk_signal_connect (GTK_OBJECT (fs->cancel_button), "clicked", + GTK_SIGNAL_FUNC (gtk_main_quit), NULL); + + priv->filesel = GTK_WIDGET (fs); + gtk_widget_show (priv->filesel); + gtk_grab_add (priv->filesel); + gtk_main (); + + gtk_widget_destroy (priv->filesel); + priv->filesel = NULL; +} + +static void +delete_cmd (GtkWidget *widget, gpointer data) +{ + CompEditor *editor = COMP_EDITOR (data); + CompEditorPrivate *priv; + CalComponentVType vtype; + + priv = editor->priv; + + vtype = cal_component_get_vtype (priv->comp); + + if (delete_component_dialog (priv->comp, 1, vtype, priv->window)) + delete_comp (editor); +} + +static void +close_cmd (GtkWidget *widget, gpointer data) +{ + CompEditor *editor = COMP_EDITOR (data); + + if (prompt_to_save_changes (editor)) + close_dialog (editor); +} + static void save_clicked_cb (GtkWidget *widget, gpointer data) { @@ -500,11 +869,35 @@ close_clicked_cb (GtkWidget *widget, gpointer data) close_dialog (editor); } +/* Button callbacks */ static void help_clicked_cb (GtkWidget *widget, gpointer data) { } +static void +page_changed_cb (GtkWidget *widget, gpointer data) +{ + CompEditor *editor = COMP_EDITOR (data); + CompEditorPrivate *priv; + + priv = editor->priv; + + priv->changed = TRUE; +} + +static void +page_needs_send_cb (GtkWidget *widget, gpointer data) +{ + CompEditor *editor = COMP_EDITOR (data); + CompEditorPrivate *priv; + + priv = editor->priv; + + priv->needs_send = TRUE; +} + +/* Page signal callbacks */ static void page_summary_changed_cb (GtkWidget *widget, const char *summary, gpointer data) { @@ -537,18 +930,6 @@ page_dates_changed_cb (GtkWidget *widget, priv->changed = TRUE; } - -static void -page_changed_cb (GtkWidget *widget, gpointer data) -{ - CompEditor *editor = COMP_EDITOR (data); - CompEditorPrivate *priv; - - priv = editor->priv; - - priv->changed = TRUE; -} - static gint delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data) { -- cgit v1.2.3