From 806e63b32a7fdca4899d89ba236a0eb64726707c Mon Sep 17 00:00:00 2001 From: Rodrigo Moya Date: Tue, 22 Jul 2003 21:13:38 +0000 Subject: added "get_selected_events", and "update_query" virtual methods. 2003-07-22 Rodrigo Moya * gui/e-cal-view.[ch]: added "get_selected_events", and "update_query" virtual methods. (e_cal_view_class_init): initialize new virtual methods. (e_cal_view_destroy): destroy new private members. (e_cal_view_get_selected_events, e_cal_view_set_cal_client, e_cal_view_get_cal_client): new functions. (e_cal_view_cut_clipboard, e_cal_view_copy_clipboard, e_cal_view_paste_clipboard): merged clipboard stuff. * gui/e-day-view.c (e_day_view_cut_clipboard, e_day_view_copy_clipboard, e_day_view_paste_clipboard): removed. (e_day_view_get_selected_events): made these private as the implementation of the 'get_selected_events' base class virtual method. * gui/e-week-view.c (e_week_view_get_selected_events): ditto. (e_week_view_cut_clipboard, e_week_view_copy_clipboard, e_week_view_paste_clipboard): removed. * gui/calendar-commands.c (sensitize_calendar_commands): call e_cal_view_get_selected_events. * gui/gnome-cal.c: removed a lot of redundant code thanks to the above changes. svn path=/trunk/; revision=21893 --- calendar/gui/e-calendar-view.c | 421 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 421 insertions(+) (limited to 'calendar/gui/e-calendar-view.c') diff --git a/calendar/gui/e-calendar-view.c b/calendar/gui/e-calendar-view.c index 6272f0eab9..1b4676beb8 100644 --- a/calendar/gui/e-calendar-view.c +++ b/calendar/gui/e-calendar-view.c @@ -22,9 +22,17 @@ */ #include +#include +#include +#include #include #include "evolution-activity-client.h" +#include "calendar-config.h" #include "e-cal-view.h" +#include "itip-utils.h" +#include "dialogs/cancel-comp.h" +#include "dialogs/delete-error.h" +#include "dialogs/send-comp.h" /* Used for the status bar messages */ #define EVOLUTION_CALENDAR_PROGRESS_IMAGE "evolution-calendar-mini.png" @@ -34,8 +42,18 @@ struct _ECalViewPrivate { /* The GnomeCalendar we are associated to */ GnomeCalendar *calendar; + /* Calendar client we are monitoring */ + CalClient *client; + + /* Search expression */ + gchar *sexp; + /* The activity client used to show messages on the status bar. */ EvolutionActivityClient *activity; + + /* the invisible widget to manage the clipboard selections */ + GtkWidget *invisible; + gchar *clipboard_selection; }; static void e_cal_view_class_init (ECalViewClass *klass); @@ -43,6 +61,7 @@ static void e_cal_view_init (ECalView *cal_view, ECalViewClass *klass); static void e_cal_view_destroy (GtkObject *object); static GObjectClass *parent_class = NULL; +static GdkAtom clipboard_atom = GDK_NONE; /* Signal IDs */ enum { @@ -73,12 +92,203 @@ e_cal_view_class_init (ECalViewClass *klass) object_class->destroy = e_cal_view_destroy; klass->selection_changed = NULL; + klass->get_selected_events = NULL; + klass->get_selected_time_range = NULL; + klass->set_selected_time_range = NULL; + klass->update_query = NULL; + + /* clipboard atom */ + if (!clipboard_atom) + clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE); +} + +static void +selection_get (GtkWidget *invisible, + GtkSelectionData *selection_data, + guint info, + guint time_stamp, + ECalView *cal_view) +{ + if (cal_view->priv->clipboard_selection != NULL) { + gtk_selection_data_set (selection_data, + GDK_SELECTION_TYPE_STRING, + 8, + cal_view->priv->clipboard_selection, + strlen (cal_view->priv->clipboard_selection)); + } +} + +static void +selection_clear_event (GtkWidget *invisible, + GdkEventSelection *event, + ECalView *cal_view) +{ + if (cal_view->priv->clipboard_selection != NULL) { + g_free (cal_view->priv->clipboard_selection); + cal_view->priv->clipboard_selection = NULL; + } +} + +static void +selection_received (GtkWidget *invisible, + GtkSelectionData *selection_data, + guint time, + ECalView *cal_view) +{ + char *comp_str, *default_tzid; + icalcomponent *icalcomp; + icalcomponent_kind kind; + CalComponent *comp; + time_t selected_time_start, selected_time_end; + struct icaltimetype itime; + struct icaltimetype tmp_itime; + time_t tt_start, tt_end; + struct icaldurationtype ic_dur; + char *uid; + CalComponentDateTime ccdt; + icaltimezone *default_zone; + + g_return_if_fail (E_IS_CAL_VIEW (cal_view)); + + if (selection_data->length < 0 || + selection_data->type != GDK_SELECTION_TYPE_STRING) { + return; + } + + comp_str = (char *) selection_data->data; + icalcomp = icalparser_parse_string ((const char *) comp_str); + if (!icalcomp) + return; + + default_tzid = calendar_config_get_timezone (); + cal_client_get_timezone (cal_view->priv->client, default_tzid, &default_zone); + + /* check the type of the component */ + kind = icalcomponent_isa (icalcomp); + if (kind != ICAL_VCALENDAR_COMPONENT && + kind != ICAL_VEVENT_COMPONENT && + kind != ICAL_VTODO_COMPONENT && + kind != ICAL_VJOURNAL_COMPONENT) { + return; + } + + e_cal_view_set_status_message (cal_view, _("Updating objects")); + e_cal_view_get_selected_time_range (cal_view, &selected_time_start, &selected_time_end); + + if (kind == ICAL_VCALENDAR_COMPONENT) { + icalcomponent_kind child_kind; + icalcomponent *subcomp; + + subcomp = icalcomponent_get_first_component (icalcomp, ICAL_ANY_COMPONENT); + while (subcomp) { + child_kind = icalcomponent_isa (subcomp); + if (child_kind == ICAL_VEVENT_COMPONENT || + child_kind == ICAL_VTODO_COMPONENT || + child_kind == ICAL_VJOURNAL_COMPONENT) { + icalcomponent *new_icalcomp; + + new_icalcomp = icalcomponent_new_clone (subcomp); + comp = cal_component_new (); + + /* change the day for the event */ + tt_start = icaltime_as_timet ( + icalcomponent_get_dtstart (new_icalcomp)); + tt_end = icaltime_as_timet ( + icalcomponent_get_dtend (new_icalcomp)); + ic_dur = icaldurationtype_from_int (tt_end - tt_start); + + tmp_itime = icaltime_from_timet_with_zone ( + selected_time_start, FALSE, default_zone); + itime = icalcomponent_get_dtstart (new_icalcomp); + itime.year = tmp_itime.year; + itime.month = tmp_itime.month; + itime.day = tmp_itime.day; + + cal_component_set_icalcomponent (comp, new_icalcomp); + ccdt.value = &itime; + ccdt.tzid = icaltimezone_get_tzid (default_zone); + cal_component_set_dtstart (comp, &ccdt); + + itime = icaltime_add (itime, ic_dur); + ccdt.value = &itime; + cal_component_set_dtend (comp, &ccdt); + + uid = cal_component_gen_uid (); + cal_component_set_uid (comp, uid); + + cal_client_update_object (cal_view->priv->client, comp); + + g_free (uid); + g_object_unref (comp); + } + subcomp = icalcomponent_get_next_component ( + icalcomp, ICAL_ANY_COMPONENT); + } + + icalcomponent_free (icalcomp); + + } + else { + comp = cal_component_new (); + + /* change the day for the event */ + tt_start = icaltime_as_timet (icalcomponent_get_dtstart (icalcomp)); + tt_end = icaltime_as_timet (icalcomponent_get_dtend (icalcomp)); + ic_dur = icaldurationtype_from_int (tt_end - tt_start); + + tmp_itime = icaltime_from_timet_with_zone ( + selected_time_start, FALSE, default_zone); + itime = icalcomponent_get_dtstart (icalcomp); + itime.year = tmp_itime.year; + itime.month = tmp_itime.month; + itime.day = tmp_itime.day; + + cal_component_set_icalcomponent (comp, icalcomp); + ccdt.value = &itime; + ccdt.tzid = icaltimezone_get_tzid (default_zone); + cal_component_set_dtstart (comp, &ccdt); + + itime = icaltime_add (itime, ic_dur); + ccdt.value = &itime; + cal_component_set_dtend (comp, &ccdt); + + uid = cal_component_gen_uid (); + cal_component_set_uid (comp, (const char *) uid); + + cal_client_update_object (cal_view->priv->client, comp); + + if (itip_organizer_is_user (comp, cal_view->priv->client) && + send_component_dialog (gtk_widget_get_toplevel (cal_view), cal_view->priv->client, comp, TRUE)) + itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp, cal_view->priv->client, NULL); + + g_free (uid); + g_object_unref (comp); + } + + e_cal_view_set_status_message (cal_view, NULL); } static void e_cal_view_init (ECalView *cal_view, ECalViewClass *klass) { cal_view->priv = g_new0 (ECalViewPrivate, 1); + + cal_view->priv->sexp = g_strdup ("#t"); /* match all by default */ + + /* Set up the invisible widget for the clipboard selections */ + cal_view->priv->invisible = gtk_invisible_new (); + gtk_selection_add_target (cal_view->priv->invisible, + clipboard_atom, + GDK_SELECTION_TYPE_STRING, + 0); + g_signal_connect (cal_view->priv->invisible, "selection_get", + G_CALLBACK (selection_get), (gpointer) cal_view); + g_signal_connect (cal_view->priv->invisible, "selection_clear_event", + G_CALLBACK (selection_clear_event), (gpointer) cal_view); + g_signal_connect (cal_view->priv->invisible, "selection_received", + G_CALLBACK (selection_received), (gpointer) cal_view); + + cal_view->priv->clipboard_selection = NULL; } static void @@ -89,11 +299,31 @@ e_cal_view_destroy (GtkObject *object) g_return_if_fail (E_IS_CAL_VIEW (cal_view)); if (cal_view->priv) { + if (cal_view->priv->client) { + g_object_unref (cal_view->priv->client); + cal_view->priv->client = NULL; + } + + if (cal_view->priv->sexp) { + g_free (cal_view->priv->sexp); + cal_view->priv->sexp = NULL; + } + if (cal_view->priv->activity) { g_object_unref (cal_view->priv->activity); cal_view->priv->activity = NULL; } + if (cal_view->priv->invisible) { + gtk_widget_destroy (cal_view->priv->invisible); + cal_view->priv->invisible = NULL; + } + + if (cal_view->priv->clipboard_selection) { + g_free (cal_view->priv->clipboard_selection); + cal_view->priv->clipboard_selection = NULL; + } + g_free (cal_view->priv); cal_view->priv = NULL; } @@ -121,6 +351,72 @@ e_cal_view_set_calendar (ECalView *cal_view, GnomeCalendar *calendar) cal_view->priv->calendar = calendar; } +CalClient * +e_cal_view_get_cal_client (ECalView *cal_view) +{ + g_return_val_if_fail (E_IS_CAL_VIEW (cal_view), NULL); + + return cal_view->priv->client; +} + +static void +cal_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer user_data) +{ + ECalView *cal_view = (ECalView *) user_data; + + if (status != CAL_CLIENT_OPEN_SUCCESS) + return; + + e_cal_view_update_query (cal_view); +} + +void +e_cal_view_set_cal_client (ECalView *cal_view, CalClient *client) +{ + g_return_if_fail (E_IS_CAL_VIEW (cal_view)); + + if (client == cal_view->priv->client) + return; + + if (IS_CAL_CLIENT (client)) + g_object_ref (client); + + if (cal_view->priv->client) { + g_signal_handlers_disconnect_matched (cal_view->priv->client, G_SIGNAL_MATCH_DATA, 0, 0, + NULL, NULL, cal_view); + g_object_unref (cal_view->priv->client); + } + + cal_view->priv->client = client; + if (cal_view->priv->client) { + if (cal_client_get_load_state (cal_view->priv->client) == CAL_CLIENT_LOAD_LOADED) + e_cal_view_update_query (cal_view); + else + g_signal_connect (cal_view->priv->client, "cal_opened", + G_CALLBACK (cal_opened_cb), cal_view); + } +} + +const gchar * +e_cal_view_get_query (ECalView *cal_view) +{ + g_return_val_if_fail (E_IS_CAL_VIEW (cal_view), NULL); + + return (const gchar *) cal_view->priv->sexp; +} + +void +e_cal_view_set_query (ECalView *cal_view, const gchar *sexp) +{ + g_return_if_fail (E_IS_CAL_VIEW (cal_view)); + + if (cal_view->priv->sexp) + g_free (cal_view->priv->sexp); + + cal_view->priv->sexp = g_strdup (sexp); + e_cal_view_update_query (cal_view); +} + void e_cal_view_set_status_message (ECalView *cal_view, const gchar *message) { @@ -147,3 +443,128 @@ e_cal_view_set_status_message (ECalView *cal_view, const gchar *message) } else evolution_activity_client_update (cal_view->priv->activity, message, -1.0); } + +GList * +e_cal_view_get_selected_events (ECalView *cal_view) +{ + g_return_val_if_fail (E_IS_CAL_VIEW (cal_view), NULL); + + if (E_CAL_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->get_selected_events) + return E_CAL_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->get_selected_events (cal_view); + + return NULL; +} + +void +e_cal_view_get_selected_time_range (ECalView *cal_view, time_t *start_time, time_t *end_time) +{ + g_return_if_fail (E_IS_CAL_VIEW (cal_view)); + + if (E_CAL_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->get_selected_time_range) { + E_CAL_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->get_selected_time_range ( + cal_view, start_time, end_time); + } +} + +void +e_cal_view_set_selected_time_range (ECalView *cal_view, time_t start_time, time_t end_time) +{ + g_return_if_fail (E_IS_CAL_VIEW (cal_view)); + + if (E_CAL_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->set_selected_time_range) { + E_CAL_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->set_selected_time_range ( + cal_view, start_time, end_time); + } +} + +void +e_cal_view_update_query (ECalView *cal_view) +{ + g_return_if_fail (E_IS_CAL_VIEW (cal_view)); + + if (E_CAL_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->update_query) { + E_CAL_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->update_query (cal_view); + } +} + +void +e_cal_view_cut_clipboard (ECalView *cal_view) +{ + GList *selected, *l; + const char *uid; + + g_return_if_fail (E_IS_CAL_VIEW (cal_view)); + + selected = e_cal_view_get_selected_events (cal_view); + if (!selected) + return; + + e_cal_view_set_status_message (cal_view, _("Deleting selected objects")); + + e_cal_view_copy_clipboard (cal_view); + for (l = selected; l != NULL; l = l->next) { + CalComponent *comp = l->data; + + if (itip_organizer_is_user (comp, cal_view->priv->client) + && cancel_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (cal_view), + cal_view->priv->client, comp, TRUE)) + itip_send_comp (CAL_COMPONENT_METHOD_CANCEL, comp, cal_view->priv->client, NULL); + + cal_component_get_uid (comp, &uid); + delete_error_dialog (cal_client_remove_object (cal_view->priv->client, uid), + CAL_COMPONENT_EVENT); + } + + e_cal_view_set_status_message (cal_view, NULL); + + g_list_free (selected); +} + +void +e_cal_view_copy_clipboard (ECalView *cal_view) +{ + GList *selected, *l; + gchar *comp_str; + icalcomponent *vcal_comp; + icalcomponent *new_icalcomp; + + g_return_if_fail (E_IS_CAL_VIEW (cal_view)); + + selected = e_cal_view_get_selected_events (cal_view); + if (!selected) + return; + + /* create top-level VCALENDAR component and add VTIMEZONE's */ + vcal_comp = cal_util_new_top_level (); + for (l = selected; l != NULL; l = l->next) + cal_util_add_timezones_from_component (vcal_comp, (CalComponent *) l->data); + + for (l = selected; l != NULL; l = l->next) { + CalComponent *comp = (CalComponent *) l->data; + + new_icalcomp = icalcomponent_new_clone (cal_component_get_icalcomponent (comp)); + icalcomponent_add_component (vcal_comp, new_icalcomp); + } + + /* copy the VCALENDAR to the clipboard */ + comp_str = icalcomponent_as_ical_string (vcal_comp); + if (cal_view->priv->clipboard_selection != NULL) + g_free (cal_view->priv->clipboard_selection); + cal_view->priv->clipboard_selection = g_strdup (comp_str); + gtk_selection_owner_set (cal_view->priv->invisible, clipboard_atom, GDK_CURRENT_TIME); + + /* free memory */ + icalcomponent_free (vcal_comp); + g_list_free (selected); +} + +void +e_cal_view_paste_clipboard (ECalView *cal_view) +{ + g_return_if_fail (E_IS_CAL_VIEW (cal_view)); + + gtk_selection_convert (cal_view->priv->invisible, + clipboard_atom, + GDK_SELECTION_TYPE_STRING, + GDK_CURRENT_TIME); +} -- cgit v1.2.3