aboutsummaryrefslogtreecommitdiffstats
path: root/calendar/gui
diff options
context:
space:
mode:
Diffstat (limited to 'calendar/gui')
-rw-r--r--calendar/gui/dialogs/comp-editor.c30
-rw-r--r--calendar/gui/e-itip-control.c1496
-rw-r--r--calendar/gui/e-itip-control.h87
-rw-r--r--calendar/gui/itip-bonobo-control.c267
-rw-r--r--calendar/gui/itip-bonobo-control.h30
-rw-r--r--calendar/gui/itip-control-factory.c267
-rw-r--r--calendar/gui/itip-control-factory.h30
-rw-r--r--calendar/gui/main.c4
8 files changed, 1442 insertions, 769 deletions
diff --git a/calendar/gui/dialogs/comp-editor.c b/calendar/gui/dialogs/comp-editor.c
index 252d858e7f..d67ebc7919 100644
--- a/calendar/gui/dialogs/comp-editor.c
+++ b/calendar/gui/dialogs/comp-editor.c
@@ -97,9 +97,6 @@ static void print_preview_cmd (GtkWidget *widget, gpointer data);
static void print_setup_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 EPixmap pixmaps [] =
@@ -177,9 +174,6 @@ setup_widgets (CompEditor *editor)
CompEditorPrivate *priv;
BonoboUIContainer *container;
GtkWidget *vbox;
- GtkWidget *bbox;
- GtkWidget *pixmap;
- GtkWidget *button;
priv = editor->priv;
@@ -902,30 +896,6 @@ close_cmd (GtkWidget *widget, gpointer data)
}
static void
-save_clicked_cb (GtkWidget *widget, gpointer data)
-{
- CompEditor *editor = COMP_EDITOR (data);
-
- save_comp (editor);
- close_dialog (editor);
-}
-
-static void
-close_clicked_cb (GtkWidget *widget, gpointer data)
-{
- CompEditor *editor = COMP_EDITOR (data);
-
- if (prompt_to_save_changes (editor))
- 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);
diff --git a/calendar/gui/e-itip-control.c b/calendar/gui/e-itip-control.c
index cbd84c52e9..8363f11d2e 100644
--- a/calendar/gui/e-itip-control.c
+++ b/calendar/gui/e-itip-control.c
@@ -1,934 +1,994 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Evolution calendar - Control for displaying iTIP mail messages
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* e-itip-control.c
*
- * Copyright (C) 2000 Helix Code, Inc.
- * Copyright (C) 2000 Ximian, Inc.
+ * Copyright (C) 2001 Ximian, Inc.
*
- * Author: Jesse Pavel <jpavel@ximian.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * 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.
+ * 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.
*
- * 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.
+ * Author: JP Rosevear
*/
+#ifdef HAVE_CONFIG_H
#include <config.h>
-#include <time.h>
+#endif
+
#include <glib.h>
-#include <gtk/gtkobject.h>
-#include <gtk/gtkwidget.h>
+#include <gtk/gtkmisc.h>
#include <libgnome/gnome-defs.h>
#include <libgnome/gnome-i18n.h>
+#include <libgnome/gnome-util.h>
+#include <libgnomeui/gnome-stock.h>
#include <libgnomeui/gnome-dialog.h>
#include <libgnomeui/gnome-dialog-util.h>
-#include <bonobo/bonobo-generic-factory.h>
-#include <bonobo/bonobo-persist-stream.h>
-#include <bonobo/bonobo-stream-client.h>
-#include <bonobo/bonobo-context.h>
-
-#include <glade/glade.h>
#include <ical.h>
-#include <Evolution-Composer.h>
-
-#include "e-itip-control.h"
#include <cal-util/cal-component.h>
#include <cal-client/cal-client.h>
#include <e-util/e-time-utils.h>
+#include <e-util/e-dialog-widgets.h>
#include "calendar-config.h"
#include "itip-utils.h"
+#include "e-itip-control.h"
-#define MAIL_COMPOSER_OAF_IID "OAFIID:GNOME_Evolution_Mail_Composer"
+struct _EItipControlPrivate {
+ GtkWidget *summary;
+ GtkWidget *datetime;
+ GtkWidget *message;
+ GtkWidget *count;
+ GtkWidget *options;
+ GtkWidget *ok;
+ GtkWidget *next;
+ GtkWidget *prev;
+
+ CalClient *event_client;
+ CalClient *task_client;
-#define DEFAULT_WIDTH 400
-#define DEFAULT_HEIGHT 300
+ char *vcalendar;
+ CalComponent *comp;
+ icalcomponent *main_comp;
+ icalcomponent *ical_comp;
+ icalcompiter iter;
+ icalproperty_method method;
-extern gchar *evolution_dir;
+ const int *map;
+ int current;
+ int total;
-typedef struct _EItipControlPrivate EItipControlPrivate;
+ gchar *from_address;
+ gchar *my_address;
+};
-struct _EItipControlPrivate {
- GladeXML *xml, *xml2;
- GtkWidget *main_frame;
- GtkWidget *organizer_entry, *dtstart_label, *dtend_label;
- GtkWidget *summary_entry, *description_box, *message_text;
- GtkWidget *button_box;
- GtkWidget *address_entry;
- GtkWidget *add_button;
- GtkWidget *loading_window;
- GtkWidget *loading_progress;
-
- icalcomponent *main_comp, *comp;
- CalComponent *cal_comp;
- char *vcalendar;
- gchar *from_address, *my_address, *organizer;
- icalparameter_partstat new_partstat;
+/* Option menu maps */
+enum {
+ UPDATE_CALENDAR
};
-enum E_ITIP_BONOBO_ARGS {
- FROM_ADDRESS_ARG_ID,
- MY_ADDRESS_ARG_ID
+enum {
+ ACCEPT_TO_CALENDAR_RSVP,
+ ACCEPT_TO_CALENDAR,
+ TENTATIVE_TO_CALENDAR_RSVP,
+ TENTATIVE_TO_CALENDAR,
+ DECLINE_TO_CALENDAR_RSVP,
+ DECLINE_TO_CALENDAR
};
+enum {
+ SEND_FREEBUSY
+};
-/********
- * find_attendee() searches through the attendee properties of `comp'
- * and returns the one the value of which is the same as `address' if such
- * a property exists. Otherwise, it will return NULL.
- ********/
-static icalproperty *
-find_attendee (icalcomponent *comp, char *address)
-{
- icalproperty *prop;
- const char *attendee, *text;
- icalvalue *value;
-
- for (prop = icalcomponent_get_first_property (comp, ICAL_ATTENDEE_PROPERTY);
- prop != NULL;
- prop = icalcomponent_get_next_property (comp, ICAL_ATTENDEE_PROPERTY))
- {
- value = icalproperty_get_value (prop);
- if (!value)
- continue;
+enum {
+ CANCEL_CALENDAR
+};
- attendee = icalvalue_get_string (value);
+static const int publish_map[] = {
+ UPDATE_CALENDAR,
+ -1
+};
- /* Here I strip off the "MAILTO:" if it is present. */
- text = strchr (attendee, ':');
- if (text != NULL)
- text++;
- else
- text = attendee;
+static const char *publish_text_map[] = {
+ "Update Calendar",
+ NULL
+};
- if (strcmp (text, address) == 0) {
- /* We have found the correct property. */
- break;
- }
- }
-
- return prop;
-}
+static const int request_map[] = {
+ ACCEPT_TO_CALENDAR_RSVP,
+ ACCEPT_TO_CALENDAR,
+ TENTATIVE_TO_CALENDAR_RSVP,
+ TENTATIVE_TO_CALENDAR,
+ DECLINE_TO_CALENDAR_RSVP,
+ DECLINE_TO_CALENDAR,
+ -1
+};
-static void
-itip_control_destroy_cb (GtkObject *object,
- gpointer data)
-{
- EItipControlPrivate *priv = data;
+static const char *request_text_map[] = {
+ "Accept and RSVP",
+ "Accept and do not RSVP",
+ "Tentatively accept and RSVP",
+ "Tentatively accept and do not RSVP",
+ "Decline and RSVP",
+ "Decline and do not RSVP",
+ NULL
+};
- gtk_object_unref (GTK_OBJECT (priv->xml));
- gtk_object_unref (GTK_OBJECT (priv->xml2));
+static const int request_fb_map[] = {
+ SEND_FREEBUSY,
+ -1
+};
- if (priv->main_comp != NULL) {
- if (priv->comp != NULL)
- icalcomponent_remove_component (priv->main_comp, priv->comp);
-
- icalcomponent_free (priv->main_comp);
- }
+static const char *request_fb_text_map[] = {
+ "Send Free/Busy Information",
+ NULL
+};
+static const int reply_map[] = {
+ UPDATE_CALENDAR,
+ -1
+};
- if (priv->cal_comp != NULL) {
- gtk_object_unref (GTK_OBJECT (priv->cal_comp));
- }
+static const char *reply_text_map[] = {
+ "Update Calendar",
+ NULL
+};
- if (priv->from_address != NULL)
- g_free (priv->from_address);
-
- if (priv->organizer != NULL)
- g_free (priv->organizer);
+static const int cancel_map[] = {
+ CANCEL_CALENDAR,
+ -1
+};
- if (priv->vcalendar != NULL)
- g_free (priv->vcalendar);
+static const char *cancel_text_map[] = {
+ "Cancel",
+ NULL
+};
- g_free (priv);
-}
-
+static void class_init (EItipControlClass *klass);
+static void init (EItipControl *itip);
+static void destroy (GtkObject *obj);
-static void
-cal_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer data)
-{
- EItipControlPrivate *priv = data;
+static void prev_clicked_cb (GtkWidget *widget, gpointer data);
+static void next_clicked_cb (GtkWidget *widget, gpointer data);
+static void ok_clicked_cb (GtkWidget *widget, gpointer data);
- gtk_widget_hide (priv->loading_progress);
+static GtkVBoxClass *parent_class = NULL;
- if (status == CAL_CLIENT_OPEN_SUCCESS) {
- if (cal_client_update_object (client, priv->cal_comp) == FALSE) {
- GtkWidget *dialog;
-
- dialog = gnome_warning_dialog(_("I couldn't update your calendar file!\n"));
- gnome_dialog_run (GNOME_DIALOG(dialog));
- } else {
- /* We have success. */
- GtkWidget *dialog;
-
- dialog = gnome_ok_dialog(_("Component successfully updated."));
- gnome_dialog_run (GNOME_DIALOG(dialog));
- }
- } else {
- GtkWidget *dialog;
- dialog = gnome_ok_dialog(_("There was an error loading the calendar file."));
- gnome_dialog_run (GNOME_DIALOG(dialog));
+GtkType
+e_itip_control_get_type (void)
+{
+ static GtkType type = 0;
+
+ if (type == 0) {
+ static const GtkTypeInfo info =
+ {
+ "EItipControl",
+ sizeof (EItipControl),
+ sizeof (EItipControlClass),
+ (GtkClassInitFunc) class_init,
+ (GtkObjectInitFunc) init,
+ /* reserved_1 */ NULL,
+ /* reserved_2 */ NULL,
+ (GtkClassInitFunc) NULL,
+ };
+
+ type = gtk_type_unique (gtk_vbox_get_type (), &info);
}
- gtk_object_unref (GTK_OBJECT (client));
- return;
+ return type;
}
static void
-update_calendar (EItipControlPrivate *priv)
+class_init (EItipControlClass *klass)
{
- gchar cal_uri[255];
- CalClient *client;
+ GtkObjectClass *object_class;
- snprintf (cal_uri, 250, "%s/local/Calendar/calendar.ics", evolution_dir);
-
- client = cal_client_new ();
-
- gtk_signal_connect (GTK_OBJECT (client), "cal_opened",
- GTK_SIGNAL_FUNC (cal_opened_cb), priv);
-
- if (cal_client_open_calendar (client, cal_uri, FALSE) == FALSE) {
- GtkWidget *dialog;
-
- dialog = gnome_warning_dialog(_("I couldn't open your calendar file!\n"));
- gnome_dialog_run (GNOME_DIALOG(dialog));
- gtk_object_unref (GTK_OBJECT (client));
-
- return;
- }
+ object_class = GTK_OBJECT_CLASS (klass);
- gtk_progress_bar_update (GTK_PROGRESS_BAR (priv->loading_progress), 0.5);
- gtk_widget_show (priv->loading_progress);
+ parent_class = gtk_type_class (gtk_vbox_get_type ());
- return;
+ object_class->destroy = destroy;
}
+
+/* Calendar Server routines */
static void
-add_button_clicked_cb (GtkWidget *widget, gpointer data)
+start_calendar_server_cb (CalClient *cal_client,
+ CalClientOpenStatus status,
+ gpointer data)
{
- EItipControlPrivate *priv = data;
+ gboolean *success = data;
- update_calendar (priv);
+ if (status == CAL_CLIENT_OPEN_SUCCESS)
+ *success = TRUE;
+ else
+ *success = FALSE;
- return;
+ gtk_main_quit (); /* end the sub event loop */
}
-static void
-change_my_status (icalparameter_partstat status, EItipControlPrivate *priv)
+static CalClient *
+start_calendar_server (gchar *uri)
{
- icalproperty *prop;
+ CalClient *client;
+ gchar *filename;
+ gboolean success;
+
+ client = cal_client_new ();
- prop = find_attendee (priv->comp, priv->my_address);
- if (prop) {
- icalparameter *param;
+ /* FIX ME */
+ filename = g_concat_dir_and_file (g_get_home_dir (), uri);
- icalproperty_remove_parameter (prop, ICAL_PARTSTAT_PARAMETER);
- param = icalparameter_new_partstat (status);
- icalproperty_add_parameter (prop, param);
- }
-}
+ gtk_signal_connect (GTK_OBJECT (client), "cal_opened",
+ start_calendar_server_cb, &success);
-static void
-accept_button_clicked_cb (GtkWidget *widget, gpointer data)
-{
- EItipControlPrivate *priv = data;
+ if (!cal_client_open_calendar (client, filename, FALSE))
+ return NULL;
- change_my_status (ICAL_PARTSTAT_ACCEPTED, priv);
- itip_send_comp (CAL_COMPONENT_METHOD_REPLY, priv->cal_comp);
- update_calendar (priv);
-
- return;
+ /* run a sub event loop to turn cal-client's async load
+ notification into a synchronous call */
+ gtk_main ();
+
+ if (success)
+ return client;
+
+ return NULL;
}
static void
-tentative_button_clicked_cb (GtkWidget *widget, gpointer data)
+init (EItipControl *itip)
{
- EItipControlPrivate *priv = data;
-
- change_my_status (ICAL_PARTSTAT_TENTATIVE, priv);
- itip_send_comp (CAL_COMPONENT_METHOD_REPLY, priv->cal_comp);
- update_calendar (priv);
+ EItipControlPrivate *priv;
+ GtkWidget *hbox, *table, *lbl;
- return;
+ priv = g_new0 (EItipControlPrivate, 1);
+
+ itip->priv = priv;
+
+ /* Header */
+ priv->count = gtk_label_new ("0 of 0");
+ gtk_widget_show (priv->count);
+ priv->prev = gnome_stock_button (GNOME_STOCK_BUTTON_PREV);
+ gtk_widget_show (priv->prev);
+ priv->next = gnome_stock_button (GNOME_STOCK_BUTTON_NEXT);
+ gtk_widget_show (priv->next);
+
+ hbox = gtk_hbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), priv->prev, FALSE, FALSE, 4);
+ gtk_box_pack_start (GTK_BOX (hbox), priv->count, TRUE, TRUE, 4);
+ gtk_box_pack_start (GTK_BOX (hbox), priv->next, FALSE, FALSE, 4);
+ gtk_widget_show (hbox);
+
+ gtk_box_pack_start (GTK_BOX (itip), hbox, FALSE, FALSE, 4);
+
+ gtk_signal_connect (GTK_OBJECT (priv->prev), "clicked",
+ GTK_SIGNAL_FUNC (prev_clicked_cb), itip);
+ gtk_signal_connect (GTK_OBJECT (priv->next), "clicked",
+ GTK_SIGNAL_FUNC (next_clicked_cb), itip);
+
+ /* Information */
+ table = gtk_table_new (1, 3, FALSE);
+ gtk_widget_show (table);
+
+ lbl = gtk_label_new (_("Summary:"));
+ gtk_misc_set_alignment (GTK_MISC (lbl), 0.0, 0.0);
+ gtk_widget_show (lbl);
+ gtk_table_attach (GTK_TABLE (table), lbl, 0, 1, 0, 1,
+ GTK_EXPAND & GTK_FILL, GTK_SHRINK, 4, 0);
+ priv->summary = gtk_label_new ("");
+ gtk_misc_set_alignment (GTK_MISC (priv->summary), 0.0, 0.5);
+ gtk_widget_show (priv->summary);
+ gtk_table_attach (GTK_TABLE (table), priv->summary, 1, 2, 0, 1,
+ GTK_EXPAND & GTK_FILL, GTK_EXPAND, 4, 0);
+
+ lbl = gtk_label_new (_("Date/Time:"));
+ gtk_misc_set_alignment (GTK_MISC (lbl), 0.0, 0.5);
+ gtk_widget_show (lbl);
+ gtk_table_attach (GTK_TABLE (table), lbl, 0, 1, 1, 2,
+ GTK_EXPAND, GTK_SHRINK, 4, 0);
+ priv->datetime = gtk_label_new ("");
+ gtk_misc_set_alignment (GTK_MISC (priv->datetime), 0.0, 0.5);
+ gtk_widget_show (priv->datetime);
+ gtk_table_attach (GTK_TABLE (table), priv->datetime, 1, 2, 1, 2,
+ GTK_EXPAND & GTK_FILL, GTK_EXPAND, 4, 0);
+
+ priv->message = gtk_label_new ("");
+ gtk_label_set_line_wrap (GTK_LABEL (priv->message), TRUE);
+ gtk_widget_show (priv->message);
+ gtk_table_attach (GTK_TABLE (table), priv->message, 0, 2, 2, 3,
+ GTK_EXPAND & GTK_FILL, GTK_EXPAND & GTK_FILL, 4, 0);
+
+ gtk_box_pack_start (GTK_BOX (itip), table, FALSE, FALSE, 4);
+
+ /* Actions */
+ priv->options = gtk_option_menu_new ();
+ gtk_widget_show (priv->options);
+ priv->ok = gnome_stock_button (GNOME_STOCK_BUTTON_OK);
+ gtk_widget_show (priv->ok);
+
+ hbox = hbox = gtk_hbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), priv->options, TRUE, TRUE, 4);
+ gtk_box_pack_start (GTK_BOX (hbox), priv->ok, FALSE, FALSE, 4);
+ gtk_widget_show (hbox);
+
+ gtk_signal_connect (GTK_OBJECT (priv->ok), "clicked",
+ GTK_SIGNAL_FUNC (ok_clicked_cb), itip);
+
+ gtk_box_pack_start (GTK_BOX (itip), hbox, FALSE, FALSE, 4);
+
+ /* Get the cal clients */
+ priv->event_client = start_calendar_server ("evolution/local/Calendar/calendar.ics");
+ if (priv->event_client == NULL)
+ g_warning ("Unable to start calendar client");
+ priv->task_client = start_calendar_server ("evolution/local/Tasks/tasks.ics");
+ g_warning ("Unable to start calendar client");
}
static void
-decline_button_clicked_cb (GtkWidget *widget, gpointer data)
+destroy (GtkObject *obj)
{
- EItipControlPrivate *priv = data;
+ EItipControl *itip = E_ITIP_CONTROL (obj);
+ EItipControlPrivate *priv;
- change_my_status (ICAL_PARTSTAT_DECLINED, priv);
- itip_send_comp (CAL_COMPONENT_METHOD_REPLY, priv->cal_comp);
-
- return;
+ priv = itip->priv;
+
+ g_free (priv);
}
+GtkWidget *
+e_itip_control_new (void)
+{
+ return gtk_type_new (E_TYPE_ITIP_CONTROL);
+}
-/********
- * load_calendar_store() opens and loads the calendar referred to by cal_uri
- * and sets cal_client as a client for that store. If cal_uri is NULL,
- * we load the default calendar URI. If all goes well, it returns TRUE;
- * otherwise, it returns FALSE.
- ********/
-static gboolean
-load_calendar_store (char *cal_uri, CalClient **cal_client)
+static icalproperty *
+find_attendee (icalcomponent *ical_comp, char *address)
{
- char uri_buf[255];
- char *uri;
+ icalproperty *prop;
+ const char *attendee, *text;
+ icalvalue *value;
- if (cal_uri == NULL) {
- snprintf (uri_buf, 250, "%s/local/Calendar/calendar.ics", evolution_dir);
- uri = uri_buf;
- }
- else {
- uri = cal_uri;
- }
+ g_return_val_if_fail (address != NULL, NULL);
- *cal_client = cal_client_new ();
- if (cal_client_open_calendar (*cal_client, uri, FALSE) == FALSE) {
- return FALSE;
- }
+ for (prop = icalcomponent_get_first_property (ical_comp, ICAL_ATTENDEE_PROPERTY);
+ prop != NULL;
+ prop = icalcomponent_get_next_property (ical_comp, ICAL_ATTENDEE_PROPERTY))
+ {
+ value = icalproperty_get_value (prop);
+ if (!value)
+ continue;
- /* FIXME!!!!!! This is fucking ugly. */
+ attendee = icalvalue_get_string (value);
- while (!cal_client_get_load_state (*cal_client) != CAL_CLIENT_LOAD_LOADED) {
- gtk_main_iteration_do (FALSE); /* Do a non-blocking iteration. */
- usleep (200000L); /* Pause for 1/5th of a second before checking again.*/
- }
+ /* Here I strip off the "MAILTO:" if it is present. */
+ text = strchr (attendee, ':');
+ if (text != NULL)
+ text++;
+ else
+ text = attendee;
- return TRUE;
+ if (!strstr (text, address))
+ break;
+ }
+
+ return prop;
}
-
static void
-update_reply_cb (GtkWidget *widget, gpointer data)
+set_label (EItipControl *itip)
{
- EItipControlPrivate *priv = data;
- CalClient *cal_client;
- CalComponent *cal_comp;
- icalcomponent *comp;
- icalproperty *prop;
- icalparameter *param;
- const char *uid;
-
- if (load_calendar_store (NULL, &cal_client) == FALSE) {
- GtkWidget *dialog;
-
- dialog = gnome_warning_dialog(_("I couldn't load your calendar file!\n"));
- gnome_dialog_run (GNOME_DIALOG(dialog));
- gtk_object_unref (GTK_OBJECT (cal_client));
+ EItipControlPrivate *priv;
+ gchar *text;
- return;
- }
+ priv = itip->priv;
+ text = g_strdup_printf ("%d of %d", priv->current, priv->total);
+ gtk_label_set_text (GTK_LABEL (priv->count), text);
- cal_component_get_uid (priv->cal_comp, &uid);
- if (cal_client_get_object (cal_client, uid, &cal_comp) != CAL_CLIENT_GET_SUCCESS) {
- GtkWidget *dialog;
-
- dialog = gnome_warning_dialog(_("I couldn't read your calendar file!\n"));
- gnome_dialog_run (GNOME_DIALOG(dialog));
- gtk_object_unref (GTK_OBJECT (cal_client));
-
- return;
- }
+}
- comp = cal_component_get_icalcomponent (cal_comp);
+static void
+set_button_status (EItipControl *itip)
+{
+ EItipControlPrivate *priv;
- prop = find_attendee (comp, priv->from_address);
- if (!prop) {
- GtkWidget *dialog;
+ priv = itip->priv;
- dialog = gnome_warning_dialog(_("This is a reply from someone who was uninvited!"));
- gnome_dialog_run (GNOME_DIALOG(dialog));
- gtk_object_unref (GTK_OBJECT (cal_client));
- gtk_object_unref (GTK_OBJECT (cal_comp));
-
- return;
- }
-
- icalproperty_remove_parameter (prop, ICAL_PARTSTAT_PARAMETER);
- param = icalparameter_new_partstat (priv->new_partstat);
- icalproperty_add_parameter (prop, param);
+ if (priv->current == priv->total)
+ gtk_widget_set_sensitive (priv->next, FALSE);
+ else
+ gtk_widget_set_sensitive (priv->next, TRUE);
- /* Now we need to update the object in the calendar store. */
- if (!cal_client_update_object (cal_client, cal_comp)) {
- GtkWidget *dialog;
+ if (priv->current == 1)
+ gtk_widget_set_sensitive (priv->prev, FALSE);
+ else
+ gtk_widget_set_sensitive (priv->prev, TRUE);
+}
- dialog = gnome_warning_dialog(_("I couldn't update your calendar store."));
- gnome_dialog_run (GNOME_DIALOG(dialog));
- gtk_object_unref (GTK_OBJECT (cal_client));
- gtk_object_unref (GTK_OBJECT (cal_comp));
+static GtkWidget *
+create_menu (const char **map)
+{
+ GtkWidget *menu, *item;
+ int i;
- return;
- }
- else {
- /* We have success. */
- GtkWidget *dialog;
+ menu = gtk_menu_new ();
- dialog = gnome_ok_dialog(_("Component successfully updated."));
- gnome_dialog_run (GNOME_DIALOG(dialog));
+ for (i = 0; map[i] != NULL; i++) {
+ item = gtk_menu_item_new_with_label (map[i]);
+ gtk_widget_show (item);
+ gtk_menu_append (GTK_MENU (menu), item);
}
-
+ gtk_widget_show (menu);
- gtk_object_unref (GTK_OBJECT (cal_client));
- gtk_object_unref (GTK_OBJECT (cal_comp));
+ return menu;
}
static void
-cancel_meeting_cb (GtkWidget *widget, gpointer data)
+set_options (EItipControl *itip)
{
- EItipControlPrivate *priv = data;
- CalClient *cal_client;
- const char *uid;
-
- if (load_calendar_store (NULL, &cal_client) == FALSE) {
- GtkWidget *dialog;
-
- dialog = gnome_warning_dialog(_("I couldn't load your calendar file!\n"));
- gnome_dialog_run (GNOME_DIALOG(dialog));
- gtk_object_unref (GTK_OBJECT (cal_client));
+ EItipControlPrivate *priv;
+ gboolean sens = TRUE;
- return;
+ priv = itip->priv;
+
+ switch (priv->method) {
+ case ICAL_METHOD_PUBLISH:
+ priv->map = publish_map;
+ gtk_option_menu_set_menu (GTK_OPTION_MENU (priv->options),
+ create_menu (publish_text_map));
+ break;
+ case ICAL_METHOD_REQUEST:
+ priv->map = request_map;
+ gtk_option_menu_set_menu (GTK_OPTION_MENU (priv->options),
+ create_menu (request_text_map));
+ break;
+ case ICAL_METHOD_REPLY:
+ priv->map = reply_map;
+ gtk_option_menu_set_menu (GTK_OPTION_MENU (priv->options),
+ create_menu (reply_text_map));
+ break;
+ case ICAL_METHOD_CANCEL:
+ priv->map = cancel_map;
+ gtk_option_menu_set_menu (GTK_OPTION_MENU (priv->options),
+ create_menu (cancel_text_map));
+ break;
+ default:
+ priv->map = NULL;
+ gtk_option_menu_remove_menu (GTK_OPTION_MENU (priv->options));
+ sens = FALSE;
}
- cal_component_get_uid (priv->cal_comp, &uid);
- if (cal_client_remove_object (cal_client, uid) == FALSE) {
- GtkWidget *dialog;
+ gtk_widget_set_sensitive (priv->options, sens);
+ gtk_widget_set_sensitive (priv->ok, sens);
+}
- dialog = gnome_warning_dialog(_("I couldn't delete the calendar component!\n"));
- gnome_dialog_run (GNOME_DIALOG(dialog));
- gtk_object_unref (GTK_OBJECT (cal_client));
+
+static void
+set_options_freebusy (EItipControl *itip)
+{
+ EItipControlPrivate *priv;
+ gboolean sens = TRUE;
- return;
+ priv = itip->priv;
+
+ switch (priv->method) {
+ case ICAL_METHOD_REQUEST:
+ priv->map = request_fb_map;
+ gtk_option_menu_set_menu (GTK_OPTION_MENU (priv->options),
+ create_menu (request_fb_text_map));
+ break;
+ default:
+ priv->map = NULL;
+ gtk_option_menu_remove_menu (GTK_OPTION_MENU (priv->options));
+ sens = FALSE;
}
- else {
- /* We have success! */
- GtkWidget *dialog;
- dialog = gnome_ok_dialog(_("Component successfully deleted."));
- gnome_dialog_run (GNOME_DIALOG(dialog));
- }
-
+ gtk_widget_set_sensitive (priv->options, sens);
+ gtk_widget_set_sensitive (priv->ok, sens);
}
+static void
+write_label_piece (time_t t, char *buffer, int size, char *stext, char *etext)
+{
+ struct tm *tmp_tm;
+ int len;
+
+ tmp_tm = localtime (&t);
+ if (stext != NULL)
+ strcat (buffer, stext);
+ len = strlen (buffer);
+ e_time_format_date_and_time (tmp_tm,
+ calendar_config_get_24_hour_format (),
+ FALSE, FALSE,
+ &buffer[len], size - len);
+ if (etext != NULL)
+ strcat (buffer, etext);
+}
-/*
- * Bonobo::PersistStream
- *
- * These two functions implement the Bonobo::PersistStream load and
- * save methods which allow data to be loaded into and out of the
- * BonoboObject.
- */
-
-static char *
-stream_read (Bonobo_Stream stream)
+static void
+set_date_label (GtkWidget *lbl, CalComponent *comp)
{
- Bonobo_Stream_iobuf *buffer;
- CORBA_Environment ev;
- gchar *data = NULL;
- gint length = 0;
-
- CORBA_exception_init (&ev);
- do {
-#define READ_CHUNK_SIZE 65536
- Bonobo_Stream_read (stream, READ_CHUNK_SIZE,
- &buffer, &ev);
+ CalComponentDateTime datetime;
+ time_t start = 0, end = 0, complete = 0, due = 0;
+ static char buffer[1024];
+
+ cal_component_get_dtstart (comp, &datetime);
+ if (datetime.value)
+ start = icaltime_as_timet (*datetime.value);
+ cal_component_get_dtend (comp, &datetime);
+ if (datetime.value)
+ end = icaltime_as_timet (*datetime.value);
+ cal_component_get_due (comp, &datetime);
+ if (datetime.value)
+ due = icaltime_as_timet (*datetime.value);
+ cal_component_get_completed (comp, &datetime.value);
+ if (datetime.value)
+ complete = icaltime_as_timet (*datetime.value);
+
+ buffer[0] = '\0';
+
+ if (start > 0)
+ write_label_piece (start, buffer, 1024, NULL, NULL);
+
+ if (end > 0 && start > 0)
+ write_label_piece (end, buffer, 1024, _(" to "), NULL);
+
+ if (complete > 0) {
+ if (start > 0)
+ write_label_piece (complete, buffer, 1024, _(" (Completed "), ")");
+ else
+ write_label_piece (complete, buffer, 1024, _("Completed "), NULL);
+ }
+
+ if (due > 0 && complete == 0) {
+ if (start > 0)
+ write_label_piece (due, buffer, 1024, _(" (Due "), ")");
+ else
+ write_label_piece (due, buffer, 1024, _("Due "), NULL);
+ }
- if (ev._major != CORBA_NO_EXCEPTION) {
- CORBA_exception_free (&ev);
- return NULL;
- }
+ gtk_label_set_text (GTK_LABEL (lbl), buffer);
+}
- if (buffer->_length <= 0)
- break;
+static void
+set_message (EItipControl *itip, gchar *message, gboolean err)
+{
+ EItipControlPrivate *priv;
+ GtkStyle *style = NULL;
+
+ priv = itip->priv;
- data = g_realloc (data,
- length + buffer->_length);
+ if (err) {
+ GdkColor color = {0, 65535, 0, 0};
+
+ style = gtk_style_copy (gtk_widget_get_style (priv->message));
+ style->fg[0] = color;
+ gtk_widget_set_style (priv->message, style);
+ } else {
+ gtk_widget_restore_default_style (priv->message);
+ }
- memcpy (data + length,
- buffer->_buffer, buffer->_length);
+ if (message != NULL)
+ gtk_label_set_text (GTK_LABEL (priv->message), message);
+ else
+ gtk_label_set_text (GTK_LABEL (priv->message), "");
- length += buffer->_length;
+ if (err) {
+ gtk_style_unref (style);
+ }
+}
- CORBA_free (buffer);
-#undef READ_CHUNK_SIZE
- } while (1);
+static void
+show_current_event (EItipControl *itip)
+{
+ EItipControlPrivate *priv;
+ CalComponentText text;
+
+ priv = itip->priv;
- CORBA_free (buffer);
- CORBA_exception_free (&ev);
+ set_options (itip);
+
+ cal_component_get_summary (priv->comp, &text);
+ if (text.value)
+ gtk_label_set_text (GTK_LABEL (priv->summary), text.value);
+ else
+ gtk_label_set_text (GTK_LABEL (priv->summary), "");
- if (data == NULL)
- data = g_strdup("");
+ set_date_label (priv->datetime, priv->comp);
- return data;
-} /* stream_read */
+ switch (priv->method) {
+ case ICAL_METHOD_PUBLISH:
+ set_message (itip, _("This is an event that can be added to your calendar."), FALSE);
+ break;
+ case ICAL_METHOD_REQUEST:
+ set_message (itip, _("This is a meeting request."), FALSE);
+ break;
+ case ICAL_METHOD_ADD:
+ set_message (itip, _("This is one or more additions to a current meeting."), FALSE);
+ break;
+ case ICAL_METHOD_REFRESH:
+ set_message (itip, _("This is a request for the latest event information."), FALSE);
+ break;
+ case ICAL_METHOD_REPLY:
+ set_message (itip, _("This is a reply to a meeting request."), FALSE);
+ break;
+ case ICAL_METHOD_CANCEL:
+ set_message (itip, _("This is an event cancellation."), FALSE);
+ break;
+ default:
+ set_message (itip, _("The message is not understandable."), TRUE);
+ }
+}
-/*
- * This function implements the Bonobo::PersistStream:load method.
- */
static void
-pstream_load (BonoboPersistStream *ps, const Bonobo_Stream stream,
- Bonobo_Persist_ContentType type, void *data,
- CORBA_Environment *ev)
+show_current_todo (EItipControl *itip)
{
- EItipControlPrivate *priv = data;
+ EItipControlPrivate *priv;
CalComponentText text;
- CalComponentDateTime datetime;
- CalComponentOrganizer organizer;
- icalproperty *prop;
- GSList *list, *l;
- time_t t;
- gint pos = 0;
- icalcompiter iter;
- icalcomponent_kind comp_kind;
- char message[256];
+ priv = itip->priv;
- if (type && g_strcasecmp (type, "text/calendar") != 0 &&
- g_strcasecmp (type, "text/x-calendar") != 0) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_Bonobo_Persist_WrongDataType, NULL);
- return;
- }
-
- if ((priv->vcalendar = stream_read (stream)) == NULL) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_Bonobo_Persist_FileNotFound, NULL);
- return;
- }
+ set_options (itip);
+
+ cal_component_get_summary (priv->comp, &text);
+ if (text.value)
+ gtk_label_set_text (GTK_LABEL (priv->summary), text.value);
+ else
+ gtk_label_set_text (GTK_LABEL (priv->summary), "");
- /* Do something with the data, here. */
+ set_date_label (priv->datetime, priv->comp);
- priv->main_comp = icalparser_parse_string (priv->vcalendar);
- if (priv->main_comp == NULL) {
- g_printerr ("e-itip-control.c: the iCalendar data was invalid!\n");
- return;
+ switch (priv->method) {
+ case ICAL_METHOD_PUBLISH:
+ set_message (itip, _("This is an task that can be added to your calendar."), FALSE);
+ break;
+ case ICAL_METHOD_REQUEST:
+ set_message (itip, _("This is a task request."), FALSE);
+ break;
+ case ICAL_METHOD_REFRESH:
+ set_message (itip, _("This is a request for the latest task information."), FALSE);
+ break;
+ case ICAL_METHOD_REPLY:
+ set_message (itip, _("This is a reply to a task request."), FALSE);
+ break;
+ case ICAL_METHOD_CANCEL:
+ set_message (itip, _("This is an task cancellation."), FALSE);
+ break;
+ default:
+ set_message (itip, _("The message is not understandable."), TRUE);
}
+}
- iter = icalcomponent_begin_component (priv->main_comp, ICAL_ANY_COMPONENT);
- priv->comp = icalcompiter_deref (&iter);
+static void
+show_current_freebusy (EItipControl *itip)
+{
+ EItipControlPrivate *priv;
+
+ priv = itip->priv;
- {
- FILE *fp;
+ set_options_freebusy (itip);
+
+ gtk_label_set_text (GTK_LABEL (priv->summary), "");
- fp = fopen ("/tmp/evo.debug", "w");
+ set_date_label (priv->datetime, priv->comp);
- fputs ("The raw vCalendar data:\n\n", fp);
- fputs (priv->vcalendar, fp);
+ switch (priv->method) {
+ case ICAL_METHOD_PUBLISH:
+ set_message (itip, _("This is freebusy information."), FALSE);
+ break;
+ case ICAL_METHOD_REQUEST:
+ set_message (itip, _("This is a request for freebusy information."), FALSE);
+ break;
+ case ICAL_METHOD_REPLY:
+ set_message (itip, _("This is a reply to a freebusy request."), FALSE);
+ break;
+ default:
+ set_message (itip, _("The message is not understandable."), TRUE);
+ }
+}
- fputs ("The main component:\n\n", fp);
- fputs (icalcomponent_as_ical_string (priv->main_comp), fp);
+static void
+show_current (EItipControl *itip)
+{
+ EItipControlPrivate *priv;
+ CalComponentVType type;
- fputs ("The child component:\n\n", fp);
- fputs (icalcomponent_as_ical_string (priv->comp), fp);
+ priv = itip->priv;
- fclose (fp);
- }
+ set_label (itip);
+ set_button_status (itip);
- if (priv->comp == NULL) {
- g_printerr ("e-itip-control.c: I could not extract a proper component from\n"
- " the vCalendar data.\n");
- icalcomponent_free (priv->main_comp);
+ if (priv->comp)
+ gtk_object_unref (GTK_OBJECT (priv->comp));
+
+ priv->comp = cal_component_new ();
+ if (!cal_component_set_icalcomponent (priv->comp, priv->ical_comp)) {
+ set_message (itip, _("The message does not appear to be properly formed"), TRUE);
+ gtk_object_unref (GTK_OBJECT (priv->comp));
+ priv->comp = NULL;
return;
- }
+ };
- comp_kind = icalcomponent_isa (priv->comp);
+ type = cal_component_get_vtype (priv->comp);
- switch (comp_kind) {
- case ICAL_VEVENT_COMPONENT:
- case ICAL_VTODO_COMPONENT:
- case ICAL_VJOURNAL_COMPONENT:
- priv->cal_comp = cal_component_new ();
- if (cal_component_set_icalcomponent (priv->cal_comp, priv->comp) == FALSE) {
- g_printerr ("e-itip-control.c: I couldn't create a CalComponent from the iTip data.\n");
- gtk_object_unref (GTK_OBJECT (priv->cal_comp));
- }
+ switch (type) {
+ case CAL_COMPONENT_EVENT:
+ show_current_event (itip);
break;
- case ICAL_VFREEBUSY_COMPONENT:
- /* Take care of busy time information. */
- return;
+ case CAL_COMPONENT_TODO:
+ show_current_todo (itip);
+ break;
+ case CAL_COMPONENT_FREEBUSY:
+ show_current_freebusy (itip);
break;
default:
- /* We don't know what this is, so bail. */
- {
- GtkWidget *dialog;
-
- dialog = gnome_warning_dialog(_("I don't recognize this type of calendar component."));
- gnome_dialog_run (GNOME_DIALOG(dialog));
-
- g_free (priv->vcalendar);
- priv->vcalendar = NULL;
-
- return;
+ set_message (itip, _("The message contains only unsupported requests."), TRUE);
}
- break;
- } /* End switch. */
+}
+void
+e_itip_control_set_data (EItipControl *itip, const gchar *text)
+{
+ EItipControlPrivate *priv;
+ icalproperty *prop;
- /* Fill in the gui */
- cal_component_get_organizer (priv->cal_comp, &organizer);
- priv->organizer = g_strdup (organizer.value);
- gtk_entry_set_text (GTK_ENTRY (priv->organizer_entry), priv->organizer);
+ priv = itip->priv;
- cal_component_get_summary (priv->cal_comp, &text);
- gtk_entry_set_text (GTK_ENTRY (priv->summary_entry), text.value);
-
- cal_component_get_description_list (priv->cal_comp, &list);
- for (l = list; l != NULL; l = l->next) {
- text = *((CalComponentText *)l->data);
+ priv->vcalendar = g_strdup (text);
+
+ priv->main_comp = icalparser_parse_string (priv->vcalendar);
+ if (priv->main_comp == NULL) {
+ set_message (itip, _("The information contained in this attachment was not valid"), TRUE);
+ priv->comp = NULL;
+ priv->total = 0;
+ priv->current = 0;
+ goto show;
- gtk_editable_insert_text (GTK_EDITABLE (priv->description_box),
- text.value, strlen (text.value), &pos);
}
- cal_component_free_text_list (list);
+
+ prop = icalcomponent_get_first_property (priv->main_comp, ICAL_METHOD_PROPERTY);
+ priv->method = icalproperty_get_method (prop);
+
+ priv->iter = icalcomponent_begin_component (priv->main_comp, ICAL_ANY_COMPONENT);
+ priv->ical_comp = icalcompiter_deref (&priv->iter);
- cal_component_get_dtstart (priv->cal_comp, &datetime);
- t = icaltime_as_timet (*datetime.value);
- e_time_format_date_and_time (localtime (&t),
- calendar_config_get_24_hour_format (),
- FALSE, FALSE, message, sizeof (message));
- gtk_label_set_text (GTK_LABEL (priv->dtstart_label), message);
+ priv->total = icalcomponent_count_components (priv->main_comp, ICAL_VEVENT_COMPONENT);
+ priv->total += icalcomponent_count_components (priv->main_comp, ICAL_VTODO_COMPONENT);
+ priv->total += icalcomponent_count_components (priv->main_comp, ICAL_VFREEBUSY_COMPONENT);
- cal_component_get_dtend (priv->cal_comp, &datetime);
- t = icaltime_as_timet (*datetime.value);
- e_time_format_date_and_time (localtime (&t),
- calendar_config_get_24_hour_format (),
- FALSE, FALSE, message, sizeof (message));
- gtk_label_set_text (GTK_LABEL (priv->dtend_label), message);
+ if (priv->total > 0)
+ priv->current = 1;
+ else
+ priv->current = 0;
- /* Clear out any old-assed text that's been lying around in my message box. */
- gtk_editable_delete_text (GTK_EDITABLE (priv->message_text), 0, -1);
+ show:
+ show_current (itip);
+}
+
+gchar *
+e_itip_control_get_data (EItipControl *itip)
+{
+ EItipControlPrivate *priv;
+
+ priv = itip->priv;
-#if 0
- prop = icalcomponent_get_first_property (priv->comp, ICAL_ORGANIZER_PROPERTY);
- if (prop) {
- organizer = icalproperty_get_organizer (prop);
-
- /* Here I strip off the "MAILTO:" if it is present. */
- new_text = strchr (organizer, ':');
- if (new_text != NULL)
- new_text++;
- else
- new_text = organizer;
+ return g_strdup (priv->vcalendar);
+}
- priv->organizer = g_strdup (new_text);
- gtk_entry_set_text (GTK_ENTRY (priv->organizer_entry), new_text);
- }
-#endif
+gint
+e_itip_control_get_data_size (EItipControl *itip)
+{
+ EItipControlPrivate *priv;
- prop = icalcomponent_get_first_property (priv->main_comp, ICAL_METHOD_PROPERTY);
- switch (icalproperty_get_method (prop)) {
- case ICAL_METHOD_PUBLISH:
- {
- GtkWidget *button;
+ priv = itip->priv;
+
+ if (priv->vcalendar == NULL)
+ return 0;
+
+ return strlen (priv->vcalendar);
+}
- snprintf (message, 250, "%s has published calendar information, "
- "which you can add to your own calendar. "
- "No reply is necessary.",
- priv->from_address);
-
- button = gtk_button_new_with_label (_("Add to Calendar"));
- gtk_box_pack_start (GTK_BOX (priv->button_box), button, FALSE, FALSE, 3);
- gtk_widget_show (button);
+void
+e_itip_control_set_from_address (EItipControl *itip, const gchar *address)
+{
+ EItipControlPrivate *priv;
- gtk_signal_connect (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (add_button_clicked_cb), priv);
-
- break;
- }
- case ICAL_METHOD_REQUEST:
- {
- /* I'll check if I have to rsvp. */
- icalproperty *prop;
- icalparameter *param;
- int rsvp = FALSE;
+ priv = itip->priv;
- prop = find_attendee (priv->comp, priv->my_address);
- if (prop) {
- param = get_icalparam_by_type (prop, ICAL_RSVP_PARAMETER);
+ if (priv->from_address)
+ g_free (priv->from_address);
- if (param) {
- if (icalparameter_get_rsvp (param))
- rsvp = TRUE;
- }
- }
+ priv->from_address = g_strdup (address);
+}
- snprintf (message, 250, "This is a meeting organized by %s, "
- "who indicated that you %s RSVP.",
- (priv->organizer ? priv->organizer : "an unknown person"),
- (rsvp ? "should" : "don't have to") );
+const gchar *
+e_itip_control_get_from_address (EItipControl *itip)
+{
+ EItipControlPrivate *priv;
- if (rsvp) {
- GtkWidget *accept_button, *decline_button, *tentative_button;
+ priv = itip->priv;
- accept_button = gtk_button_new_with_label (_(" Accept "));
- decline_button = gtk_button_new_with_label (_(" Decline "));
- tentative_button = gtk_button_new_with_label (_(" Tentative "));
+ return priv->from_address;
+}
- gtk_box_pack_start (GTK_BOX (priv->button_box), decline_button, FALSE, FALSE, 3);
- gtk_box_pack_end (GTK_BOX (priv->button_box), accept_button, FALSE, FALSE, 3);
- gtk_box_pack_end (GTK_BOX (priv->button_box), tentative_button, FALSE, FALSE, 3);
- gtk_signal_connect (GTK_OBJECT (accept_button), "clicked",
- GTK_SIGNAL_FUNC (accept_button_clicked_cb), priv);
- gtk_signal_connect (GTK_OBJECT (tentative_button), "clicked",
- GTK_SIGNAL_FUNC (tentative_button_clicked_cb), priv);
- gtk_signal_connect (GTK_OBJECT (decline_button), "clicked",
- GTK_SIGNAL_FUNC (decline_button_clicked_cb), priv);
+void
+e_itip_control_set_my_address (EItipControl *itip, const gchar *address)
+{
+ EItipControlPrivate *priv;
- gtk_widget_show (accept_button);
- gtk_widget_show (tentative_button);
- gtk_widget_show (decline_button);
- }
+ priv = itip->priv;
- }
- break;
- case ICAL_METHOD_REPLY:
- {
- icalproperty *prop;
- icalparameter *param;
- gboolean success = FALSE;
-
- prop = find_attendee (priv->comp, priv->from_address);
- if (prop) {
- param = get_icalparam_by_type (prop, ICAL_PARTSTAT_PARAMETER);
- if (param) {
- success = TRUE;
+ if (priv->my_address)
+ g_free (priv->my_address);
+
+ priv->my_address = g_strdup (address);
+}
- priv->new_partstat = icalparameter_get_partstat (param);
- }
- }
+const gchar *
+e_itip_control_get_my_address (EItipControl *itip)
+{
+ EItipControlPrivate *priv;
- if (!success) {
- snprintf (message, 250, "%s sent a reply to a meeting request, but "
- "the reply is not properly formed.",
- priv->from_address);
- }
- else {
- GtkWidget *button;
-
- button = gtk_button_new_with_label (_("Update Calendar"));
- gtk_box_pack_start (GTK_BOX (priv->button_box), button, FALSE, FALSE, 3);
- gtk_widget_show (button);
-
- gtk_signal_connect (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (update_reply_cb), priv);
-
- snprintf (message, 250, "%s responded to your request, replying with: %s",
- priv->from_address, partstat_values[priv->new_partstat]);
- }
+ priv = itip->priv;
- }
- break;
- case ICAL_METHOD_CANCEL:
- if (strcmp (priv->organizer, priv->from_address) != 0) {
- snprintf (message, 250, "%s sent a cancellation request, but is not "
- "the organizer of the meeting.",
- priv->from_address);
- } else {
- GtkWidget *button;
-
- button = gtk_button_new_with_label (_("Cancel Meeting"));
- gtk_box_pack_start (GTK_BOX (priv->button_box), button, FALSE, FALSE, 3);
- gtk_widget_show (button);
-
- gtk_signal_connect (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (cancel_meeting_cb), priv);
-
- snprintf (message, 250, "%s sent a cancellation request. You can"
- " delete this event from your calendar, if you wish.",
- priv->organizer);
- }
- break;
- default:
- snprintf (message, 250, "I haven't the slightest notion what this calendar "
- "object represents. Sorry.");
- }
+ return priv->my_address;
+}
- pos = 0;
- gtk_editable_insert_text (GTK_EDITABLE (priv->message_text),
- message, strlen (message), &pos);
-} /* pstream_load */
-/*
- * This function implements the Bonobo::PersistStream:save method.
- */
static void
-pstream_save (BonoboPersistStream *ps, const Bonobo_Stream stream,
- Bonobo_Persist_ContentType type, void *data,
- CORBA_Environment *ev)
+update_item (EItipControl *itip)
{
- EItipControlPrivate *priv = data;
- int length;
+ EItipControlPrivate *priv;
+ CalClient *client;
+ CalComponentVType type;
+
+ priv = itip->priv;
- if (type && g_strcasecmp (type, "text/calendar") != 0 &&
- g_strcasecmp (type, "text/x-calendar") != 0) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_Bonobo_Persist_WrongDataType, NULL);
- return;
+ type = cal_component_get_vtype (priv->comp);
+ if (type == CAL_COMPONENT_TODO)
+ client = priv->task_client;
+ else
+ client = priv->event_client;
+
+ if (!cal_client_update_object (client, priv->comp)) {
+ GtkWidget *dialog;
+
+ dialog = gnome_warning_dialog(_("I couldn't update your calendar file!\n"));
+ gnome_dialog_run (GNOME_DIALOG(dialog));
}
+}
- /* Put something into vcalendar here. */
- length = strlen (priv->vcalendar);
+static void
+remove_item (EItipControl *itip)
+{
+ EItipControlPrivate *priv;
+ CalClient *client;
+ CalComponentVType type;
+ const char *uid;
+
+ priv = itip->priv;
- bonobo_stream_client_write (stream, priv->vcalendar, length, ev);
-} /* pstream_save */
+ type = cal_component_get_vtype (priv->comp);
+ if (type == CAL_COMPONENT_TODO)
+ client = priv->task_client;
+ else
+ client = priv->event_client;
-static CORBA_long
-pstream_get_max_size (BonoboPersistStream *ps, void *data,
- CORBA_Environment *ev)
-{
- EItipControlPrivate *priv = data;
-
- if (priv->vcalendar)
- return strlen (priv->vcalendar);
- else
- return 0L;
+ cal_component_get_uid (priv->comp, &uid);
+ if (!cal_client_remove_object (client, uid)) {
+ GtkWidget *dialog;
+
+ dialog = gnome_warning_dialog(_("I couldn't remove the item from your calendar file!\n"));
+ gnome_dialog_run (GNOME_DIALOG(dialog));
+ }
}
-static Bonobo_Persist_ContentTypeList *
-pstream_get_content_types (BonoboPersistStream *ps, void *closure,
- CORBA_Environment *ev)
+static void
+send_freebusy (void)
{
- return bonobo_persist_generate_content_types (2, "text/calendar", "text/x-calendar");
}
static void
-get_prop ( BonoboPropertyBag *bag,
- BonoboArg *arg,
- guint arg_id,
- CORBA_Environment *ev,
- gpointer user_data)
+change_status (EItipControl *itip, gchar *address, icalparameter_partstat status)
{
- EItipControlPrivate *priv = user_data;
+ EItipControlPrivate *priv;
+ icalproperty *prop;
- if (arg_id == FROM_ADDRESS_ARG_ID) {
- BONOBO_ARG_SET_STRING (arg, priv->from_address);
- }
- else if (arg_id == MY_ADDRESS_ARG_ID) {
- BONOBO_ARG_SET_STRING (arg, priv->my_address);
+ priv = itip->priv;
+
+ prop = find_attendee (priv->ical_comp, address);
+ if (prop) {
+ icalparameter *param;
+
+ icalproperty_remove_parameter (prop, ICAL_PARTSTAT_PARAMETER);
+ param = icalparameter_new_partstat (status);
+ icalproperty_add_parameter (prop, param);
}
}
static void
-set_prop ( BonoboPropertyBag *bag,
- const BonoboArg *arg,
- guint arg_id,
- CORBA_Environment *ev,
- gpointer user_data)
+prev_clicked_cb (GtkWidget *widget, gpointer data)
{
- EItipControlPrivate *priv = user_data;
+ EItipControl *itip = E_ITIP_CONTROL (data);
+ EItipControlPrivate *priv;
- if (arg_id == FROM_ADDRESS_ARG_ID) {
- if (priv->from_address)
- g_free (priv->from_address);
+ priv = itip->priv;
-
- priv->from_address = g_strdup (BONOBO_ARG_GET_STRING (arg));
+ priv->current--;
+ priv->ical_comp = icalcompiter_prior (&priv->iter);
- /* Let's set the widget here, though I'm not sure if
- it will work. */
- gtk_entry_set_text (GTK_ENTRY (priv->address_entry), priv->from_address);
-
- }
- else if (arg_id == MY_ADDRESS_ARG_ID) {
- if (priv->my_address)
- g_free (priv->my_address);
-
- priv->my_address = g_strdup (BONOBO_ARG_GET_STRING (arg));
- }
+ show_current (itip);
}
-
-static BonoboObject *
-e_itip_control_factory (BonoboGenericFactory *Factory, void *closure)
+static void
+next_clicked_cb (GtkWidget *widget, gpointer data)
{
- BonoboControl *control;
- BonoboPropertyBag *prop_bag;
- BonoboPersistStream *stream;
+ EItipControl *itip = E_ITIP_CONTROL (data);
EItipControlPrivate *priv;
- priv = g_new0 (EItipControlPrivate, 1);
-
- priv->xml = glade_xml_new (EVOLUTION_GLADEDIR "/" "e-itip-control.glade", "main_frame");
-
- /* Create the control. */
- priv->main_frame = glade_xml_get_widget (priv->xml, "main_frame");
- priv->organizer_entry = glade_xml_get_widget (priv->xml, "organizer_entry");
- priv->dtstart_label = glade_xml_get_widget (priv->xml, "dtstart_label");
- priv->dtend_label = glade_xml_get_widget (priv->xml, "dtend_label");
- priv->summary_entry = glade_xml_get_widget (priv->xml, "summary_entry");
- priv->description_box = glade_xml_get_widget (priv->xml, "description_box");
- /* priv->add_button = glade_xml_get_widget (priv->xml, "add_button"); */
- priv->button_box = glade_xml_get_widget (priv->xml, "button_box");
- priv->address_entry = glade_xml_get_widget (priv->xml, "address_entry");
- priv->message_text = glade_xml_get_widget (priv->xml, "message_text");
-
- gtk_text_set_word_wrap (GTK_TEXT (priv->message_text), TRUE);
+ priv = itip->priv;
- priv->xml2 = glade_xml_new (EVOLUTION_GLADEDIR "/" "e-itip-control.glade", "loading_window");
- priv->loading_progress = glade_xml_get_widget (priv->xml2, "loading_progress");
- priv->loading_window = glade_xml_get_widget (priv->xml2, "loading_window");
-
- gtk_signal_connect (GTK_OBJECT (priv->main_frame), "destroy",
- GTK_SIGNAL_FUNC (itip_control_destroy_cb), priv);
+ priv->current++;
+ priv->ical_comp = icalcompiter_next (&priv->iter);
- gtk_widget_show (priv->main_frame);
+ show_current (itip);
+}
- control = bonobo_control_new (priv->main_frame);
+static void
+ok_clicked_cb (GtkWidget *widget, gpointer data)
+{
+ EItipControl *itip = E_ITIP_CONTROL (data);
+ EItipControlPrivate *priv;
+ gint selection;
+
+ priv = itip->priv;
- /* create a property bag */
- prop_bag = bonobo_property_bag_new ( get_prop, set_prop, priv );
- bonobo_property_bag_add (prop_bag, "from_address", FROM_ADDRESS_ARG_ID, BONOBO_ARG_STRING, NULL,
- "from_address", 0 );
- bonobo_property_bag_add (prop_bag, "my_address", MY_ADDRESS_ARG_ID, BONOBO_ARG_STRING, NULL,
- "my_address", 0 );
+ selection = e_dialog_option_menu_get (priv->options, priv->map);
- bonobo_control_set_properties (control, prop_bag);
- bonobo_object_unref (BONOBO_OBJECT (prop_bag));
+ if (priv->map == publish_map) {
+ update_item (itip);
+ } else if (priv->map == request_map) {
+ gboolean rsvp = FALSE;
+
+ switch (selection) {
+ case ACCEPT_TO_CALENDAR_RSVP:
+ rsvp = TRUE;
+ case ACCEPT_TO_CALENDAR:
+ change_status (itip, priv->my_address, ICAL_PARTSTAT_ACCEPTED);
+ break;
+ case TENTATIVE_TO_CALENDAR_RSVP:
+ rsvp = TRUE;
+ case TENTATIVE_TO_CALENDAR:
+ change_status (itip, priv->my_address, ICAL_PARTSTAT_TENTATIVE);
+ break;
+ case DECLINE_TO_CALENDAR_RSVP:
+ rsvp = TRUE;
+ case DECLINE_TO_CALENDAR:
+ change_status (itip, priv->my_address, ICAL_PARTSTAT_DECLINED);
+ break;
+ }
+ update_item (itip);
+ if (rsvp)
+ itip_send_comp (CAL_COMPONENT_METHOD_REPLY, priv->comp);
- bonobo_control_set_automerge (control, TRUE);
+ } else if (priv->map == request_fb_map) {
+ send_freebusy ();
- stream = bonobo_persist_stream_new (pstream_load, pstream_save,
- pstream_get_max_size,
- pstream_get_content_types,
- priv);
+ } else if (priv->map == reply_map) {
+ update_item (itip);
- if (stream == NULL) {
- bonobo_object_unref (BONOBO_OBJECT (control));
- return NULL;
+ } else if (priv->map == cancel_map) {
+ remove_item (itip);
}
-
- bonobo_object_add_interface (BONOBO_OBJECT (control),
- BONOBO_OBJECT (stream));
-
- return BONOBO_OBJECT (control);
-}
-
-void
-e_itip_control_factory_init (void)
-{
- static BonoboGenericFactory *factory = NULL;
-
- if (factory != NULL)
- return;
-
- factory = bonobo_generic_factory_new (
- "OAFIID:GNOME_Evolution_Calendar_iTip_ControlFactory",
- e_itip_control_factory, NULL);
- bonobo_running_context_auto_exit_unref (BONOBO_OBJECT (factory));;
-
- if (factory == NULL)
- g_error ("I could not register an iTip control factory.");
}
-
diff --git a/calendar/gui/e-itip-control.h b/calendar/gui/e-itip-control.h
index 6c2df626ce..afad2b744d 100644
--- a/calendar/gui/e-itip-control.h
+++ b/calendar/gui/e-itip-control.h
@@ -1,30 +1,79 @@
-/* Evolution calendar - Control for displaying iTIP mail messages
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* e-itip-control.h
*
- * Copyright (C) 2000 Helix Code, Inc.
- * Copyright (C) 2000 Ximian, Inc.
+ * Copyright (C) 2001 Ximian, Inc.
*
- * Author: Jesse Pavel <jpavel@ximian.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * 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.
+ * 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.
*
- * 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.
+ * Author: JP Rosevear
*/
-#ifndef __E_ITIP_CONTROL_H__
-#define __E_ITIP_CONTROL_H__
+#ifndef _E_ITIP_CONTROL_H_
+#define _E_ITIP_CONTROL_H_
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+
+#ifdef __cplusplus
+extern "C" {
+#pragma }
+#endif /* __cplusplus */
+
+#define E_TYPE_ITIP_CONTROL (e_itip_control_get_type ())
+#define E_ITIP_CONTROL(obj) (GTK_CHECK_CAST ((obj), E_TYPE_ITIP_CONTROL, EItipControl))
+#define E_ITIP_CONTROL_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_ITIP_CONTROL, EItipControlClass))
+#define E_IS_ITIP_CONTROL(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_ITIP_CONTROL))
+#define E_IS_ITIP_CONTROL_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TYPE_ITIP_CONTROL))
+
+
+typedef struct _EItipControl EItipControl;
+typedef struct _EItipControlPrivate EItipControlPrivate;
+typedef struct _EItipControlClass EItipControlClass;
+
+struct _EItipControl {
+ GtkVBox parent;
+
+ EItipControlPrivate *priv;
+};
+
+struct _EItipControlClass {
+ GtkVBoxClass parent_class;
+};
+
+
+
+GtkType e_itip_control_get_type (void);
+GtkWidget * e_itip_control_new (void);
+void e_itip_control_set_data (EItipControl *itip,
+ const gchar *text);
+gchar * e_itip_control_get_data (EItipControl *itip);
+gint e_itip_control_get_data_size (EItipControl *itip);
+void e_itip_control_set_from_address (EItipControl *itip,
+ const gchar *address);
+const gchar *e_itip_control_get_from_address (EItipControl *itip);
+void e_itip_control_set_my_address (EItipControl *itip,
+ const gchar *address);
+const gchar *e_itip_control_get_my_address (EItipControl *itip);
-#include <bonobo/bonobo-control.h>
-void e_itip_control_factory_init (void);
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
-#endif /* __E_ITIP_CONTROL_H__ */
+#endif /* _E_ITIP_CONTROL_H_ */
diff --git a/calendar/gui/itip-bonobo-control.c b/calendar/gui/itip-bonobo-control.c
new file mode 100644
index 0000000000..a385803bc8
--- /dev/null
+++ b/calendar/gui/itip-bonobo-control.c
@@ -0,0 +1,267 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* Evolution calendar - Control for displaying iTIP mail messages
+ *
+ * Copyright (C) 2000 Helix Code, Inc.
+ * Copyright (C) 2000 Ximian, Inc.
+ *
+ * Author: Jesse Pavel <jpavel@ximian.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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.
+ */
+
+#include <config.h>
+#include <glib.h>
+#include <gtk/gtkobject.h>
+#include <gtk/gtkwidget.h>
+#include <bonobo/bonobo-generic-factory.h>
+#include <bonobo/bonobo-control.h>
+#include <bonobo/bonobo-property-bag.h>
+#include <bonobo/bonobo-persist-stream.h>
+#include <bonobo/bonobo-stream-client.h>
+#include <bonobo/bonobo-context.h>
+#include <ical.h>
+
+#include "e-itip-control.h"
+#include "itip-control-factory.h"
+
+extern gchar *evolution_dir;
+
+enum E_ITIP_BONOBO_ARGS {
+ FROM_ADDRESS_ARG_ID,
+ MY_ADDRESS_ARG_ID
+};
+
+/*
+ * Bonobo::PersistStream
+ *
+ * These two functions implement the Bonobo::PersistStream load and
+ * save methods which allow data to be loaded into and out of the
+ * BonoboObject.
+ */
+
+static char *
+stream_read (Bonobo_Stream stream)
+{
+ Bonobo_Stream_iobuf *buffer;
+ CORBA_Environment ev;
+ gchar *data = NULL;
+ gint length = 0;
+
+ CORBA_exception_init (&ev);
+ do {
+#define READ_CHUNK_SIZE 65536
+ Bonobo_Stream_read (stream, READ_CHUNK_SIZE,
+ &buffer, &ev);
+
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ CORBA_exception_free (&ev);
+ return NULL;
+ }
+
+ if (buffer->_length <= 0)
+ break;
+
+ data = g_realloc (data,
+ length + buffer->_length);
+
+ memcpy (data + length,
+ buffer->_buffer, buffer->_length);
+
+ length += buffer->_length;
+
+ CORBA_free (buffer);
+#undef READ_CHUNK_SIZE
+ } while (1);
+
+ CORBA_free (buffer);
+ CORBA_exception_free (&ev);
+
+ if (data == NULL)
+ data = g_strdup("");
+
+ return data;
+} /* stream_read */
+
+/*
+ * This function implements the Bonobo::PersistStream:load method.
+ */
+static void
+pstream_load (BonoboPersistStream *ps, const Bonobo_Stream stream,
+ Bonobo_Persist_ContentType type, void *data,
+ CORBA_Environment *ev)
+{
+ EItipControl *itip = data;
+ gchar *text;
+
+ if (type && g_strcasecmp (type, "text/calendar") != 0 &&
+ g_strcasecmp (type, "text/x-calendar") != 0) {
+ CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
+ ex_Bonobo_Persist_WrongDataType, NULL);
+ return;
+ }
+
+ if ((text = stream_read (stream)) == NULL) {
+ CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
+ ex_Bonobo_Persist_FileNotFound, NULL);
+ return;
+ }
+
+ e_itip_control_set_data (itip, text);
+ g_free (text);
+}
+/*
+ * This function implements the Bonobo::PersistStream:save method.
+ */
+static void
+pstream_save (BonoboPersistStream *ps, const Bonobo_Stream stream,
+ Bonobo_Persist_ContentType type, void *data,
+ CORBA_Environment *ev)
+{
+ EItipControl *itip = data;
+ gchar *text;
+ gint len;
+
+ if (type && g_strcasecmp (type, "text/calendar") != 0 &&
+ g_strcasecmp (type, "text/x-calendar") != 0) {
+ CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
+ ex_Bonobo_Persist_WrongDataType, NULL);
+ return;
+ }
+
+ text = e_itip_control_get_data (itip);
+ len = e_itip_control_get_data_size (itip);
+
+ bonobo_stream_client_write (stream, text, len, ev);
+ g_free (text);
+} /* pstream_save */
+
+static CORBA_long
+pstream_get_max_size (BonoboPersistStream *ps, void *data,
+ CORBA_Environment *ev)
+{
+ EItipControl *itip = data;
+ gint len;
+
+ len = e_itip_control_get_data_size (itip);
+
+ if (len > 0)
+ return len;
+
+ return 0L;
+}
+
+static Bonobo_Persist_ContentTypeList *
+pstream_get_content_types (BonoboPersistStream *ps, void *closure,
+ CORBA_Environment *ev)
+{
+ return bonobo_persist_generate_content_types (2, "text/calendar", "text/x-calendar");
+}
+
+static void
+get_prop (BonoboPropertyBag *bag,
+ BonoboArg *arg,
+ guint arg_id,
+ CORBA_Environment *ev,
+ gpointer user_data)
+{
+ EItipControl *itip = user_data;
+
+ switch (arg_id) {
+ case FROM_ADDRESS_ARG_ID:
+ BONOBO_ARG_SET_STRING (arg, e_itip_control_get_from_address (itip));
+ break;
+ case MY_ADDRESS_ARG_ID:
+ BONOBO_ARG_SET_STRING (arg, e_itip_control_get_my_address (itip));
+ break;
+ }
+}
+
+static void
+set_prop ( BonoboPropertyBag *bag,
+ const BonoboArg *arg,
+ guint arg_id,
+ CORBA_Environment *ev,
+ gpointer user_data)
+{
+ EItipControl *itip = user_data;
+
+ switch (arg_id) {
+ case FROM_ADDRESS_ARG_ID:
+ e_itip_control_set_from_address (itip, BONOBO_ARG_GET_STRING (arg));
+ break;
+ case MY_ADDRESS_ARG_ID:
+ e_itip_control_set_my_address (itip, BONOBO_ARG_GET_STRING (arg));
+ break;
+ }
+}
+
+
+static BonoboObject *
+itip_control_factory (BonoboGenericFactory *Factory, void *closure)
+{
+ BonoboControl *control;
+ BonoboPropertyBag *prop_bag;
+ BonoboPersistStream *stream;
+ GtkWidget *itip;
+
+ itip = e_itip_control_new ();
+ gtk_widget_show (itip);
+ control = bonobo_control_new (itip);
+
+ /* create a property bag */
+ prop_bag = bonobo_property_bag_new (get_prop, set_prop, itip);
+ bonobo_property_bag_add (prop_bag, "from_address", FROM_ADDRESS_ARG_ID, BONOBO_ARG_STRING, NULL,
+ "from_address", 0 );
+ bonobo_property_bag_add (prop_bag, "my_address", MY_ADDRESS_ARG_ID, BONOBO_ARG_STRING, NULL,
+ "my_address", 0 );
+
+ bonobo_control_set_properties (control, prop_bag);
+ bonobo_object_unref (BONOBO_OBJECT (prop_bag));
+
+ bonobo_control_set_automerge (control, TRUE);
+
+ stream = bonobo_persist_stream_new (pstream_load, pstream_save,
+ pstream_get_max_size,
+ pstream_get_content_types,
+ itip);
+
+ if (stream == NULL) {
+ bonobo_object_unref (BONOBO_OBJECT (control));
+ return NULL;
+ }
+
+ bonobo_object_add_interface (BONOBO_OBJECT (control),
+ BONOBO_OBJECT (stream));
+
+ return BONOBO_OBJECT (control);
+}
+
+void
+itip_control_factory_init (void)
+{
+ static BonoboGenericFactory *factory = NULL;
+
+ if (factory != NULL)
+ return;
+
+ factory = bonobo_generic_factory_new (
+ "OAFIID:GNOME_Evolution_Calendar_iTip_ControlFactory",
+ itip_control_factory, NULL);
+ bonobo_running_context_auto_exit_unref (BONOBO_OBJECT (factory));;
+
+ if (factory == NULL)
+ g_error ("I could not register an iTip control factory.");
+}
+
diff --git a/calendar/gui/itip-bonobo-control.h b/calendar/gui/itip-bonobo-control.h
new file mode 100644
index 0000000000..045fd31bc3
--- /dev/null
+++ b/calendar/gui/itip-bonobo-control.h
@@ -0,0 +1,30 @@
+/* Evolution calendar - Control for displaying iTIP mail messages
+ *
+ * Copyright (C) 2000 Helix Code, Inc.
+ * Copyright (C) 2000 Ximian, Inc.
+ *
+ * Authors:
+ * Jesse Pavel <jpavel@ximian.com>
+ * JP Rosevear <jpr@ximian.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 __ITIP_CONTROL_FACTORY_H__
+#define __ITIP_CONTROL_FACTORY_H__
+
+void itip_control_factory_init (void);
+
+#endif /* __ITIP_CONTROL_H__ */
diff --git a/calendar/gui/itip-control-factory.c b/calendar/gui/itip-control-factory.c
new file mode 100644
index 0000000000..a385803bc8
--- /dev/null
+++ b/calendar/gui/itip-control-factory.c
@@ -0,0 +1,267 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* Evolution calendar - Control for displaying iTIP mail messages
+ *
+ * Copyright (C) 2000 Helix Code, Inc.
+ * Copyright (C) 2000 Ximian, Inc.
+ *
+ * Author: Jesse Pavel <jpavel@ximian.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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.
+ */
+
+#include <config.h>
+#include <glib.h>
+#include <gtk/gtkobject.h>
+#include <gtk/gtkwidget.h>
+#include <bonobo/bonobo-generic-factory.h>
+#include <bonobo/bonobo-control.h>
+#include <bonobo/bonobo-property-bag.h>
+#include <bonobo/bonobo-persist-stream.h>
+#include <bonobo/bonobo-stream-client.h>
+#include <bonobo/bonobo-context.h>
+#include <ical.h>
+
+#include "e-itip-control.h"
+#include "itip-control-factory.h"
+
+extern gchar *evolution_dir;
+
+enum E_ITIP_BONOBO_ARGS {
+ FROM_ADDRESS_ARG_ID,
+ MY_ADDRESS_ARG_ID
+};
+
+/*
+ * Bonobo::PersistStream
+ *
+ * These two functions implement the Bonobo::PersistStream load and
+ * save methods which allow data to be loaded into and out of the
+ * BonoboObject.
+ */
+
+static char *
+stream_read (Bonobo_Stream stream)
+{
+ Bonobo_Stream_iobuf *buffer;
+ CORBA_Environment ev;
+ gchar *data = NULL;
+ gint length = 0;
+
+ CORBA_exception_init (&ev);
+ do {
+#define READ_CHUNK_SIZE 65536
+ Bonobo_Stream_read (stream, READ_CHUNK_SIZE,
+ &buffer, &ev);
+
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ CORBA_exception_free (&ev);
+ return NULL;
+ }
+
+ if (buffer->_length <= 0)
+ break;
+
+ data = g_realloc (data,
+ length + buffer->_length);
+
+ memcpy (data + length,
+ buffer->_buffer, buffer->_length);
+
+ length += buffer->_length;
+
+ CORBA_free (buffer);
+#undef READ_CHUNK_SIZE
+ } while (1);
+
+ CORBA_free (buffer);
+ CORBA_exception_free (&ev);
+
+ if (data == NULL)
+ data = g_strdup("");
+
+ return data;
+} /* stream_read */
+
+/*
+ * This function implements the Bonobo::PersistStream:load method.
+ */
+static void
+pstream_load (BonoboPersistStream *ps, const Bonobo_Stream stream,
+ Bonobo_Persist_ContentType type, void *data,
+ CORBA_Environment *ev)
+{
+ EItipControl *itip = data;
+ gchar *text;
+
+ if (type && g_strcasecmp (type, "text/calendar") != 0 &&
+ g_strcasecmp (type, "text/x-calendar") != 0) {
+ CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
+ ex_Bonobo_Persist_WrongDataType, NULL);
+ return;
+ }
+
+ if ((text = stream_read (stream)) == NULL) {
+ CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
+ ex_Bonobo_Persist_FileNotFound, NULL);
+ return;
+ }
+
+ e_itip_control_set_data (itip, text);
+ g_free (text);
+}
+/*
+ * This function implements the Bonobo::PersistStream:save method.
+ */
+static void
+pstream_save (BonoboPersistStream *ps, const Bonobo_Stream stream,
+ Bonobo_Persist_ContentType type, void *data,
+ CORBA_Environment *ev)
+{
+ EItipControl *itip = data;
+ gchar *text;
+ gint len;
+
+ if (type && g_strcasecmp (type, "text/calendar") != 0 &&
+ g_strcasecmp (type, "text/x-calendar") != 0) {
+ CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
+ ex_Bonobo_Persist_WrongDataType, NULL);
+ return;
+ }
+
+ text = e_itip_control_get_data (itip);
+ len = e_itip_control_get_data_size (itip);
+
+ bonobo_stream_client_write (stream, text, len, ev);
+ g_free (text);
+} /* pstream_save */
+
+static CORBA_long
+pstream_get_max_size (BonoboPersistStream *ps, void *data,
+ CORBA_Environment *ev)
+{
+ EItipControl *itip = data;
+ gint len;
+
+ len = e_itip_control_get_data_size (itip);
+
+ if (len > 0)
+ return len;
+
+ return 0L;
+}
+
+static Bonobo_Persist_ContentTypeList *
+pstream_get_content_types (BonoboPersistStream *ps, void *closure,
+ CORBA_Environment *ev)
+{
+ return bonobo_persist_generate_content_types (2, "text/calendar", "text/x-calendar");
+}
+
+static void
+get_prop (BonoboPropertyBag *bag,
+ BonoboArg *arg,
+ guint arg_id,
+ CORBA_Environment *ev,
+ gpointer user_data)
+{
+ EItipControl *itip = user_data;
+
+ switch (arg_id) {
+ case FROM_ADDRESS_ARG_ID:
+ BONOBO_ARG_SET_STRING (arg, e_itip_control_get_from_address (itip));
+ break;
+ case MY_ADDRESS_ARG_ID:
+ BONOBO_ARG_SET_STRING (arg, e_itip_control_get_my_address (itip));
+ break;
+ }
+}
+
+static void
+set_prop ( BonoboPropertyBag *bag,
+ const BonoboArg *arg,
+ guint arg_id,
+ CORBA_Environment *ev,
+ gpointer user_data)
+{
+ EItipControl *itip = user_data;
+
+ switch (arg_id) {
+ case FROM_ADDRESS_ARG_ID:
+ e_itip_control_set_from_address (itip, BONOBO_ARG_GET_STRING (arg));
+ break;
+ case MY_ADDRESS_ARG_ID:
+ e_itip_control_set_my_address (itip, BONOBO_ARG_GET_STRING (arg));
+ break;
+ }
+}
+
+
+static BonoboObject *
+itip_control_factory (BonoboGenericFactory *Factory, void *closure)
+{
+ BonoboControl *control;
+ BonoboPropertyBag *prop_bag;
+ BonoboPersistStream *stream;
+ GtkWidget *itip;
+
+ itip = e_itip_control_new ();
+ gtk_widget_show (itip);
+ control = bonobo_control_new (itip);
+
+ /* create a property bag */
+ prop_bag = bonobo_property_bag_new (get_prop, set_prop, itip);
+ bonobo_property_bag_add (prop_bag, "from_address", FROM_ADDRESS_ARG_ID, BONOBO_ARG_STRING, NULL,
+ "from_address", 0 );
+ bonobo_property_bag_add (prop_bag, "my_address", MY_ADDRESS_ARG_ID, BONOBO_ARG_STRING, NULL,
+ "my_address", 0 );
+
+ bonobo_control_set_properties (control, prop_bag);
+ bonobo_object_unref (BONOBO_OBJECT (prop_bag));
+
+ bonobo_control_set_automerge (control, TRUE);
+
+ stream = bonobo_persist_stream_new (pstream_load, pstream_save,
+ pstream_get_max_size,
+ pstream_get_content_types,
+ itip);
+
+ if (stream == NULL) {
+ bonobo_object_unref (BONOBO_OBJECT (control));
+ return NULL;
+ }
+
+ bonobo_object_add_interface (BONOBO_OBJECT (control),
+ BONOBO_OBJECT (stream));
+
+ return BONOBO_OBJECT (control);
+}
+
+void
+itip_control_factory_init (void)
+{
+ static BonoboGenericFactory *factory = NULL;
+
+ if (factory != NULL)
+ return;
+
+ factory = bonobo_generic_factory_new (
+ "OAFIID:GNOME_Evolution_Calendar_iTip_ControlFactory",
+ itip_control_factory, NULL);
+ bonobo_running_context_auto_exit_unref (BONOBO_OBJECT (factory));;
+
+ if (factory == NULL)
+ g_error ("I could not register an iTip control factory.");
+}
+
diff --git a/calendar/gui/itip-control-factory.h b/calendar/gui/itip-control-factory.h
new file mode 100644
index 0000000000..045fd31bc3
--- /dev/null
+++ b/calendar/gui/itip-control-factory.h
@@ -0,0 +1,30 @@
+/* Evolution calendar - Control for displaying iTIP mail messages
+ *
+ * Copyright (C) 2000 Helix Code, Inc.
+ * Copyright (C) 2000 Ximian, Inc.
+ *
+ * Authors:
+ * Jesse Pavel <jpavel@ximian.com>
+ * JP Rosevear <jpr@ximian.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 __ITIP_CONTROL_FACTORY_H__
+#define __ITIP_CONTROL_FACTORY_H__
+
+void itip_control_factory_init (void);
+
+#endif /* __ITIP_CONTROL_H__ */
diff --git a/calendar/gui/main.c b/calendar/gui/main.c
index e75819f0f0..7a21193799 100644
--- a/calendar/gui/main.c
+++ b/calendar/gui/main.c
@@ -41,7 +41,7 @@
#include "calendar-config.h"
#include "component-factory.h"
#include "control-factory.h"
-#include "e-itip-control.h"
+#include "itip-control-factory.h"
#include "tasks-control-factory.h"
static void
@@ -77,7 +77,7 @@ main (int argc, char **argv)
control_factory_init ();
component_factory_init ();
- e_itip_control_factory_init ();
+ itip_control_factory_init ();
tasks_control_factory_init ();
bonobo_main ();