aboutsummaryrefslogtreecommitdiffstats
path: root/calendar/gui/e-cal-view.c
diff options
context:
space:
mode:
authorRodrigo Moya <rodrigo@ximian.com>2003-07-23 05:13:38 +0800
committerRodrigo Moya <rodrigo@src.gnome.org>2003-07-23 05:13:38 +0800
commit806e63b32a7fdca4899d89ba236a0eb64726707c (patch)
treeb16e3db0eb30e98b7a700d6854310f3a736c1062 /calendar/gui/e-cal-view.c
parent2c6ab566c91705955a8de51a2937fa97f2a79d91 (diff)
downloadgsoc2013-evolution-806e63b32a7fdca4899d89ba236a0eb64726707c.tar.gz
gsoc2013-evolution-806e63b32a7fdca4899d89ba236a0eb64726707c.tar.zst
gsoc2013-evolution-806e63b32a7fdca4899d89ba236a0eb64726707c.zip
added "get_selected_events", and "update_query" virtual methods.
2003-07-22 Rodrigo Moya <rodrigo@ximian.com> * 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
Diffstat (limited to 'calendar/gui/e-cal-view.c')
-rw-r--r--calendar/gui/e-cal-view.c421
1 files changed, 421 insertions, 0 deletions
diff --git a/calendar/gui/e-cal-view.c b/calendar/gui/e-cal-view.c
index 6272f0eab9..1b4676beb8 100644
--- a/calendar/gui/e-cal-view.c
+++ b/calendar/gui/e-cal-view.c
@@ -22,9 +22,17 @@
*/
#include <config.h>
+#include <string.h>
+#include <gtk/gtkinvisible.h>
+#include <libgnome/gnome-i18n.h>
#include <gal/util/e-util.h>
#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);
+}