From 4ba91933ab9ba3c23fd75d113efd7844a879c60b Mon Sep 17 00:00:00 2001 From: Jesse Pavel Date: Mon, 2 Oct 2000 16:17:04 +0000 Subject: *** empty log message *** svn path=/trunk/; revision=5658 --- calendar/ChangeLog | 8 + calendar/gui/e-meeting-dialog.glade | 157 ++++++++++----- calendar/gui/e-meeting-edit.c | 370 +++++++++++++++++++++++++++--------- calendar/gui/e-meeting-edit.h | 11 +- calendar/gui/event-editor.c | 5 +- 5 files changed, 411 insertions(+), 140 deletions(-) diff --git a/calendar/ChangeLog b/calendar/ChangeLog index ef896182e1..925cada41a 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,3 +1,11 @@ +2000-09-29 Jesse Pavel + + * gui/e-meeting-edit.c: added code that makes changes to the underlying + iCAL structure of an event, when the user changes meeting information. + + * gui/e-meeting-dialog.glade: this is the Glade UI for the meeting dialog + and accoutrements. + 2000-09-29 Damon Chaplin * cal-util/cal-recur.c: updated to support RDATE end times or diff --git a/calendar/gui/e-meeting-dialog.glade b/calendar/gui/e-meeting-dialog.glade index 7dee1b9166..809eb38f8f 100644 --- a/calendar/gui/e-meeting-dialog.glade +++ b/calendar/gui/e-meeting-dialog.glade @@ -16,7 +16,7 @@ GtkWindow meeting_window 400 - 300 + 330 False Meeting Invitations GTK_WINDOW_DIALOG @@ -38,7 +38,7 @@ GTK_ORIENTATION_HORIZONTAL GTK_TOOLBAR_BOTH 5 - GTK_TOOLBAR_SPACE_EMPTY + GTK_TOOLBAR_SPACE_LINE GTK_RELIEF_NORMAL True @@ -51,69 +51,78 @@ GtkButton Toolbar:button send_button - 64 - + GNOME_STOCK_PIXMAP_MAIL_SND + + GtkVSeparator + vseparator1 + 13 + 58 + + GtkButton Toolbar:button - cancel_button - + button4 + GNOME_STOCK_PIXMAP_CLOSE + + + GtkVSeparator + vseparator2 + 12 + 58 + - GtkScrolledWindow - scrolledwindow1 - GTK_POLICY_AUTOMATIC - GTK_POLICY_AUTOMATIC - GTK_UPDATE_CONTINUOUS - GTK_UPDATE_CONTINUOUS + GtkHBox + hbox3 + 3 + False + 0 - 0 - True + 4 + False True - GtkCList - attendee_list - 3 - True - 2 - 222,80 - GTK_SELECTION_SINGLE - True - GTK_SHADOW_IN - - - GtkLabel - CList:title - attendee_label - - GTK_JUSTIFY_LEFT - False - 0.5 - 0.5 - 0 - 0 - + GtkLabel + label3 + + GTK_JUSTIFY_RIGHT + False + 0.5 + 0.5 + 3 + 0 + + 1 + False + False + + - - GtkLabel - CList:title - status_label - - GTK_JUSTIFY_CENTER - False - 0.5 - 0.5 - 0 - 0 - + + GtkEntry + organizer_entry + 252 + True + False + True + 0 + + + 0 + False + True + @@ -186,6 +195,58 @@ + + + GtkScrolledWindow + scrolledwindow1 + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_UPDATE_CONTINUOUS + GTK_UPDATE_CONTINUOUS + + 0 + True + True + + + + GtkCList + attendee_list + 3 + True + 2 + 222,80 + GTK_SELECTION_SINGLE + True + GTK_SHADOW_IN + + + GtkLabel + CList:title + attendee_label + + GTK_JUSTIFY_LEFT + False + 0.5 + 0.5 + 0 + 0 + + + + GtkLabel + CList:title + status_label + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + + diff --git a/calendar/gui/e-meeting-edit.c b/calendar/gui/e-meeting-edit.c index 4b0499542a..55442b819b 100644 --- a/calendar/gui/e-meeting-edit.c +++ b/calendar/gui/e-meeting-edit.c @@ -23,19 +23,44 @@ #include #include #include +#include #include "e-meeting-edit.h" #define E_MEETING_GLADE_XML "e-meeting-dialog.glade" #define E_MEETING_DEBUG -/* These are the widgets to be used in the GUI. */ -static GladeXML *xml; -static GtkWidget *meeting_window; -static GtkWidget *attendee_list; -static GtkWidget *address_entry; -static GtkWidget *add_dialog; -static gint selected_row; +typedef struct _EMeetingEditorPrivate EMeetingEditorPrivate; + +struct _EMeetingEditorPrivate { + /* These are the widgets to be used in the GUI. */ + GladeXML *xml; + GtkWidget *meeting_window; + GtkWidget *attendee_list; + GtkWidget *address_entry; + GtkWidget *add_dialog; + + /* Various pieces of information. */ + gint selected_row; + CalComponent *comp; + CalClient *client; + icalcomponent *icalcomp, *vevent; + + gint numentries; /* How many attendees are there? */ + gboolean dirty; /* Has anything changed? */ +}; + + +static gchar *partstat_values[] = { + "Needs action", + "Accepted", + "Declined", + "Tentative", + "Delegated", + "Completed", + "In Progress", + "Unknown" +}; static gboolean @@ -43,10 +68,28 @@ window_delete_cb (GtkWidget *widget, GdkEvent *event, gpointer data) { + EMeetingEditorPrivate *priv; + + priv = (EMeetingEditorPrivate *) ((EMeetingEditor *)data)->priv; #ifdef E_MEETING_DEBUG - g_print ("e-meeting-edit.c: The main window received a delete event.\n"); + g_printerr ("e-meeting-edit.c: The main window received a delete event.\n"); #endif + + if (priv->dirty == TRUE) { + /* FIXME: notify the event editor that our data has changed. + For now, I'll just display a dialog box. */ + { + GtkWidget *dialog; + + dialog = gnome_warning_dialog_parented ("Note that the meeting has changed,\n" + "and you should save this event.", + GTK_WINDOW (priv->meeting_window)); + gnome_dialog_run (GNOME_DIALOG(dialog)); + } + } + + return (FALSE); } @@ -55,9 +98,14 @@ static void window_destroy_cb (GtkWidget *widget, gpointer data) { + EMeetingEditorPrivate *priv; + #ifdef E_MEETING_DEBUG - g_print ("e-meeting-edit.c: The main window received a destroy event.\n"); + g_printerr ("e-meeting-edit.c: The main window received a destroy event.\n"); #endif + + priv = (EMeetingEditorPrivate *) ((EMeetingEditor *)data)->priv; + gtk_main_quit (); return; } @@ -65,68 +113,112 @@ window_destroy_cb (GtkWidget *widget, static void add_button_clicked_cb (GtkWidget *widget, gpointer data) { + EMeetingEditorPrivate *priv; gint button_num; + gchar buffer[200]; #ifdef E_MEETING_DEBUG - g_print ("e-meeting-edit.c: the add button was clicked.\n"); + g_printerr ("e-meeting-edit.c: the add button was clicked.\n"); #endif - if (add_dialog == NULL || address_entry == NULL) { - add_dialog = glade_xml_get_widget (xml, "add_dialog"); - address_entry = glade_xml_get_widget (xml, "address_entry"); - - gnome_dialog_set_close (GNOME_DIALOG (add_dialog), TRUE); - gnome_dialog_editable_enters (GNOME_DIALOG (add_dialog), GTK_EDITABLE (address_entry)); - gnome_dialog_close_hides (GNOME_DIALOG (add_dialog), TRUE); - gnome_dialog_set_default (GNOME_DIALOG (add_dialog), 0); + + priv = (EMeetingEditorPrivate *) ((EMeetingEditor *)data)->priv; + + if (priv->add_dialog == NULL || priv->address_entry == NULL) { + priv->add_dialog = glade_xml_get_widget (priv->xml, "add_dialog"); + priv->address_entry = glade_xml_get_widget (priv->xml, "address_entry"); + + gnome_dialog_set_close (GNOME_DIALOG (priv->add_dialog), TRUE); + gnome_dialog_editable_enters (GNOME_DIALOG (priv->add_dialog), + GTK_EDITABLE (priv->address_entry)); + gnome_dialog_close_hides (GNOME_DIALOG (priv->add_dialog), TRUE); + gnome_dialog_set_default (GNOME_DIALOG (priv->add_dialog), 0); } - g_return_if_fail (add_dialog != NULL); - g_return_if_fail (address_entry != NULL); + g_return_if_fail (priv->add_dialog != NULL); + g_return_if_fail (priv->address_entry != NULL); - gtk_widget_show (add_dialog); + gtk_widget_show (priv->add_dialog); - button_num = gnome_dialog_run (GNOME_DIALOG (add_dialog)); + button_num = gnome_dialog_run (GNOME_DIALOG (priv->add_dialog)); if (button_num == 0) { /* The user pressed Okay--let's add it to our list. */ - gchar temp_stat[] = "Needs action"; + icalproperty *prop; + icalparameter *param; + icalvalue *value; + gchar *address; gchar * row_text[2]; - address = gtk_entry_get_text (GTK_ENTRY (address_entry)); + address = gtk_entry_get_text (GTK_ENTRY (priv->address_entry)); + + prop = icalproperty_new (ICAL_ATTENDEE_PROPERTY); + g_snprintf (buffer, 190, "MAILTO:%s", address); + value = icalvalue_new_text (buffer); + icalproperty_set_value (prop, value); + + param = icalparameter_new_partstat (ICAL_PARTSTAT_PARAMETER); + icalparameter_set_partstat (param, ICAL_PARTSTAT_NEEDSACTION); + icalproperty_add_parameter (prop, param); + + icalcomponent_add_property (priv->vevent, prop); + row_text[0] = address; - row_text[1] = temp_stat; + row_text[1] = partstat_values[icalparameter_get_partstat (param)]; - gtk_clist_append (GTK_CLIST (attendee_list), row_text); + gtk_clist_append (GTK_CLIST (priv->attendee_list), row_text); + gtk_clist_set_row_data (GTK_CLIST (priv->attendee_list), priv->numentries, prop); + + priv->numentries++; + priv->dirty = TRUE; } - gtk_entry_set_text (GTK_ENTRY (address_entry), ""); + gtk_entry_set_text (GTK_ENTRY (priv->address_entry), ""); } static void delete_button_clicked_cb (GtkWidget *widget, gpointer data) { - if (selected_row < 0) { + EMeetingEditorPrivate *priv; + + priv = (EMeetingEditorPrivate *) ((EMeetingEditor *)data)->priv; + + if (priv->selected_row < 0) { GtkWidget *dialog; dialog = gnome_warning_dialog_parented ("You must select an entry to delete.", - GTK_WINDOW (add_dialog)); + GTK_WINDOW (priv->meeting_window)); gnome_dialog_run (GNOME_DIALOG(dialog)); } else { - gtk_clist_remove (GTK_CLIST (attendee_list), selected_row); - selected_row = -1; + /* Delete the associated property from the iCAL object. */ + icalproperty *prop; + + prop = (icalproperty *)gtk_clist_get_row_data (GTK_CLIST (priv->attendee_list), + priv->selected_row); + icalcomponent_remove_property (priv->vevent, prop); + icalproperty_free (prop); + + gtk_clist_remove (GTK_CLIST (priv->attendee_list), priv->selected_row); + priv->selected_row = -1; + priv->numentries--; + priv->dirty = TRUE; } } static void edit_button_clicked_cb (GtkWidget *widget, gpointer data) { - if (selected_row < 0) { + EMeetingEditorPrivate *priv; + + priv = (EMeetingEditorPrivate *) ((EMeetingEditor *)data)->priv; + + + if (priv->selected_row < 0) { GtkWidget *dialog; dialog = gnome_warning_dialog_parented ("You must select an entry to edit.", - GTK_WINDOW (add_dialog)); + GTK_WINDOW (priv->meeting_window)); gnome_dialog_run (GNOME_DIALOG(dialog)); return; } @@ -136,122 +228,220 @@ edit_button_clicked_cb (GtkWidget *widget, gpointer data) gint button_num; for (cntr = 0; cntr < 2; cntr++) { - gtk_clist_get_text (GTK_CLIST (attendee_list), - selected_row, + gtk_clist_get_text (GTK_CLIST (priv->attendee_list), + priv->selected_row, cntr, &text[cntr]); } - if (add_dialog == NULL || address_entry == NULL) { - add_dialog = glade_xml_get_widget (xml, "add_dialog"); - address_entry = glade_xml_get_widget (xml, "address_entry"); + if (priv->add_dialog == NULL || priv->address_entry == NULL) { + priv->add_dialog = glade_xml_get_widget (priv->xml, "add_dialog"); + priv->address_entry = glade_xml_get_widget (priv->xml, "address_entry"); - gnome_dialog_set_close (GNOME_DIALOG (add_dialog), TRUE); - gnome_dialog_editable_enters (GNOME_DIALOG (add_dialog), GTK_EDITABLE (address_entry)); - gnome_dialog_close_hides (GNOME_DIALOG (add_dialog), TRUE); - gnome_dialog_set_default (GNOME_DIALOG (add_dialog), 0); + gnome_dialog_set_close (GNOME_DIALOG (priv->add_dialog), TRUE); + gnome_dialog_editable_enters (GNOME_DIALOG (priv->add_dialog), + GTK_EDITABLE (priv->address_entry)); + gnome_dialog_close_hides (GNOME_DIALOG (priv->add_dialog), TRUE); + gnome_dialog_set_default (GNOME_DIALOG (priv->add_dialog), 0); } - gtk_entry_set_text (GTK_ENTRY (address_entry), text[0]); + gtk_entry_set_text (GTK_ENTRY (priv->address_entry), text[0]); - gtk_widget_show (add_dialog); + gtk_widget_show (priv->add_dialog); - button_num = gnome_dialog_run (GNOME_DIALOG (add_dialog)); + button_num = gnome_dialog_run (GNOME_DIALOG (priv->add_dialog)); if (button_num == 0) { gchar *new_text; + icalproperty *prop; + icalparameter *param; + icalvalue *value; + gchar buffer[200]; - new_text = gtk_entry_get_text (GTK_ENTRY (address_entry)); + new_text = gtk_entry_get_text (GTK_ENTRY (priv->address_entry)); - gtk_clist_set_text (GTK_CLIST (attendee_list), - selected_row, + gtk_clist_set_text (GTK_CLIST (priv->attendee_list), + priv->selected_row, 0, new_text); + + prop = (icalproperty *)gtk_clist_get_row_data (GTK_CLIST (priv->attendee_list), + priv->selected_row); + g_snprintf (buffer, 190, "MAILTO:%s", new_text); + value = icalvalue_new_text (buffer); + icalproperty_set_value (prop, value); + + priv->dirty = TRUE; } - gtk_entry_set_text (GTK_ENTRY (address_entry), ""); + gtk_entry_set_text (GTK_ENTRY (priv->address_entry), ""); } } - - - static void list_row_select_cb (GtkWidget *widget, gint row, gint column, GdkEventButton *event, gpointer data) { - selected_row = row; + EMeetingEditorPrivate *priv; + + priv = (EMeetingEditorPrivate *) ((EMeetingEditor *)data)->priv; + + priv->selected_row = row; } -static void -reset_widgets (void) + +/* ------------------------------------------------------------ */ +/* --------------------- Exported Functions ------------------- */ +/* ------------------------------------------------------------ */ + +EMeetingEditor * +e_meeting_editor_new (CalComponent *comp, CalClient *client) +{ + EMeetingEditor *object; + EMeetingEditorPrivate *priv; + + object = (EMeetingEditor *)g_new(EMeetingEditor, 1); + + priv = (EMeetingEditorPrivate *) g_new0(EMeetingEditorPrivate, 1); + priv->selected_row = -1; + priv->comp = comp; + priv->client = client; + priv->icalcomp = cal_component_get_icalcomponent (comp); + + object->priv = priv; + + return object; +} + +void +e_meeting_editor_free (EMeetingEditor *editor) { - xml = NULL; - meeting_window = NULL; - attendee_list = NULL; - address_entry = NULL; - add_dialog = NULL; - selected_row = -1; + if (editor == NULL) + return; + + if (editor->priv != NULL) + g_free (editor->priv); + + g_free (editor); } + + void -e_meeting_edit (CalComponent *comp, CalClient *client) +e_meeting_edit (EMeetingEditor *editor) { + EMeetingEditorPrivate *priv; GtkWidget *add_button, *delete_button, *edit_button; + icalproperty *prop; + icalparameter *param; + icalvalue *value; + gchar *text; + gchar *row_text[2]; + + + g_return_if_fail (editor != NULL); - reset_widgets (); + priv = (EMeetingEditorPrivate *)editor->priv; - xml = glade_xml_new (EVOLUTION_GLADEDIR "/" E_MEETING_GLADE_XML, NULL); + g_return_if_fail (priv != NULL); + + + priv->xml = glade_xml_new (EVOLUTION_GLADEDIR "/" E_MEETING_GLADE_XML, NULL); - meeting_window = glade_xml_get_widget (xml, "meeting_window"); - attendee_list = glade_xml_get_widget (xml, "attendee_list"); + priv->meeting_window = glade_xml_get_widget (priv->xml, "meeting_window"); + priv->attendee_list = glade_xml_get_widget (priv->xml, "attendee_list"); - gtk_clist_set_column_justification (GTK_CLIST (attendee_list), 1, GTK_JUSTIFY_CENTER); + gtk_clist_set_column_justification (GTK_CLIST (priv->attendee_list), 1, GTK_JUSTIFY_CENTER); - gtk_signal_connect (GTK_OBJECT (meeting_window), "delete_event", - GTK_SIGNAL_FUNC (window_delete_cb), NULL); + gtk_signal_connect (GTK_OBJECT (priv->meeting_window), "delete_event", + GTK_SIGNAL_FUNC (window_delete_cb), editor); - gtk_signal_connect_after (GTK_OBJECT (meeting_window), "delete_event", - GTK_SIGNAL_FUNC (window_destroy_cb), NULL); + gtk_signal_connect_after (GTK_OBJECT (priv->meeting_window), "delete_event", + GTK_SIGNAL_FUNC (window_destroy_cb), editor); - gtk_signal_connect (GTK_OBJECT (meeting_window), "destroy_event", - GTK_SIGNAL_FUNC (window_destroy_cb), NULL); + gtk_signal_connect (GTK_OBJECT (priv->meeting_window), "destroy_event", + GTK_SIGNAL_FUNC (window_destroy_cb), editor); - gtk_signal_connect (GTK_OBJECT (attendee_list), "select_row", - GTK_SIGNAL_FUNC (list_row_select_cb), NULL); + gtk_signal_connect (GTK_OBJECT (priv->attendee_list), "select_row", + GTK_SIGNAL_FUNC (list_row_select_cb), editor); - add_button = glade_xml_get_widget (xml, "add_button"); - delete_button = glade_xml_get_widget (xml, "delete_button"); - edit_button = glade_xml_get_widget (xml, "edit_button"); + add_button = glade_xml_get_widget (priv->xml, "add_button"); + delete_button = glade_xml_get_widget (priv->xml, "delete_button"); + edit_button = glade_xml_get_widget (priv->xml, "edit_button"); gtk_signal_connect (GTK_OBJECT (add_button), "clicked", - GTK_SIGNAL_FUNC (add_button_clicked_cb), NULL); + GTK_SIGNAL_FUNC (add_button_clicked_cb), editor); gtk_signal_connect (GTK_OBJECT (delete_button), "clicked", - GTK_SIGNAL_FUNC (delete_button_clicked_cb), NULL); + GTK_SIGNAL_FUNC (delete_button_clicked_cb), editor); gtk_signal_connect (GTK_OBJECT (edit_button), "clicked", - GTK_SIGNAL_FUNC (edit_button_clicked_cb), NULL); + GTK_SIGNAL_FUNC (edit_button_clicked_cb), editor); + + if (icalcomponent_isa (priv->icalcomp) != ICAL_VEVENT_COMPONENT) + priv->vevent = icalcomponent_get_first_component(priv->icalcomp,ICAL_VEVENT_COMPONENT); + else + priv->vevent = priv->icalcomp; + + g_assert (priv->vevent != NULL); + + /* Let's go through the iCAL object, and create a list entry + for each ATTENDEE property. */ + for (prop = icalcomponent_get_first_property (priv->vevent, ICAL_ATTENDEE_PROPERTY); + prop != NULL; + prop = icalcomponent_get_next_property (priv->vevent, ICAL_ATTENDEE_PROPERTY)) + { + value = icalproperty_get_value (prop); + text = g_strdup (icalvalue_as_ical_string (value)); + + /* Strip off the MAILTO: from the property value. */ + row_text[0] = strchr (text, ':'); + if (row_text[0] != NULL) + row_text[0]++; + else + row_text[0] = text; + + for (param = icalproperty_get_first_parameter (prop, ICAL_ANY_PARAMETER); + param != NULL && icalparameter_isa (param) != ICAL_PARTSTAT_PARAMETER; + param = icalproperty_get_next_parameter (prop, ICAL_ANY_PARAMETER) ); + + if (param == NULL) { + /* We need to add a PARTSTAT parameter to this property. */ + param = icalparameter_new_partstat (ICAL_PARTSTAT_PARAMETER); + icalparameter_set_partstat (param, ICAL_PARTSTAT_NEEDSACTION); + icalproperty_add_parameter (prop, param); + } + + /* row_text[1] corresponds to the `Status' column in the CList. */ + row_text[1] = partstat_values[icalparameter_get_partstat (param)]; + gtk_clist_append (GTK_CLIST (priv->attendee_list), row_text); + + /* The property to which each row in the list refers will be stored + as the data for that row. */ + gtk_clist_set_row_data (GTK_CLIST (priv->attendee_list), priv->numentries, prop); + priv->numentries++; + + g_free (text); + } + - gtk_widget_show (meeting_window); + gtk_widget_show (priv->meeting_window); gtk_main (); #ifdef E_MEETING_DEBUG - g_print ("e-meeting-edit.c: We've terminated the subsidiary gtk_main().\n"); + g_printerr ("e-meeting-edit.c: We've terminated the subsidiary gtk_main().\n"); #endif - if (meeting_window != NULL) - gtk_widget_destroy (meeting_window); - - if (add_dialog != NULL) - gtk_widget_destroy (add_dialog); - + if (priv->meeting_window != NULL) + gtk_widget_destroy (priv->meeting_window); + if (priv->add_dialog != NULL) + gtk_widget_destroy (priv->add_dialog); - gtk_object_destroy (GTK_OBJECT (xml)); + gtk_object_unref (GTK_OBJECT (priv->xml)); } diff --git a/calendar/gui/e-meeting-edit.h b/calendar/gui/e-meeting-edit.h index 82b2af9288..783a9c6b34 100644 --- a/calendar/gui/e-meeting-edit.h +++ b/calendar/gui/e-meeting-edit.h @@ -28,7 +28,16 @@ #include #include -void e_meeting_edit (CalComponent *comp, CalClient *client); +typedef struct _EMeetingEditor EMeetingEditor; + +struct _EMeetingEditor { + gpointer priv; +}; + + +EMeetingEditor * e_meeting_editor_new (CalComponent *comp, CalClient *client); +void e_meeting_edit (EMeetingEditor *editor); +void e_meeting_editor_free (EMeetingEditor *editor); #endif /* __E_MEETING_EDIT_H__ */ diff --git a/calendar/gui/event-editor.c b/calendar/gui/event-editor.c index 5f7b693be3..7575e1f34d 100644 --- a/calendar/gui/event-editor.c +++ b/calendar/gui/event-editor.c @@ -1153,6 +1153,7 @@ schedule_meeting_cb (GtkWidget *widget, gpointer data) { EventEditor *ee; EventEditorPrivate *priv; + EMeetingEditor *editor; ee = EVENT_EDITOR (data); @@ -1160,7 +1161,9 @@ schedule_meeting_cb (GtkWidget *widget, gpointer data) priv = (EventEditorPrivate *)ee->priv; - e_meeting_edit (priv->comp, priv->client); + editor = e_meeting_editor_new (priv->comp, priv->client); + e_meeting_edit (editor); + e_meeting_editor_free (editor); } -- cgit v1.2.3