From d639a620a6438ea93787cedfe9f3eb87014275a3 Mon Sep 17 00:00:00 2001 From: JP Rosevear Date: Wed, 19 Sep 2001 04:33:33 +0000 Subject: A page that shows the meeting time selector and free/busy data for 2001-09-18 JP Rosevear * gui/dialogs/schedule-page.*: A page that shows the meeting time selector and free/busy data for attendees * gui/dialogs/meeting-page.c: use the meeting model to track/edit attendees, remove table value conversion routines and simple table routines (set_attendees): take a pointer array (meeting_page_destroy): destroy the pointer array, save state (meeting_page_init): new pointer array (meeting_page_fill_widgets): don't null the deleted attendees field (popup_delegate_cb): array add (popup_delete_cb): array add (cleanup_attendees): iterate over the array to unref now (meeting_page_fill_widgets): don't null out fields, no need to add attendees here (invite_entry_changed): use e_meeting_attendee routines (popup_delegate_cb): ditto (popup_delete_cb): ditto (meeting_page_new): take new arg and pass it to construct (meeting_page_construct): take new arg, use e-meeting-model routines to construct table * gui/dialogs/task-editor.c (task_editor_init): new meeting model (task_editor_destroy): unref the model * gui/dialogs/event-editor.c (event_editor_init): make new model and pass it to meeting and schedule pages (event_editor_set_cal_client): virtual function, set meeting model client (event_editor_edit_comp): add the attendees to the model (event_editor_destroy): unref model * gui/dialogs/comp-editor.h: add virtual function * gui/dialogs/comp-editor.c (comp_editor_set_cal_client): make set_cal_client a virutal function * gui/e-meeting-types.h: generally useful type defines * gui/e-meeting-time-sel*.[hc]: Move here and use an e-table for the attendee list and extract display information from the new meeting model and attendees * gui/e-meeting-time-sel.etspec: spec for the table * gui/e-meeting-attendee.[hc]: meeting attendees for the model, with to/from conversions for CalComponentAttendee structure, emits changed signal and allows getting and setting of free busy periods * gui/e-meeting-model.[hc]: move the model out on its own * gui/e-itip-control.c (write_error_html): clean up warnings svn path=/trunk/; revision=12968 --- calendar/gui/dialogs/Makefile.am | 3 + calendar/gui/dialogs/comp-editor.c | 89 ++-- calendar/gui/dialogs/comp-editor.h | 1 + calendar/gui/dialogs/event-editor.c | 51 +- calendar/gui/dialogs/meeting-page.c | 843 ++++--------------------------- calendar/gui/dialogs/meeting-page.etspec | 2 +- calendar/gui/dialogs/meeting-page.h | 5 +- calendar/gui/dialogs/schedule-page.c | 402 +++++++++++++++ calendar/gui/dialogs/schedule-page.glade | 36 ++ calendar/gui/dialogs/schedule-page.h | 60 +++ calendar/gui/dialogs/task-editor.c | 8 +- 11 files changed, 717 insertions(+), 783 deletions(-) create mode 100644 calendar/gui/dialogs/schedule-page.c create mode 100644 calendar/gui/dialogs/schedule-page.glade create mode 100644 calendar/gui/dialogs/schedule-page.h (limited to 'calendar/gui/dialogs') diff --git a/calendar/gui/dialogs/Makefile.am b/calendar/gui/dialogs/Makefile.am index b93a5b2335..c0c410a565 100644 --- a/calendar/gui/dialogs/Makefile.am +++ b/calendar/gui/dialogs/Makefile.am @@ -69,6 +69,8 @@ libcal_dialogs_a_SOURCES = \ recurrence-page.h \ save-comp.c \ save-comp.h \ + schedule-page.c \ + schedule-page.h \ send-comp.c \ send-comp.h \ task-editor.c \ @@ -87,6 +89,7 @@ glade_DATA = \ event-page.glade \ meeting-page.glade \ recurrence-page.glade \ + schedule-page.glade \ task-details-page.glade \ task-page.glade diff --git a/calendar/gui/dialogs/comp-editor.c b/calendar/gui/dialogs/comp-editor.c index 433a9879aa..de4e528334 100644 --- a/calendar/gui/dialogs/comp-editor.c +++ b/calendar/gui/dialogs/comp-editor.c @@ -76,6 +76,7 @@ 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_set_cal_client (CompEditor *editor, CalClient *client); static void real_edit_comp (CompEditor *editor, CalComponent *comp); static void real_send_comp (CompEditor *editor, CalComponentItipMethod method); static void save_comp (CompEditor *editor); @@ -174,6 +175,7 @@ comp_editor_class_init (CompEditorClass *klass) parent_class = gtk_type_class (GTK_TYPE_OBJECT); + klass->set_cal_client = real_set_cal_client; klass->edit_comp = real_edit_comp; klass->send_comp = real_send_comp; @@ -242,7 +244,6 @@ comp_editor_destroy (GtkObject *object) { CompEditor *editor; CompEditorPrivate *priv; - GList *l; editor = COMP_EDITOR (object); priv = editor->priv; @@ -252,12 +253,6 @@ comp_editor_destroy (GtkObject *object) priv->window = NULL; } - /* We want to destroy the pages after the widgets get destroyed, - since they have lots of signal handlers connected to the widgets - with the pages as the data. */ - for (l = priv->pages; l != NULL; l = l->next) - gtk_object_unref (GTK_OBJECT (l->data)); - gtk_signal_disconnect_by_data (GTK_OBJECT (priv->client), editor); g_free (priv); @@ -398,41 +393,15 @@ comp_editor_show_page (CompEditor *editor, CompEditorPage *page) void comp_editor_set_cal_client (CompEditor *editor, CalClient *client) { - CompEditorPrivate *priv; - GList *elem; - + CompEditorClass *klass; + g_return_if_fail (editor != NULL); g_return_if_fail (IS_COMP_EDITOR (editor)); - priv = editor->priv; - - if (client == priv->client) - return; - - if (client) { - g_return_if_fail (IS_CAL_CLIENT (client)); - g_return_if_fail (cal_client_get_load_state (client) == - CAL_CLIENT_LOAD_LOADED); - gtk_object_ref (GTK_OBJECT (client)); - } + klass = COMP_EDITOR_CLASS (GTK_OBJECT (editor)->klass); - if (priv->client) { - gtk_signal_disconnect_by_data (GTK_OBJECT (priv->client), - editor); - gtk_object_unref (GTK_OBJECT (priv->client)); - } - - priv->client = client; - - /* Pass the client to any pages that need it. */ - for (elem = priv->pages; elem; elem = elem->next) - comp_editor_page_set_cal_client (elem->data, client); - - gtk_signal_connect (GTK_OBJECT (priv->client), "obj_updated", - GTK_SIGNAL_FUNC (obj_updated_cb), editor); - - gtk_signal_connect (GTK_OBJECT (priv->client), "obj_removed", - GTK_SIGNAL_FUNC (obj_removed_cb), editor); + if (klass->set_cal_client) + klass->set_cal_client (editor, client); } /** @@ -519,6 +488,46 @@ fill_widgets (CompEditor *editor) for (l = priv->pages; l != NULL; l = l->next) comp_editor_page_fill_widgets (l->data, priv->comp); +} + +static void +real_set_cal_client (CompEditor *editor, CalClient *client) +{ + CompEditorPrivate *priv; + GList *elem; + + g_return_if_fail (editor != NULL); + g_return_if_fail (IS_COMP_EDITOR (editor)); + + priv = editor->priv; + + if (client == priv->client) + return; + + if (client) { + g_return_if_fail (IS_CAL_CLIENT (client)); + g_return_if_fail (cal_client_get_load_state (client) == + CAL_CLIENT_LOAD_LOADED); + gtk_object_ref (GTK_OBJECT (client)); + } + + if (priv->client) { + gtk_signal_disconnect_by_data (GTK_OBJECT (priv->client), + editor); + gtk_object_unref (GTK_OBJECT (priv->client)); + } + + priv->client = client; + + /* Pass the client to any pages that need it. */ + for (elem = priv->pages; elem; elem = elem->next) + comp_editor_page_set_cal_client (elem->data, client); + + gtk_signal_connect (GTK_OBJECT (priv->client), "obj_updated", + GTK_SIGNAL_FUNC (obj_updated_cb), editor); + + gtk_signal_connect (GTK_OBJECT (priv->client), "obj_removed", + GTK_SIGNAL_FUNC (obj_removed_cb), editor); } static void @@ -814,11 +823,15 @@ static void close_dialog (CompEditor *editor) { CompEditorPrivate *priv; + GList *l; priv = editor->priv; g_assert (priv->window != NULL); + for (l = priv->pages; l != NULL; l = l->next) + gtk_object_unref (GTK_OBJECT (l->data)); + gtk_object_destroy (GTK_OBJECT (editor)); } diff --git a/calendar/gui/dialogs/comp-editor.h b/calendar/gui/dialogs/comp-editor.h index a8a459e008..64920879cc 100644 --- a/calendar/gui/dialogs/comp-editor.h +++ b/calendar/gui/dialogs/comp-editor.h @@ -52,6 +52,7 @@ typedef struct { GtkObjectClass parent_class; /* Virtual functions */ + void (* set_cal_client) (CompEditor *page, CalClient *client); void (* edit_comp) (CompEditor *page, CalComponent *comp); void (* send_comp) (CompEditor *page, CalComponentItipMethod method); } CompEditorClass; diff --git a/calendar/gui/dialogs/event-editor.c b/calendar/gui/dialogs/event-editor.c index a58d1d4b82..f95f201883 100644 --- a/calendar/gui/dialogs/event-editor.c +++ b/calendar/gui/dialogs/event-editor.c @@ -35,6 +35,7 @@ #include "alarm-page.h" #include "recurrence-page.h" #include "meeting-page.h" +#include "schedule-page.h" #include "cancel-comp.h" #include "event-editor.h" @@ -43,6 +44,9 @@ struct _EventEditorPrivate { AlarmPage *alarm_page; RecurrencePage *recur_page; MeetingPage *meet_page; + SchedulePage *sched_page; + + EMeetingModel *model; gboolean meeting_shown; }; @@ -51,6 +55,7 @@ struct _EventEditorPrivate { static void event_editor_class_init (EventEditorClass *class); static void event_editor_init (EventEditor *ee); +static void event_editor_set_cal_client (CompEditor *editor, CalClient *client); static void event_editor_edit_comp (CompEditor *editor, CalComponent *comp); static void event_editor_send_comp (CompEditor *editor, CalComponentItipMethod method); static void event_editor_destroy (GtkObject *object); @@ -117,6 +122,7 @@ event_editor_class_init (EventEditorClass *klass) parent_class = gtk_type_class (TYPE_COMP_EDITOR); + editor_class->set_cal_client = event_editor_set_cal_client; editor_class->edit_comp = event_editor_edit_comp; editor_class->send_comp = event_editor_send_comp; @@ -164,12 +170,19 @@ event_editor_init (EventEditor *ee) comp_editor_append_page (COMP_EDITOR (ee), COMP_EDITOR_PAGE (priv->recur_page), _("Recurrence")); - - priv->meet_page = meeting_page_new (); + + priv->model = E_MEETING_MODEL (e_meeting_model_new ()); + + priv->meet_page = meeting_page_new (priv->model); comp_editor_append_page (COMP_EDITOR (ee), COMP_EDITOR_PAGE (priv->meet_page), _("Meeting")); + priv->sched_page = schedule_page_new (priv->model); + comp_editor_append_page (COMP_EDITOR (ee), + COMP_EDITOR_PAGE (priv->sched_page), + _("Scheduling")); + comp_editor_merge_ui (COMP_EDITOR (ee), EVOLUTION_DATADIR "/gnome/ui/evolution-event-editor.xml", verbs); @@ -178,6 +191,21 @@ event_editor_init (EventEditor *ee) set_menu_sens (ee); } +static void +event_editor_set_cal_client (CompEditor *editor, CalClient *client) +{ + EventEditor *ee; + EventEditorPrivate *priv; + + ee = EVENT_EDITOR (editor); + priv = ee->priv; + + e_meeting_model_set_cal_client (priv->model, client); + + if (parent_class->set_cal_client) + parent_class->set_cal_client (editor, client); +} + static void event_editor_edit_comp (CompEditor *editor, CalComponent *comp) { @@ -191,9 +219,20 @@ event_editor_edit_comp (CompEditor *editor, CalComponent *comp) cal_component_get_attendee_list (comp, &attendees); if (attendees == NULL) { comp_editor_remove_page (editor, COMP_EDITOR_PAGE (priv->meet_page)); + comp_editor_remove_page (editor, COMP_EDITOR_PAGE (priv->sched_page)); + e_meeting_model_remove_all_attendees (priv->model); priv->meeting_shown = FALSE; set_menu_sens (ee); - } + } else { + GSList *l; + for (l = attendees; l != NULL; l = l->next) { + CalComponentAttendee *ca = l->data; + EMeetingAttendee *ia = E_MEETING_ATTENDEE (e_meeting_attendee_new_from_cal_component_attendee (ca)); + + e_meeting_model_add_attendee (priv->model, ia); + gtk_object_unref (GTK_OBJECT (ia)); + } + } cal_component_free_attendee_list (attendees); if (parent_class->edit_comp) @@ -240,6 +279,9 @@ event_editor_destroy (GtkObject *object) gtk_object_unref (GTK_OBJECT (priv->alarm_page)); gtk_object_unref (GTK_OBJECT (priv->recur_page)); gtk_object_unref (GTK_OBJECT (priv->meet_page)); + gtk_object_unref (GTK_OBJECT (priv->sched_page)); + + gtk_object_unref (GTK_OBJECT (priv->model)); if (GTK_OBJECT_CLASS (parent_class)->destroy) (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); @@ -271,6 +313,9 @@ schedule_meeting_cmd (GtkWidget *widget, gpointer data) comp_editor_append_page (COMP_EDITOR (ee), COMP_EDITOR_PAGE (priv->meet_page), _("Meeting")); + comp_editor_append_page (COMP_EDITOR (ee), + COMP_EDITOR_PAGE (priv->sched_page), + _("Scheduling")); priv->meeting_shown = TRUE; set_menu_sens (ee); } diff --git a/calendar/gui/dialogs/meeting-page.c b/calendar/gui/dialogs/meeting-page.c index 9d833d304e..5a146e3d04 100644 --- a/calendar/gui/dialogs/meeting-page.c +++ b/calendar/gui/dialogs/meeting-page.c @@ -52,6 +52,8 @@ #include #include "Evolution-Addressbook-SelectNames.h" #include "../component-factory.h" +#include "../e-meeting-attendee.h" +#include "../e-meeting-model.h" #include "../itip-utils.h" #include "comp-editor-util.h" #include "e-delegate-dialog.h" @@ -74,27 +76,10 @@ enum columns { MEETING_COLUMN_COUNT }; -struct attendee { - char *address; - char *member; - - icalparameter_cutype cutype; - icalparameter_role role; - icalparameter_partstat status; - gboolean rsvp; - - char *delto; - char *delfrom; - char *sentby; - char *cn; - char *language; -}; - /* Private part of the MeetingPage structure */ struct _MeetingPagePrivate { /* Lists of attendees */ - GSList *attendees; - GSList *deleted_attendees; + GPtrArray *deleted_attendees; /* To use in case of cancellation */ CalComponent *comp; @@ -121,8 +106,8 @@ struct _MeetingPagePrivate { GtkWidget *invite; /* E Table stuff */ - ETableModel *model; - GtkWidget *etable; + EMeetingModel *model; + ETableScrolled *etable; gint row; /* For handling who the organizer is */ @@ -145,8 +130,6 @@ static void meeting_page_focus_main_widget (CompEditorPage *page); static void meeting_page_fill_widgets (CompEditorPage *page, CalComponent *comp); static void meeting_page_fill_component (CompEditorPage *page, CalComponent *comp); -static int row_count (ETableModel *etm, void *data); -static void *init_value (ETableModel *etm, int col, void *data); static gint right_click_cb (ETable *etable, gint row, gint col, GdkEvent *event, gpointer data); static CompEditorPageClass *parent_class = NULL; @@ -217,8 +200,7 @@ meeting_page_init (MeetingPage *mpage) priv = g_new0 (MeetingPagePrivate, 1); mpage->priv = priv; - priv->attendees = NULL; - priv->deleted_attendees = NULL; + priv->deleted_attendees = g_ptr_array_new (); priv->comp = NULL; @@ -233,56 +215,35 @@ meeting_page_init (MeetingPage *mpage) } static void -set_attendees (CalComponent *comp, GSList *attendees) +set_attendees (CalComponent *comp, const GPtrArray *attendees) { - GSList *comp_attendees = NULL; - GSList *l; + GSList *comp_attendees = NULL, *l; + int i; - for (l = attendees; l != NULL; l = l->next) { - struct attendee *attendee = l->data; - CalComponentAttendee *att = g_new0 (CalComponentAttendee, 1); + for (i = 0; i < attendees->len; i++) { + EMeetingAttendee *ia = g_ptr_array_index (attendees, i); + CalComponentAttendee *ca; + ca = e_meeting_attendee_as_cal_component_attendee (ia); - att->value = attendee->address; - att->member = (attendee->member && *attendee->member) ? attendee->member : NULL; - att->cutype= attendee->cutype; - att->role = attendee->role; - att->status = attendee->status; - att->rsvp = attendee->rsvp; - att->delto = (attendee->delto && *attendee->delto) ? attendee->delto : NULL; - att->delfrom = (attendee->delfrom && *attendee->delfrom) ? attendee->delfrom : NULL; - att->sentby = (attendee->sentby && *attendee->sentby) ? attendee->sentby : NULL; - att->cn = (attendee->cn && *attendee->cn) ? attendee->cn : NULL; - att->language = (attendee->language && *attendee->language) ? attendee->language : NULL; - - comp_attendees = g_slist_prepend (comp_attendees, att); + comp_attendees = g_slist_prepend (comp_attendees, ca); } comp_attendees = g_slist_reverse (comp_attendees); cal_component_set_attendee_list (comp, comp_attendees); + + for (l = comp_attendees; l != NULL; l = l->next) + g_free (l->data); g_slist_free (comp_attendees); } static void -cleanup_attendees (GSList *attendees) +cleanup_attendees (GPtrArray *attendees) { - GSList *l; + int i; - for (l = attendees; l != NULL; l = l->next) { - struct attendee *a = l->data; - - g_free (a->address); - g_free (a->member); - g_free (a->delto); - g_free (a->delfrom); - g_free (a->sentby); - g_free (a->cn); - g_free (a->language); - - g_free (a); - } - - g_slist_free (attendees); + for (i = 0; i < attendees->len; i++) + gtk_object_unref (GTK_OBJECT (g_ptr_array_index (attendees, i))); } /* Destroy handler for the task page */ @@ -291,6 +252,8 @@ meeting_page_destroy (GtkObject *object) { MeetingPage *mpage; MeetingPagePrivate *priv; + ETable *real_table; + char *filename; g_return_if_fail (object != NULL); g_return_if_fail (IS_MEETING_PAGE (object)); @@ -301,12 +264,21 @@ meeting_page_destroy (GtkObject *object) if (priv->comp != NULL) gtk_object_unref (GTK_OBJECT (priv->comp)); - cleanup_attendees (priv->attendees); cleanup_attendees (priv->deleted_attendees); + g_ptr_array_free (priv->deleted_attendees, FALSE); itip_addresses_free (priv->addresses); g_list_free (priv->address_strings); + gtk_object_unref (GTK_OBJECT (priv->model)); + + /* Save state */ + filename = g_strdup_printf ("%s/config/et-header-meeting-page", + evolution_dir); + real_table = e_table_scrolled_get_table (priv->etable); + e_table_save_state (real_table, filename); + g_free (filename); + if (priv->xml) { gtk_object_unref (GTK_OBJECT (priv->xml)); priv->xml = NULL; @@ -376,8 +348,8 @@ meeting_page_fill_widgets (CompEditorPage *page, CalComponent *comp) MeetingPage *mpage; MeetingPagePrivate *priv; CalComponentOrganizer organizer; - GSList *attendees, *l; - GList *l2; + GSList *attendees; + GList *l; mpage = MEETING_PAGE (page); priv = mpage->priv; @@ -389,10 +361,7 @@ meeting_page_fill_widgets (CompEditorPage *page, CalComponent *comp) gtk_object_unref (GTK_OBJECT (priv->comp)); priv->comp = NULL; - cleanup_attendees (priv->attendees); cleanup_attendees (priv->deleted_attendees); - priv->attendees = NULL; - priv->deleted_attendees = NULL; /* Clean the screen */ clear_widgets (mpage); @@ -403,8 +372,8 @@ meeting_page_fill_widgets (CompEditorPage *page, CalComponent *comp) /* Organizer */ cal_component_get_organizer (comp, &organizer); priv->addresses = itip_addresses_get (); - for (l2 = priv->addresses; l2 != NULL; l2 = l2->next) { - ItipAddress *a = l2->data; + for (l = priv->addresses; l != NULL; l = l->next) { + ItipAddress *a = l->data; priv->address_strings = g_list_append (priv->address_strings, a->full); if (a->default_address) @@ -431,36 +400,11 @@ meeting_page_fill_widgets (CompEditorPage *page, CalComponent *comp) e_dialog_editable_set (GTK_COMBO (priv->organizer)->entry, priv->default_address); } - /* Attendees */ - cal_component_get_attendee_list (comp, &attendees); - for (l = attendees; l != NULL; l = l->next) { - CalComponentAttendee *att = l->data; - struct attendee *attendee = g_new0 (struct attendee, 1); - - attendee->address = att->value ? g_strdup (att->value) : g_strdup (""); - attendee->member = att->member ? g_strdup (att->member) : g_strdup (""); - attendee->cutype= att->cutype; - attendee->role = att->role; - attendee->status = att->status; - attendee->rsvp = att->rsvp; - attendee->delto = att->delto ? g_strdup (att->delto) : g_strdup (""); - attendee->delfrom = att->delfrom ? g_strdup (att->delfrom) : g_strdup (""); - attendee->sentby = att->sentby ? g_strdup (att->sentby) : g_strdup (""); - attendee->cn = att->cn ? g_strdup (att->cn) : g_strdup (""); - attendee->language = att->language ? g_strdup (att->language) : g_strdup (""); - - priv->attendees = g_slist_prepend (priv->attendees, attendee); - - } - priv->attendees = g_slist_reverse (priv->attendees); - cal_component_free_attendee_list (attendees); - - /* Table */ - e_table_model_rows_inserted (priv->model, 0, row_count (priv->model, mpage)); - /* So the comp editor knows we need to send if anything changes */ - if (priv->attendees != NULL) + cal_component_get_attendee_list (comp, &attendees); + if (attendees != NULL) comp_editor_page_notify_needs_send (COMP_EDITOR_PAGE (mpage)); + cal_component_free_attendee_list (attendees); priv->updating = FALSE; } @@ -514,7 +458,7 @@ meeting_page_fill_component (CompEditorPage *page, CalComponent *comp) g_free (cn); } - set_attendees (comp, priv->attendees); + set_attendees (comp, e_meeting_model_get_attendees (priv->model)); } @@ -561,167 +505,6 @@ get_widgets (MeetingPage *mpage) && priv->existing_organizer_btn); } - -static icalparameter_cutype -text_to_type (const char *type) -{ - if (!g_strcasecmp (type, _("Individual"))) - return ICAL_CUTYPE_INDIVIDUAL; - else if (!g_strcasecmp (type, _("Group"))) - return ICAL_CUTYPE_GROUP; - else if (!g_strcasecmp (type, _("Resource"))) - return ICAL_CUTYPE_RESOURCE; - else if (!g_strcasecmp (type, _("Room"))) - return ICAL_CUTYPE_ROOM; - else - return ICAL_CUTYPE_NONE; -} - -static char * -type_to_text (icalparameter_cutype type) -{ - switch (type) { - case ICAL_CUTYPE_INDIVIDUAL: - return _("Individual"); - case ICAL_CUTYPE_GROUP: - return _("Group"); - case ICAL_CUTYPE_RESOURCE: - return _("Resource"); - case ICAL_CUTYPE_ROOM: - return _("Room"); - default: - return _("Unknown"); - } - - return NULL; - -} - -static icalparameter_role -text_to_role (const char *role) -{ - if (!g_strcasecmp (role, _("Chair"))) - return ICAL_ROLE_CHAIR; - else if (!g_strcasecmp (role, _("Required Participant"))) - return ICAL_ROLE_REQPARTICIPANT; - else if (!g_strcasecmp (role, _("Optional Participant"))) - return ICAL_ROLE_OPTPARTICIPANT; - else if (!g_strcasecmp (role, _("Non-Participant"))) - return ICAL_ROLE_NONPARTICIPANT; - else - return ICAL_ROLE_NONE; -} - -static char * -role_to_text (icalparameter_role role) -{ - switch (role) { - case ICAL_ROLE_CHAIR: - return _("Chair"); - case ICAL_ROLE_REQPARTICIPANT: - return _("Required Participant"); - case ICAL_ROLE_OPTPARTICIPANT: - return _("Optional Participant"); - case ICAL_ROLE_NONPARTICIPANT: - return _("Non-Participant"); - default: - return _("Unknown"); - } - - return NULL; -} - -static gboolean -text_to_boolean (const char *role) -{ - if (!g_strcasecmp (role, _("Yes"))) - return TRUE; - else - return FALSE; -} - -static char * -boolean_to_text (gboolean b) -{ - if (b) - return _("Yes"); - else - return _("No"); -} - -static icalparameter_partstat -text_to_partstat (const char *partstat) -{ - if (!g_strcasecmp (partstat, _("Needs Action"))) - return ICAL_PARTSTAT_NEEDSACTION; - else if (!g_strcasecmp (partstat, _("Accepted"))) - return ICAL_PARTSTAT_ACCEPTED; - else if (!g_strcasecmp (partstat, _("Declined"))) - return ICAL_PARTSTAT_DECLINED; - else if (!g_strcasecmp (partstat, _("Tentative"))) - return ICAL_PARTSTAT_TENTATIVE; - else if (!g_strcasecmp (partstat, _("Delegated"))) - return ICAL_PARTSTAT_DELEGATED; - else if (!g_strcasecmp (partstat, _("Completed"))) - return ICAL_PARTSTAT_COMPLETED; - else if (!g_strcasecmp (partstat, _("In Process"))) - return ICAL_PARTSTAT_INPROCESS; - else - return ICAL_PARTSTAT_NONE; -} - -static char * -partstat_to_text (icalparameter_partstat partstat) -{ - switch (partstat) { - case ICAL_PARTSTAT_NEEDSACTION: - return _("Needs Action"); - case ICAL_PARTSTAT_ACCEPTED: - return _("Accepted"); - case ICAL_PARTSTAT_DECLINED: - return _("Declined"); - case ICAL_PARTSTAT_TENTATIVE: - return _("Tentative"); - case ICAL_PARTSTAT_DELEGATED: - return _("Delegated"); - case ICAL_PARTSTAT_COMPLETED: - return _("Completed"); - case ICAL_PARTSTAT_INPROCESS: - return _("In Process"); - default: - return _("Unknown"); - } - - return NULL; -} - -static struct attendee * -find_match (MeetingPage *mpage, const char *address, int *pos) -{ - MeetingPagePrivate *priv; - struct attendee *a; - GSList *l; - int i; - - priv = mpage->priv; - - if (address == NULL) - return NULL; - - /* Make sure we can add the new delegatee person */ - for (l = priv->attendees, i = 0; l != NULL; l = l->next, i++) { - a = l->data; - - if (a->address != NULL && !g_strcasecmp (itip_strip_mailto (a->address), itip_strip_mailto (address))) { - if (pos != NULL) - *pos = i; - return a; - } - } - - return NULL; -} - static void duplicate_error (void) { @@ -759,50 +542,28 @@ invite_entry_changed (BonoboListener *listener, return; for (i = 0; destv[i] != NULL; i++) { - struct attendee *a; + EMeetingAttendee *ia; const char *name, *address; - char *str; - int row_cnt; name = e_destination_get_name (destv[i]); address = e_destination_get_email (destv[i]); - if (find_match (mpage, address, NULL) == NULL) { - a = g_new0 (struct attendee, 1); - - a->address = g_strdup_printf ("MAILTO:%s", address); - a->member = init_value (NULL, MEETING_MEMBER_COL, mpage); - str = init_value (NULL, MEETING_TYPE_COL, mpage); - a->cutype = text_to_type (str); - g_free (str); + if (e_meeting_model_find_attendee (priv->model, address, NULL) == NULL) { + ia = e_meeting_model_add_attendee_with_defaults (priv->model); + e_meeting_attendee_set_address (ia, g_strdup_printf ("MAILTO:%s", address)); if (!strcmp (section, _("Chair Persons"))) - a->role = ICAL_ROLE_CHAIR; + e_meeting_attendee_set_role (ia, ICAL_ROLE_CHAIR); else if (!strcmp (section, _("Required Participants"))) - a->role = ICAL_ROLE_REQPARTICIPANT; + e_meeting_attendee_set_role (ia, ICAL_ROLE_REQPARTICIPANT); else if (!strcmp (section, _("Optional Participants"))) - a->role = ICAL_ROLE_OPTPARTICIPANT; + e_meeting_attendee_set_role (ia, ICAL_ROLE_OPTPARTICIPANT); else if (!strcmp (section, _("Non-Participants"))) - a->role = ICAL_ROLE_NONPARTICIPANT; - - str = init_value (NULL, MEETING_RSVP_COL, mpage); - a->rsvp = text_to_boolean (str); - g_free (str); - a->delto = init_value (NULL, MEETING_DELTO_COL, mpage); - a->delfrom = init_value (NULL, MEETING_DELTO_COL, mpage); - str = init_value (NULL, MEETING_STATUS_COL, mpage); - a->status = text_to_partstat (str); - g_free (str); - a->cn = name ? g_strdup (name) : g_strdup (""); - a->language = init_value (NULL, MEETING_LANG_COL, mpage); - - priv->attendees = g_slist_append (priv->attendees, a); - - row_cnt = row_count (priv->model, mpage) - 1; - e_table_model_row_inserted (priv->model, row_cnt); + e_meeting_attendee_set_role (ia, ICAL_ROLE_NONPARTICIPANT); + e_meeting_attendee_set_cn (ia, g_strdup (name)); - comp_editor_page_notify_needs_send (COMP_EDITOR_PAGE (mpage)); - comp_editor_page_notify_changed (COMP_EDITOR_PAGE (mpage)); + comp_editor_page_notify_needs_send (COMP_EDITOR_PAGE (mpage)); + comp_editor_page_notify_changed (COMP_EDITOR_PAGE (mpage)); } } e_destination_freev (destv); @@ -976,373 +737,6 @@ init_widgets (MeetingPage *mpage) GTK_SIGNAL_FUNC (invite_cb), mpage); } -static int -column_count (ETableModel *etm, void *data) -{ - return MEETING_COLUMN_COUNT; -} - -static int -row_count (ETableModel *etm, void *data) -{ - MeetingPage *mpage; - MeetingPagePrivate *priv; - - mpage = MEETING_PAGE (data); - priv = mpage->priv; - - return g_slist_length (priv->attendees); -} - -static void -append_row (ETableModel *etm, ETableModel *model, int row, void *data) -{ - MeetingPage *mpage; - MeetingPagePrivate *priv; - struct attendee *attendee; - char *address; - gint row_cnt; - - mpage = MEETING_PAGE (data); - priv = mpage->priv; - - address = (char *) e_table_model_value_at (model, MEETING_ATTENDEE_COL, row); - if (find_match (mpage, address, NULL) != NULL) { - duplicate_error (); - return; - } - - attendee = g_new0 (struct attendee, 1); - - attendee->address = g_strdup_printf ("MAILTO:%s", address); - attendee->member = g_strdup (e_table_model_value_at (model, MEETING_MEMBER_COL, row)); - attendee->cutype = text_to_type (e_table_model_value_at (model, MEETING_TYPE_COL, row)); - attendee->role = text_to_role (e_table_model_value_at (model, MEETING_ROLE_COL, row)); - attendee->rsvp = text_to_boolean (e_table_model_value_at (model, MEETING_RSVP_COL, row)); - attendee->delto = g_strdup (e_table_model_value_at (model, MEETING_DELTO_COL, row)); - attendee->delfrom = g_strdup (e_table_model_value_at (model, MEETING_DELFROM_COL, row)); - attendee->status = text_to_partstat (e_table_model_value_at (model, MEETING_STATUS_COL, row)); - attendee->cn = g_strdup (e_table_model_value_at (model, MEETING_CN_COL, row)); - attendee->language = g_strdup (e_table_model_value_at (model, MEETING_LANG_COL, row)); - - priv->attendees = g_slist_append (priv->attendees, attendee); - - row_cnt = row_count (etm, data) - 1; - e_table_model_row_inserted (E_TABLE_MODEL (etm), row_cnt); - - comp_editor_page_notify_needs_send (COMP_EDITOR_PAGE (mpage)); - comp_editor_page_notify_changed (COMP_EDITOR_PAGE (mpage)); -} - -static void * -value_at (ETableModel *etm, int col, int row, void *data) -{ - MeetingPage *mpage; - MeetingPagePrivate *priv; - struct attendee *attendee; - - mpage = MEETING_PAGE (data); - priv = mpage->priv; - - attendee = g_slist_nth_data (priv->attendees, row); - - switch (col) { - case MEETING_ATTENDEE_COL: - return (void *)itip_strip_mailto (attendee->address); - case MEETING_MEMBER_COL: - return attendee->member; - case MEETING_TYPE_COL: - return type_to_text (attendee->cutype); - case MEETING_ROLE_COL: - return role_to_text (attendee->role); - case MEETING_RSVP_COL: - return boolean_to_text (attendee->rsvp); - case MEETING_DELTO_COL: - return (void *)itip_strip_mailto (attendee->delto); - case MEETING_DELFROM_COL: - return (void *)itip_strip_mailto (attendee->delfrom); - case MEETING_STATUS_COL: - return partstat_to_text (attendee->status); - case MEETING_CN_COL: - return attendee->cn; - case MEETING_LANG_COL: - return attendee->language; - } - - return NULL; -} - -static void -set_value_at (ETableModel *etm, int col, int row, const void *val, void *data) -{ - MeetingPage *mpage; - MeetingPagePrivate *priv; - struct attendee *attendee; - - mpage = MEETING_PAGE (data); - priv = mpage->priv; - - attendee = g_slist_nth_data (priv->attendees, row); - - switch (col) { - case MEETING_ATTENDEE_COL: - if (attendee->address) - g_free (attendee->address); - attendee->address = g_strdup_printf ("MAILTO:%s", (char *) val); - break; - case MEETING_MEMBER_COL: - if (attendee->member) - g_free (attendee->member); - attendee->member = g_strdup (val); - break; - case MEETING_TYPE_COL: - attendee->cutype = text_to_type (val); - break; - case MEETING_ROLE_COL: - attendee->role = text_to_role (val); - break; - case MEETING_RSVP_COL: - attendee->rsvp = text_to_boolean (val); - break; - case MEETING_DELTO_COL: - if (attendee->delto) - g_free (attendee->delto); - attendee->delto = g_strdup (val); - break; - case MEETING_DELFROM_COL: - if (attendee->delfrom) - g_free (attendee->delfrom); - attendee->delto = g_strdup (val); - break; - case MEETING_STATUS_COL: - attendee->status = text_to_partstat (val); - break; - case MEETING_CN_COL: - if (attendee->cn) - g_free (attendee->cn); - attendee->cn = g_strdup (val); - break; - case MEETING_LANG_COL: - if (attendee->language) - g_free (attendee->language); - attendee->language = g_strdup (val); - break; - } - - if (!priv->updating) { - comp_editor_page_notify_needs_send (COMP_EDITOR_PAGE (mpage)); - comp_editor_page_notify_changed (COMP_EDITOR_PAGE (mpage)); - } -} - -static gboolean -is_cell_editable (ETableModel *etm, int col, int row, void *data) -{ - switch (col) { - case MEETING_DELTO_COL: - case MEETING_DELFROM_COL: - return FALSE; - - default: - } - - return TRUE; -} - -static void * -duplicate_value (ETableModel *etm, int col, const void *val, void *data) -{ - return g_strdup (val); -} - -static void -free_value (ETableModel *etm, int col, void *val, void *data) -{ - g_free (val); -} - -static void * -init_value (ETableModel *etm, int col, void *data) -{ - switch (col) { - case MEETING_ATTENDEE_COL: - return g_strdup (""); - case MEETING_MEMBER_COL: - return g_strdup (""); - case MEETING_TYPE_COL: - return g_strdup (_("Individual")); - case MEETING_ROLE_COL: - return g_strdup (_("Required Participant")); - case MEETING_RSVP_COL: - return g_strdup (_("Yes")); - case MEETING_DELTO_COL: - return g_strdup (""); - case MEETING_DELFROM_COL: - return g_strdup (""); - case MEETING_STATUS_COL: - return g_strdup (_("Needs Action")); - case MEETING_CN_COL: - return g_strdup (""); - case MEETING_LANG_COL: - return g_strdup ("en"); - } - - return g_strdup (""); -} - -static gboolean -value_is_empty (ETableModel *etm, int col, const void *val, void *data) -{ - - switch (col) { - case MEETING_ATTENDEE_COL: - case MEETING_MEMBER_COL: - case MEETING_DELTO_COL: - case MEETING_DELFROM_COL: - case MEETING_CN_COL: - if (val && !g_strcasecmp (val, "")) - return TRUE; - else - return FALSE; - default: - } - - return TRUE; -} - -static char * -value_to_string (ETableModel *etm, int col, const void *val, void *data) -{ - return g_strdup (val); -} - -static void -etable_destroy_cb (ETable *real_table, MeetingPage *mpage) -{ - char *filename; - - filename = g_strdup_printf ("%s/config/et-header-meeting-page", - evolution_dir); - e_table_save_state (real_table, filename); - g_free (filename); -} - -static void -build_etable (MeetingPage *mpage) -{ - MeetingPagePrivate *priv; - ETable *real_table; - ETableExtras *extras; - GList *strings; - ECell *popup_cell, *cell; - - char *filename; - - priv = mpage->priv; - - extras = e_table_extras_new (); - - /* For type */ - cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT); - popup_cell = e_cell_combo_new (); - e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell); - gtk_object_unref (GTK_OBJECT (cell)); - - strings = NULL; - strings = g_list_append (strings, _("Individual")); - strings = g_list_append (strings, _("Group")); - strings = g_list_append (strings, _("Resource")); - strings = g_list_append (strings, _("Room")); - strings = g_list_append (strings, _("Unknown")); - - e_cell_combo_set_popdown_strings (E_CELL_COMBO (popup_cell), strings); - e_table_extras_add_cell (extras, "typeedit", popup_cell); - - /* For role */ - cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT); - popup_cell = e_cell_combo_new (); - e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell); - gtk_object_unref (GTK_OBJECT (cell)); - - strings = NULL; - strings = g_list_append (strings, _("Chair")); - strings = g_list_append (strings, _("Required Participant")); - strings = g_list_append (strings, _("Optional Participant")); - strings = g_list_append (strings, _("Non-Participant")); - strings = g_list_append (strings, _("Unknown")); - - e_cell_combo_set_popdown_strings (E_CELL_COMBO (popup_cell), strings); - e_table_extras_add_cell (extras, "roleedit", popup_cell); - - /* For rsvp */ - cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT); - popup_cell = e_cell_combo_new (); - e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell); - gtk_object_unref (GTK_OBJECT (cell)); - - strings = NULL; - strings = g_list_append (strings, _("Yes")); - strings = g_list_append (strings, _("No")); - - e_cell_combo_set_popdown_strings (E_CELL_COMBO (popup_cell), strings); - e_table_extras_add_cell (extras, "rsvpedit", popup_cell); - - /* For status */ - cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT); - popup_cell = e_cell_combo_new (); - e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell); - gtk_object_unref (GTK_OBJECT (cell)); - - strings = NULL; - strings = g_list_append (strings, _("Needs Action")); - strings = g_list_append (strings, _("Accepted")); - strings = g_list_append (strings, _("Declined")); - strings = g_list_append (strings, _("Tentative")); - strings = g_list_append (strings, _("Delegated")); - - e_cell_combo_set_popdown_strings (E_CELL_COMBO (popup_cell), strings); - e_table_extras_add_cell (extras, "statusedit", popup_cell); - - - /* The table itself */ - priv->model = e_table_simple_new (column_count, - row_count, - append_row, - - value_at, - set_value_at, - is_cell_editable, - - NULL, - NULL, - - duplicate_value, - free_value, - init_value, - value_is_empty, - value_to_string, - mpage); - - priv->etable = e_table_scrolled_new_from_spec_file (priv->model, - extras, - EVOLUTION_ETSPECDIR "/meeting-page.etspec", - NULL); - filename = g_strdup_printf ("%s/config/et-header-meeting-page", - evolution_dir); - real_table = e_table_scrolled_get_table (E_TABLE_SCROLLED (priv->etable)); - e_table_load_state (real_table, filename); - g_free (filename); - - gtk_signal_connect (GTK_OBJECT (real_table), - "destroy", GTK_SIGNAL_FUNC (etable_destroy_cb), - mpage); - - gtk_signal_connect (GTK_OBJECT (real_table), - "right_click", GTK_SIGNAL_FUNC (right_click_cb), mpage); - - gtk_object_unref (GTK_OBJECT (extras)); -} - static void popup_delegate_cb (GtkWidget *widget, gpointer data) { @@ -1350,78 +744,49 @@ popup_delegate_cb (GtkWidget *widget, gpointer data) MeetingPagePrivate *priv; EDelegateDialog *edd; GtkWidget *dialog; - struct attendee *a; + EMeetingAttendee *ia; char *address = NULL, *name = NULL; - gint row_cnt; priv = mpage->priv; - a = g_slist_nth_data (priv->attendees, priv->row); + ia = e_meeting_model_find_attendee_at_row (priv->model, priv->row); /* Show dialog. */ - edd = e_delegate_dialog_new (NULL, itip_strip_mailto (a->delto)); + edd = e_delegate_dialog_new (NULL, itip_strip_mailto (e_meeting_attendee_get_delto (ia))); dialog = e_delegate_dialog_get_toplevel (edd); if (gnome_dialog_run_and_close (GNOME_DIALOG (dialog)) == 0){ - struct attendee *a; - char *str; + EMeetingAttendee *ic; name = e_delegate_dialog_get_delegate_name (edd); address = e_delegate_dialog_get_delegate (edd); /* Make sure we can add the new delegatee person */ - if (find_match (mpage, address, NULL) != NULL) { + if (e_meeting_model_find_attendee (priv->model, address, NULL) != NULL) { duplicate_error (); goto cleanup; } /* Update information for attendee */ - a = g_slist_nth_data (priv->attendees, priv->row); - if (a->delto) { - struct attendee *b; + if (e_meeting_attendee_is_set_delto (ia)) { + EMeetingAttendee *ib; - b = find_match (mpage, a->delto, NULL); - if (b != NULL) { - priv->attendees = g_slist_remove (priv->attendees, b); - priv->deleted_attendees = g_slist_append (priv->deleted_attendees, b); + ib = e_meeting_model_find_attendee (priv->model, itip_strip_mailto (e_meeting_attendee_get_delto (ia)), NULL); + if (ib != NULL) { + gtk_object_ref (GTK_OBJECT (ib)); + g_ptr_array_add (priv->deleted_attendees, ib); - e_table_model_row_deleted (priv->model, priv->row); + e_meeting_model_remove_attendee (priv->model, ib); } - g_free (a->delto); } - - a->delto = g_strdup_printf ("MAILTO:%s", address); + e_meeting_attendee_set_delto (ia, g_strdup_printf ("MAILTO:%s", address)); /* Construct delegatee information */ - a = g_new0 (struct attendee, 1); - - a->address = g_strdup_printf ("MAILTO:%s", address); - a->member = init_value (NULL, MEETING_MEMBER_COL, mpage); - str = init_value (NULL, MEETING_TYPE_COL, mpage); - a->cutype = text_to_type (str); - g_free (str); - str = init_value (NULL, MEETING_ROLE_COL, mpage); - a->role = text_to_role (str); - g_free (str); - str = init_value (NULL, MEETING_RSVP_COL, mpage); - a->rsvp = text_to_boolean (str); - g_free (str); - a->delto = init_value (NULL, MEETING_DELTO_COL, mpage); - a->delfrom = g_strdup_printf ("MAILTO:%s", (char *) value_at (NULL, MEETING_ATTENDEE_COL, priv->row, mpage)); - str = init_value (NULL, MEETING_STATUS_COL, mpage); - a->status = text_to_partstat (str); - g_free (str); - a->cn = name ? g_strdup (name) : g_strdup (""); - a->language = init_value (NULL, MEETING_LANG_COL, mpage); + ic = e_meeting_model_add_attendee_with_defaults (priv->model); - priv->attendees = g_slist_append (priv->attendees, a); - - row_cnt = row_count (priv->model, mpage) - 1; - e_table_model_row_changed (priv->model, priv->row); - e_table_model_row_inserted (priv->model, row_cnt); - - comp_editor_page_notify_needs_send (COMP_EDITOR_PAGE (mpage)); - comp_editor_page_notify_changed (COMP_EDITOR_PAGE (mpage)); + e_meeting_attendee_set_address (ic, g_strdup_printf ("MAILTO:%s", address)); + e_meeting_attendee_set_delfrom (ic, g_strdup (e_meeting_attendee_get_address (ia))); + e_meeting_attendee_set_cn (ic, g_strdup (name)); } cleanup: @@ -1435,44 +800,33 @@ popup_delete_cb (GtkWidget *widget, gpointer data) { MeetingPage *mpage = MEETING_PAGE (data); MeetingPagePrivate *priv; - struct attendee *a; + EMeetingAttendee *ia; int pos = 0; priv = mpage->priv; - - a = g_slist_nth_data (priv->attendees, priv->row); + + ia = e_meeting_model_find_attendee_at_row (priv->model, priv->row); /* If this was a delegatee, no longer delegate */ - if (a->delfrom != NULL && *a->delfrom != '\0') { - struct attendee *b; + if (e_meeting_attendee_is_set_delfrom (ia)) { + EMeetingAttendee *ib; - b = find_match (mpage, a->delfrom, &pos); - if (b != NULL && b->delto) { - g_free (b->delto); - b->delto = g_strdup (""); - - e_table_model_row_changed (priv->model, pos); - } + ib = e_meeting_model_find_attendee (priv->model, e_meeting_attendee_get_delfrom (ia), &pos); + if (ib != NULL) + e_meeting_attendee_set_delto (ib, NULL); } /* Handle deleting all attendees in the delegation chain */ - pos = priv->row; - while (a != NULL) { - struct attendee *b = NULL; - - e_table_model_pre_change (priv->model); - - priv->attendees = g_slist_remove (priv->attendees, a); - priv->deleted_attendees = g_slist_append (priv->deleted_attendees, a); + while (ia != NULL) { + EMeetingAttendee *ib = NULL; - e_table_model_row_deleted (priv->model, pos); + gtk_object_ref (GTK_OBJECT (ia)); + g_ptr_array_add (priv->deleted_attendees, ia); + e_meeting_model_remove_attendee (priv->model, ia); - comp_editor_page_notify_needs_send (COMP_EDITOR_PAGE (mpage)); - comp_editor_page_notify_changed (COMP_EDITOR_PAGE (mpage)); - - if (a->delto != NULL) - b = find_match (mpage, a->delto, &pos); - a = b; + if (e_meeting_attendee_get_delto (ia) != NULL) + ib = e_meeting_model_find_attendee (priv->model, e_meeting_attendee_get_delto (ia), NULL); + ia = ib; } } @@ -1527,9 +881,11 @@ right_click_cb (ETable *etable, gint row, gint col, GdkEvent *event, gpointer da * be created. **/ MeetingPage * -meeting_page_construct (MeetingPage *mpage) +meeting_page_construct (MeetingPage *mpage, EMeetingModel *emm) { MeetingPagePrivate *priv; + ETable *real_table; + gchar *filename; priv = mpage->priv; @@ -1548,9 +904,21 @@ meeting_page_construct (MeetingPage *mpage) } /* The etable displaying attendees and their status */ - build_etable (mpage); - gtk_widget_show (priv->etable); - gtk_box_pack_start (GTK_BOX (priv->main), priv->etable, TRUE, TRUE, 2); + gtk_object_ref (GTK_OBJECT (emm)); + priv->model = emm; + + filename = g_strdup_printf ("%s/config/et-header-meeting-page", evolution_dir); + priv->etable = e_meeting_model_etable_from_model (priv->model, + EVOLUTION_ETSPECDIR "/meeting-page.etspec", + filename); + g_free (filename); + + real_table = e_table_scrolled_get_table (priv->etable); + gtk_signal_connect (GTK_OBJECT (real_table), + "right_click", GTK_SIGNAL_FUNC (right_click_cb), mpage); + + gtk_widget_show (GTK_WIDGET (priv->etable)); + gtk_box_pack_start (GTK_BOX (priv->main), GTK_WIDGET (priv->etable), TRUE, TRUE, 2); /* Init the widget signals */ init_widgets (mpage); @@ -1567,12 +935,12 @@ meeting_page_construct (MeetingPage *mpage) * not be created. **/ MeetingPage * -meeting_page_new (void) +meeting_page_new (EMeetingModel *emm) { MeetingPage *mpage; mpage = gtk_type_new (TYPE_MEETING_PAGE); - if (!meeting_page_construct (mpage)) { + if (!meeting_page_construct (mpage, emm)) { gtk_object_unref (GTK_OBJECT (mpage)); return NULL; } @@ -1605,4 +973,3 @@ meeting_page_get_cancel_comp (MeetingPage *mpage) return cal_component_clone (priv->comp); } - diff --git a/calendar/gui/dialogs/meeting-page.etspec b/calendar/gui/dialogs/meeting-page.etspec index da49873e61..96bc480fe9 100644 --- a/calendar/gui/dialogs/meeting-page.etspec +++ b/calendar/gui/dialogs/meeting-page.etspec @@ -1,4 +1,4 @@ - + diff --git a/calendar/gui/dialogs/meeting-page.h b/calendar/gui/dialogs/meeting-page.h index ba8a6d18b4..206ee90bb8 100644 --- a/calendar/gui/dialogs/meeting-page.h +++ b/calendar/gui/dialogs/meeting-page.h @@ -25,6 +25,7 @@ #ifndef MEETING_PAGE_H #define MEETING_PAGE_H +#include "../e-meeting-model.h" #include "comp-editor-page.h" BEGIN_GNOME_DECLS @@ -52,8 +53,8 @@ typedef struct { GtkType meeting_page_get_type (void); -MeetingPage *meeting_page_construct (MeetingPage *mpage); -MeetingPage *meeting_page_new (void); +MeetingPage *meeting_page_construct (MeetingPage *mpage, EMeetingModel *emm); +MeetingPage *meeting_page_new (EMeetingModel *emm); CalComponent *meeting_page_get_cancel_comp (MeetingPage *mpage); diff --git a/calendar/gui/dialogs/schedule-page.c b/calendar/gui/dialogs/schedule-page.c new file mode 100644 index 0000000000..42510e0b5a --- /dev/null +++ b/calendar/gui/dialogs/schedule-page.c @@ -0,0 +1,402 @@ +/* Evolution calendar - Scheduling page + * + * Copyright (C) 2001 Ximian, Inc. + * + * Authors: Federico Mena-Quintero + * Miguel de Icaza + * Seth Alves + * JP Rosevear + * + * 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 of the License, 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. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include "Evolution-Addressbook-SelectNames.h" +#include "../e-meeting-time-sel.h" +#include "../itip-utils.h" +#include "comp-editor-util.h" +#include "e-delegate-dialog.h" +#include "schedule-page.h" + + + +/* Private part of the SchedulePage structure */ +struct _SchedulePagePrivate { + /* Glade XML data */ + GladeXML *xml; + + /* Widgets from the Glade file */ + GtkWidget *main; + + /* Model */ + EMeetingModel *model; + + /* Selector */ + EMeetingTimeSelector *sel; + + gboolean updating; +}; + + + +static void schedule_page_class_init (SchedulePageClass *class); +static void schedule_page_init (SchedulePage *spage); +static void schedule_page_destroy (GtkObject *object); + +static GtkWidget *schedule_page_get_widget (CompEditorPage *page); +static void schedule_page_focus_main_widget (CompEditorPage *page); +static void schedule_page_fill_widgets (CompEditorPage *page, CalComponent *comp); +static void schedule_page_fill_component (CompEditorPage *page, CalComponent *comp); + +static void model_row_changed_cb (ETableModel *etm, int row, gpointer data); +static void row_count_changed_cb (ETableModel *etm, int row, int count, gpointer data); + +static CompEditorPageClass *parent_class = NULL; + + + +/** + * schedule_page_get_type: + * + * Registers the #SchedulePage class if necessary, and returns the type ID + * associated to it. + * + * Return value: The type ID of the #SchedulePage class. + **/ +GtkType +schedule_page_get_type (void) +{ + static GtkType schedule_page_type; + + if (!schedule_page_type) { + static const GtkTypeInfo schedule_page_info = { + "SchedulePage", + sizeof (SchedulePage), + sizeof (SchedulePageClass), + (GtkClassInitFunc) schedule_page_class_init, + (GtkObjectInitFunc) schedule_page_init, + NULL, /* reserved_1 */ + NULL, /* reserved_2 */ + (GtkClassInitFunc) NULL + }; + + schedule_page_type = + gtk_type_unique (TYPE_COMP_EDITOR_PAGE, + &schedule_page_info); + } + + return schedule_page_type; +} + +/* Class initialization function for the schedule page */ +static void +schedule_page_class_init (SchedulePageClass *class) +{ + CompEditorPageClass *editor_page_class; + GtkObjectClass *object_class; + + editor_page_class = (CompEditorPageClass *) class; + object_class = (GtkObjectClass *) class; + + parent_class = gtk_type_class (TYPE_COMP_EDITOR_PAGE); + + editor_page_class->get_widget = schedule_page_get_widget; + editor_page_class->focus_main_widget = schedule_page_focus_main_widget; + editor_page_class->fill_widgets = schedule_page_fill_widgets; + editor_page_class->fill_component = schedule_page_fill_component; + editor_page_class->set_summary = NULL; + editor_page_class->set_dates = NULL; + + object_class->destroy = schedule_page_destroy; +} + +/* Object initialization function for the schedule page */ +static void +schedule_page_init (SchedulePage *spage) +{ + SchedulePagePrivate *priv; + + priv = g_new0 (SchedulePagePrivate, 1); + spage->priv = priv; + + priv->xml = NULL; + + priv->main = NULL; + + priv->updating = FALSE; +} + +/* Destroy handler for the schedule page */ +static void +schedule_page_destroy (GtkObject *object) +{ + SchedulePage *spage; + SchedulePagePrivate *priv; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_SCHEDULE_PAGE (object)); + + spage = SCHEDULE_PAGE (object); + priv = spage->priv; + + if (priv->xml) { + gtk_object_unref (GTK_OBJECT (priv->xml)); + priv->xml = NULL; + } + + gtk_object_unref (GTK_OBJECT (priv->model)); + + g_free (priv); + spage->priv = NULL; + + if (GTK_OBJECT_CLASS (parent_class)->destroy) + (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); +} + + + +/* get_widget handler for the schedule page */ +static GtkWidget * +schedule_page_get_widget (CompEditorPage *page) +{ + SchedulePage *spage; + SchedulePagePrivate *priv; + + spage = SCHEDULE_PAGE (page); + priv = spage->priv; + + return priv->main; +} + +/* focus_main_widget handler for the schedule page */ +static void +schedule_page_focus_main_widget (CompEditorPage *page) +{ + SchedulePage *spage; + SchedulePagePrivate *priv; + + spage = SCHEDULE_PAGE (page); + priv = spage->priv; + + gtk_widget_grab_focus (GTK_WIDGET (priv->sel)); +} + +/* Fills the widgets with default values */ +static void +clear_widgets (SchedulePage *spage) +{ + SchedulePagePrivate *priv; + + priv = spage->priv; +} + +/* fill_widgets handler for the schedule page */ +static void +schedule_page_fill_widgets (CompEditorPage *page, CalComponent *comp) +{ + SchedulePage *spage; + SchedulePagePrivate *priv; + GSList *attendees; + + spage = SCHEDULE_PAGE (page); + priv = spage->priv; + + priv->updating = TRUE; + + /* Clean the screen */ + clear_widgets (spage); + + /* Attendees */ + cal_component_get_attendee_list (comp, &attendees); + + /* So the comp editor knows we need to send if anything changes */ + if (attendees != NULL) + comp_editor_page_notify_needs_send (COMP_EDITOR_PAGE (spage)); + + cal_component_free_attendee_list (attendees); + + priv->updating = FALSE; +} + +/* fill_component handler for the schedule page */ +static void +schedule_page_fill_component (CompEditorPage *page, CalComponent *comp) +{ + SchedulePage *spage; + SchedulePagePrivate *priv; + + spage = SCHEDULE_PAGE (page); + priv = spage->priv; +} + + + +/* Gets the widgets from the XML file and returns if they are all available. */ +static gboolean +get_widgets (SchedulePage *spage) +{ + SchedulePagePrivate *priv; + + priv = spage->priv; + +#define GW(name) glade_xml_get_widget (priv->xml, name) + + priv->main = GW ("schedule-page"); + if (!priv->main) + return FALSE; + + gtk_widget_ref (priv->main); + gtk_widget_unparent (priv->main); + +#undef GW + + return TRUE; +} + +/* Hooks the widget signals */ +static void +init_widgets (SchedulePage *spage) +{ + SchedulePagePrivate *priv; + + priv = spage->priv; + + gtk_signal_connect (GTK_OBJECT (priv->model), "model_row_changed", + GTK_SIGNAL_FUNC (model_row_changed_cb), spage); + gtk_signal_connect (GTK_OBJECT (priv->model), "model_rows_inserted", + GTK_SIGNAL_FUNC (row_count_changed_cb), spage); + gtk_signal_connect (GTK_OBJECT (priv->model), "model_rows_deleted", + GTK_SIGNAL_FUNC (row_count_changed_cb), spage); +} + + + +/** + * schedule_page_construct: + * @spage: An schedule page. + * + * Constructs an schedule page by loading its Glade data. + * + * Return value: The same object as @spage, or NULL if the widgets could not + * be created. + **/ +SchedulePage * +schedule_page_construct (SchedulePage *spage, EMeetingModel *emm) +{ + SchedulePagePrivate *priv; + + priv = spage->priv; + + priv->xml = glade_xml_new (EVOLUTION_GLADEDIR + "/schedule-page.glade", NULL); + if (!priv->xml) { + g_message ("schedule_page_construct(): " + "Could not load the Glade XML file!"); + return NULL; + } + + if (!get_widgets (spage)) { + g_message ("schedule_page_construct(): " + "Could not find all widgets in the XML file!"); + return NULL; + } + + /* Model */ + gtk_object_ref (GTK_OBJECT (emm)); + priv->model = emm; + + /* Selector */ + priv->sel = E_MEETING_TIME_SELECTOR (e_meeting_time_selector_new (emm)); + gtk_widget_show (GTK_WIDGET (priv->sel)); + gtk_box_pack_start (GTK_BOX (priv->main), GTK_WIDGET (priv->sel), TRUE, TRUE, 2); + + /* Init the widget signals */ + init_widgets (spage); + + return spage; +} + +/** + * schedule_page_new: + * + * Creates a new schedule page. + * + * Return value: A newly-created schedule page, or NULL if the page could + * not be created. + **/ +SchedulePage * +schedule_page_new (EMeetingModel *emm) +{ + SchedulePage *spage; + + spage = gtk_type_new (TYPE_SCHEDULE_PAGE); + if (!schedule_page_construct (spage, emm)) { + gtk_object_unref (GTK_OBJECT (spage)); + return NULL; + } + + return spage; +} + +static void +model_row_changed_cb (ETableModel *etm, int row, gpointer data) +{ + SchedulePage *spage = SCHEDULE_PAGE (data); + SchedulePagePrivate *priv; + + priv = spage->priv; + + if (!priv->updating) + comp_editor_page_notify_changed (COMP_EDITOR_PAGE (spage)); +} + +static void +row_count_changed_cb (ETableModel *etm, int row, int count, gpointer data) +{ + SchedulePage *spage = SCHEDULE_PAGE (data); + SchedulePagePrivate *priv; + + priv = spage->priv; + + if (!priv->updating) + comp_editor_page_notify_changed (COMP_EDITOR_PAGE (spage)); +} diff --git a/calendar/gui/dialogs/schedule-page.glade b/calendar/gui/dialogs/schedule-page.glade new file mode 100644 index 0000000000..95a2147659 --- /dev/null +++ b/calendar/gui/dialogs/schedule-page.glade @@ -0,0 +1,36 @@ + + + + + task-details-page + task-details-page + + src + pixmaps + C + True + True + + + + GtkWindow + schedule-toplevel + False + window1 + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + False + True + False + + + GtkVBox + schedule-page + 4 + False + 4 + + + + diff --git a/calendar/gui/dialogs/schedule-page.h b/calendar/gui/dialogs/schedule-page.h new file mode 100644 index 0000000000..b9a136e86c --- /dev/null +++ b/calendar/gui/dialogs/schedule-page.h @@ -0,0 +1,60 @@ +/* Evolution calendar - Scheduling page + * + * Copyright (C) 2001 Ximian, Inc. + * + * Authors: JP Rosevear + * + * 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 of the License, 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. + * + * 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. + */ + +#ifndef SCHEDULE_PAGE_H +#define SCHEDULE_PAGE_H + +#include "../e-meeting-model.h" +#include "comp-editor-page.h" + +BEGIN_GNOME_DECLS + + + +#define TYPE_SCHEDULE_PAGE (schedule_page_get_type ()) +#define SCHEDULE_PAGE(obj) (GTK_CHECK_CAST ((obj), TYPE_SCHEDULE_PAGE, SchedulePage)) +#define SCHEDULE_PAGE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_SCHEDULE_PAGE, SchedulePageClass)) +#define IS_SCHEDULE_PAGE(obj) (GTK_CHECK_TYPE ((obj), TYPE_SCHEDULE_PAGE)) +#define IS_SCHEDULE_PAGE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), TYPE_SCHEDULE_PAGE)) + +typedef struct _SchedulePagePrivate SchedulePagePrivate; + +typedef struct { + CompEditorPage page; + + /* Private data */ + SchedulePagePrivate *priv; +} SchedulePage; + +typedef struct { + CompEditorPageClass parent_class; +} SchedulePageClass; + + +GtkType schedule_page_get_type (void); +SchedulePage *schedule_page_construct (SchedulePage *mpage, EMeetingModel *emm); +SchedulePage *schedule_page_new (EMeetingModel *emm); + + + +END_GNOME_DECLS + +#endif diff --git a/calendar/gui/dialogs/task-editor.c b/calendar/gui/dialogs/task-editor.c index 22b89e5ce5..c7879a1986 100644 --- a/calendar/gui/dialogs/task-editor.c +++ b/calendar/gui/dialogs/task-editor.c @@ -41,6 +41,8 @@ struct _TaskEditorPrivate { TaskDetailsPage *task_details_page; MeetingPage *meet_page; + EMeetingModel *model; + gboolean meeting_shown; }; @@ -155,7 +157,9 @@ task_editor_init (TaskEditor *te) COMP_EDITOR_PAGE (priv->task_details_page), _("Details")); - priv->meet_page = meeting_page_new (); + priv->model = E_MEETING_MODEL (e_meeting_model_new ()); + + priv->meet_page = meeting_page_new (priv->model); comp_editor_append_page (COMP_EDITOR (te), COMP_EDITOR_PAGE (priv->meet_page), _("Assignment")); @@ -207,6 +211,8 @@ task_editor_destroy (GtkObject *object) gtk_object_unref (GTK_OBJECT (priv->task_details_page)); gtk_object_unref (GTK_OBJECT (priv->meet_page)); + gtk_object_unref (GTK_OBJECT (priv->model)); + if (GTK_OBJECT_CLASS (parent_class)->destroy) (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); } -- cgit v1.2.3