aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--calendar/ChangeLog22
-rw-r--r--calendar/gui/e-calendar-table.c215
-rw-r--r--calendar/gui/e-calendar-table.h4
-rw-r--r--calendar/idl/evolution-calendar.idl3
-rw-r--r--calendar/pcs/cal-backend-db.c11
-rw-r--r--calendar/pcs/cal-backend-file.c8
-rw-r--r--calendar/pcs/cal-backend.c26
-rw-r--r--calendar/pcs/cal-backend.h3
-rw-r--r--calendar/pcs/cal.c35
9 files changed, 327 insertions, 0 deletions
diff --git a/calendar/ChangeLog b/calendar/ChangeLog
index 5d97924c80..b4f169e2cd 100644
--- a/calendar/ChangeLog
+++ b/calendar/ChangeLog
@@ -1,3 +1,19 @@
+2001-06-20 Rodrigo Moya <rodrigo@ximian.com>
+
+ * idl/evolution-calendar.idl: added getFreeBusy method
+
+ * pcs/cal.c (impl_Cal_get_free_busy): implementation of the new
+ getFreeBusy added method
+
+ * pcs/cal-backend.[ch]: added new virtual method to the CalBackend
+ class (get_free_busy)
+
+ * pcs/cal-backend-db.c (cal_backend_db_get_free_busy): new function,
+ not implemented yet
+
+ * pcs/cal-backend-file.c (cal_backend_file_get_free_busy): new funtion,
+ not implemented yet
+
2001-06-20 Damon Chaplin <damon@ximian.com>
* gui/calendar-config.[hc]:
@@ -19,6 +35,12 @@
set the "None" item string before adding it to the combo, to stop the
combo putting "None" in the entry initially.
+2001-06-19 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/e-calendar-table.[ch]: added cut/copy/paste support. It works
+ with single selections (a single component selected) and with
+ multiple ones (several components selected)
+
2001-06-19 Damon Chaplin <damon@ximian.com>
* gui/dialogs/event-page.c: if the timezones of the start and end of
diff --git a/calendar/gui/e-calendar-table.c b/calendar/gui/e-calendar-table.c
index d95318cb04..2c862de720 100644
--- a/calendar/gui/e-calendar-table.c
+++ b/calendar/gui/e-calendar-table.c
@@ -32,6 +32,7 @@
#include <sys/stat.h>
#include <unistd.h>
#include <gnome.h>
+#include <gtk/gtkinvisible.h>
#include <gal/e-table/e-cell-checkbox.h>
#include <gal/e-table/e-cell-toggle.h>
#include <gal/e-table/e-cell-text.h>
@@ -67,6 +68,12 @@ static gint e_calendar_table_on_right_click (ETable *table,
ECalendarTable *cal_table);
static void e_calendar_table_on_open_task (GtkWidget *menuitem,
gpointer data);
+static void e_calendar_table_on_cut (GtkWidget *menuitem,
+ gpointer data);
+static void e_calendar_table_on_copy (GtkWidget *menuitem,
+ gpointer data);
+static void e_calendar_table_on_paste (GtkWidget *menuitem,
+ gpointer data);
static gint e_calendar_table_on_key_press (ETable *table,
gint row,
gint col,
@@ -85,6 +92,21 @@ static void e_calendar_table_on_rows_deleted (ETableModel *model,
int count,
ECalendarTable *cal_table);
+static void selection_clear_event (GtkWidget *invisible,
+ GdkEventSelection *event,
+ ECalendarTable *cal_table);
+static void selection_received (GtkWidget *invisible,
+ GtkSelectionData *selection_data,
+ guint time,
+ ECalendarTable *cal_table);
+static void selection_get (GtkWidget *invisible,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time_stamp,
+ ECalendarTable *cal_table);
+static void invisible_destroyed (GtkWidget *invisible,
+ ECalendarTable *cal_table);
+
/* The icons to represent the task. */
#define E_CALENDAR_MODEL_NUM_ICONS 4
@@ -94,6 +116,7 @@ static char** icon_xpm_data[E_CALENDAR_MODEL_NUM_ICONS] = {
static GdkPixbuf* icon_pixbufs[E_CALENDAR_MODEL_NUM_ICONS] = { 0 };
static GtkTableClass *parent_class;
+static GdkAtom clipboard_atom = GDK_NONE;
GtkType
@@ -143,6 +166,10 @@ e_calendar_table_class_init (ECalendarTableClass *class)
widget_class->focus_out_event = e_calendar_table_focus_out;
widget_class->key_press_event = e_calendar_table_key_press;
#endif
+
+ /* clipboard atom */
+ if (!clipboard_atom)
+ clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE);
}
#ifdef JUST_FOR_TRANSLATORS
@@ -463,6 +490,30 @@ e_calendar_table_init (ECalendarTable *cal_table)
gtk_signal_connect (GTK_OBJECT (e_table), "key_press",
GTK_SIGNAL_FUNC (e_calendar_table_on_key_press),
cal_table);
+
+ /* Set up the invisible widget for the clipboard selections */
+ cal_table->invisible = gtk_invisible_new ();
+ gtk_selection_add_target (cal_table->invisible,
+ clipboard_atom,
+ GDK_SELECTION_TYPE_STRING,
+ 0);
+ gtk_signal_connect (GTK_OBJECT (cal_table->invisible),
+ "selection_get",
+ GTK_SIGNAL_FUNC (selection_get),
+ (gpointer) cal_table);
+ gtk_signal_connect (GTK_OBJECT (cal_table->invisible),
+ "selection_clear_event",
+ GTK_SIGNAL_FUNC (selection_clear_event),
+ (gpointer) cal_table);
+ gtk_signal_connect (GTK_OBJECT (cal_table->invisible),
+ "selection_received",
+ GTK_SIGNAL_FUNC (selection_received),
+ (gpointer) cal_table);
+ gtk_signal_connect (GTK_OBJECT (cal_table->invisible),
+ "destroy",
+ GTK_SIGNAL_FUNC (invisible_destroyed),
+ (gpointer) cal_table);
+ cal_table->clipboard_selection = NULL;
}
@@ -514,6 +565,11 @@ e_calendar_table_destroy (GtkObject *object)
gtk_object_unref (GTK_OBJECT (cal_table->subset_model));
cal_table->subset_model = NULL;
+ if (cal_table->invisible)
+ gtk_widget_destroy (cal_table->invisible);
+ if (cal_table->clipboard_selection)
+ g_free (cal_table->clipboard_selection);
+
GTK_OBJECT_CLASS (parent_class)->destroy (object);
}
@@ -735,6 +791,9 @@ delete_cb (GtkWidget *menuitem, gpointer data)
static GnomeUIInfo tasks_popup_one[] = {
GNOMEUIINFO_ITEM_NONE (N_("Edit this task"), NULL, e_calendar_table_on_open_task),
+ GNOMEUIINFO_ITEM_NONE (N_("Cut"), NULL, e_calendar_table_on_cut),
+ GNOMEUIINFO_ITEM_NONE (N_("Copy"), NULL, e_calendar_table_on_copy),
+ GNOMEUIINFO_ITEM_NONE (N_("Paste"), NULL, e_calendar_table_on_paste),
GNOMEUIINFO_SEPARATOR,
GNOMEUIINFO_ITEM_NONE (N_("Mark as complete"), NULL, mark_as_complete_cb),
GNOMEUIINFO_ITEM_NONE (N_("Delete this task"), NULL, delete_cb),
@@ -742,6 +801,10 @@ static GnomeUIInfo tasks_popup_one[] = {
};
static GnomeUIInfo tasks_popup_many[] = {
+ GNOMEUIINFO_ITEM_NONE (N_("Cut"), NULL, e_calendar_table_on_cut),
+ GNOMEUIINFO_ITEM_NONE (N_("Copy"), NULL, e_calendar_table_on_copy),
+ GNOMEUIINFO_ITEM_NONE (N_("Paste"), NULL, e_calendar_table_on_paste),
+ GNOMEUIINFO_SEPARATOR,
GNOMEUIINFO_ITEM_NONE (N_("Mark tasks as complete"), NULL, mark_as_complete_cb),
GNOMEUIINFO_ITEM_NONE (N_("Delete selected tasks"), NULL, delete_cb),
GNOMEUIINFO_END
@@ -785,6 +848,84 @@ e_calendar_table_on_open_task (GtkWidget *menuitem,
open_task (cal_table, comp);
}
+static void
+e_calendar_table_on_cut (GtkWidget *menuitem, gpointer data)
+{
+ ECalendarTable *cal_table;
+
+ cal_table = E_CALENDAR_TABLE (data);
+
+ e_calendar_table_on_copy (menuitem, data);
+ delete_selected_components (cal_table);
+}
+
+static void
+copy_row_cb (int model_row, gpointer data)
+{
+ ECalendarTable *cal_table;
+ CalComponent *comp;
+ gchar *comp_str;
+ icalcomponent *new_comp;
+
+ cal_table = E_CALENDAR_TABLE (data);
+
+ comp = calendar_model_get_component (cal_table->model, model_row);
+ if (!comp)
+ return;
+
+
+ if (cal_table->clipboard_selection) {
+ //new_comp = icalparser_parse_string (cal_table->clipboard_selection);
+ //if (!new_comp)
+ // return;
+
+ //icalcomponent_add_component (new_comp,
+ // cal_component_get_icalcomponent (comp));
+ //g_free (cal_table->clipboard_selection);
+ }
+ else {
+ new_comp = icalparser_parse_string (
+ icalcomponent_as_ical_string (cal_component_get_icalcomponent (comp)));
+ if (!new_comp)
+ return;
+ }
+
+ comp_str = icalcomponent_as_ical_string (new_comp);
+ cal_table->clipboard_selection = g_strdup (comp_str);
+
+ free (comp_str);
+ icalcomponent_free (new_comp);
+}
+
+static void
+e_calendar_table_on_copy (GtkWidget *menuitem, gpointer data)
+{
+ ECalendarTable *cal_table;
+ ETable *etable;
+
+ cal_table = E_CALENDAR_TABLE (data);
+
+ if (cal_table->clipboard_selection) {
+ g_free (cal_table->clipboard_selection);
+ cal_table->clipboard_selection = NULL;
+ }
+
+ etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (cal_table->etable));
+ e_table_selected_row_foreach (etable, copy_row_cb, cal_table);
+
+ gtk_selection_owner_set (cal_table->invisible, clipboard_atom, GDK_CURRENT_TIME);
+}
+
+static void
+e_calendar_table_on_paste (GtkWidget *menuitem, gpointer data)
+{
+ ECalendarTable *cal_table = E_CALENDAR_TABLE (data);
+
+ gtk_selection_convert (cal_table->invisible,
+ clipboard_atom,
+ GDK_SELECTION_TYPE_STRING,
+ GDK_CURRENT_TIME);
+}
static gint
e_calendar_table_on_key_press (ETable *table,
@@ -969,3 +1110,77 @@ e_calendar_table_get_spec (void)
{
return E_CALENDAR_TABLE_SPEC;
}
+
+static void
+invisible_destroyed (GtkWidget *invisible, ECalendarTable *cal_table)
+{
+ cal_table->invisible = NULL;
+}
+
+static void
+selection_get (GtkWidget *invisible,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time_stamp,
+ ECalendarTable *cal_table)
+{
+ if (cal_table->clipboard_selection != NULL) {
+ gtk_selection_data_set (selection_data,
+ GDK_SELECTION_TYPE_STRING,
+ 8,
+ cal_table->clipboard_selection,
+ strlen (cal_table->clipboard_selection));
+ }
+}
+
+static void
+selection_clear_event (GtkWidget *invisible,
+ GdkEventSelection *event,
+ ECalendarTable *cal_table)
+{
+ if (cal_table->clipboard_selection != NULL) {
+ g_free (cal_table->clipboard_selection);
+ cal_table->clipboard_selection = NULL;
+ }
+}
+
+static void
+selection_received (GtkWidget *invisible,
+ GtkSelectionData *selection_data,
+ guint time,
+ ECalendarTable *cal_table)
+{
+ char *comp_str;
+ icalcomponent *icalcomp;
+
+ 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) {
+ icalcomponent *tmp_comp;
+ char *uid;
+
+ /* there can be various components */
+ tmp_comp = icalcomponent_get_first_component (icalcomp, ICAL_ANY_COMPONENT);
+ while (tmp_comp != NULL) {
+ CalComponent *comp;
+
+ comp = cal_component_new ();
+ cal_component_set_icalcomponent (comp, icalcomp);
+ uid = cal_component_gen_uid ();
+ cal_component_set_uid (comp, (const char *) uid);
+ free (uid);
+
+ tmp_comp = icalcomponent_get_next_component (icalcomp, ICAL_ANY_COMPONENT);
+
+ cal_client_update_object (
+ calendar_model_get_cal_client (cal_table->model),
+ comp);
+ gtk_object_unref (GTK_OBJECT (comp));
+ }
+ }
+}
diff --git a/calendar/gui/e-calendar-table.h b/calendar/gui/e-calendar-table.h
index 914a0bcd87..6ca523ac5c 100644
--- a/calendar/gui/e-calendar-table.h
+++ b/calendar/gui/e-calendar-table.h
@@ -83,6 +83,10 @@ struct _ECalendarTable
/* The ECell used to view & edit dates. */
ECellDateEdit *dates_cell;
+
+ /* The invisible widget used for cut/copy/paste */
+ GtkWidget *invisible;
+ gchar *clipboard_selection;
};
struct _ECalendarTableClass
diff --git a/calendar/idl/evolution-calendar.idl b/calendar/idl/evolution-calendar.idl
index ee8f91edcd..d14decca04 100644
--- a/calendar/idl/evolution-calendar.idl
+++ b/calendar/idl/evolution-calendar.idl
@@ -140,6 +140,9 @@ module Calendar {
CalComponentAlarmsSeq getAlarmsInRange (in Time_t start, in Time_t end)
raises (InvalidRange);
+ /* Returns free/busy objects for the given interval */
+ CalObjUIDSeq getFreeBusy (in Time_t start, in Time_t end);
+
/* Gets the alarms for the specified component that trigger in
* the specified time range.
*/
diff --git a/calendar/pcs/cal-backend-db.c b/calendar/pcs/cal-backend-db.c
index d4773760f8..785ba98440 100644
--- a/calendar/pcs/cal-backend-db.c
+++ b/calendar/pcs/cal-backend-db.c
@@ -77,6 +77,9 @@ static GList* cal_backend_db_get_objects_in_range (CalBackend *backend,
CalObjType type,
time_t start,
time_t end);
+static GList *cal_backend_db_get_free_busy (CalBackend *backend,
+ time_t start,
+ time_t end);
static GNOME_Evolution_Calendar_CalObjChangeSeq *cal_backend_db_get_changes (
CalBackend *backend, CalObjType type, const char *change_id);
@@ -157,6 +160,7 @@ cal_backend_db_class_init (CalBackendDBClass *klass)
backend_class->get_type_by_uid = cal_backend_db_get_type_by_uid;
backend_class->get_uids = cal_backend_db_get_uids;
backend_class->get_objects_in_range = cal_backend_db_get_objects_in_range;
+ backend_class->get_free_busy = cal_backend_db_get_free_busy;
backend_class->get_changes = cal_backend_db_get_changes;
backend_class->get_alarms_in_range = cal_backend_db_get_alarms_in_range;
backend_class->get_alarms_for_object = cal_backend_db_get_alarms_for_object;
@@ -934,6 +938,13 @@ cal_backend_db_get_objects_in_range (CalBackend *backend,
return list;
}
+/* get_free_busy handler for the DB backend */
+static GList *
+cal_backend_db_get_free_busy (CalBackend *backend, time_t start, time_t end)
+{
+ return NULL;
+}
+
/* get_changes handler for the DB backend */
static GNOME_Evolution_Calendar_CalObjChangeSeq *
cal_backend_db_get_changes (CalBackend *backend, CalObjType type, const char *change_id)
diff --git a/calendar/pcs/cal-backend-file.c b/calendar/pcs/cal-backend-file.c
index 1267f44e3f..d8951571f8 100644
--- a/calendar/pcs/cal-backend-file.c
+++ b/calendar/pcs/cal-backend-file.c
@@ -77,6 +77,7 @@ static CalObjType cal_backend_file_get_type_by_uid (CalBackend *backend, const c
static GList *cal_backend_file_get_uids (CalBackend *backend, CalObjType type);
static GList *cal_backend_file_get_objects_in_range (CalBackend *backend, CalObjType type,
time_t start, time_t end);
+static GList *cal_backend_file_get_free_busy (CalBackend *backend, time_t start, time_t end);
static GNOME_Evolution_Calendar_CalObjChangeSeq *cal_backend_file_get_changes (
CalBackend *backend, CalObjType type, const char *change_id);
@@ -150,6 +151,7 @@ cal_backend_file_class_init (CalBackendFileClass *class)
backend_class->get_type_by_uid = cal_backend_file_get_type_by_uid;
backend_class->get_uids = cal_backend_file_get_uids;
backend_class->get_objects_in_range = cal_backend_file_get_objects_in_range;
+ backend_class->get_free_busy = cal_backend_file_get_free_busy;
backend_class->get_changes = cal_backend_file_get_changes;
backend_class->get_alarms_in_range = cal_backend_file_get_alarms_in_range;
backend_class->get_alarms_for_object = cal_backend_file_get_alarms_for_object;
@@ -976,6 +978,12 @@ cal_backend_file_get_objects_in_range (CalBackend *backend, CalObjType type,
return event_list;
}
+/* Get_free_busy handler for the file backend */
+static GList *
+cal_backend_file_get_free_busy (CalBackend *backend, time_t start, time_t end)
+{
+ return NULL;
+}
typedef struct
{
diff --git a/calendar/pcs/cal-backend.c b/calendar/pcs/cal-backend.c
index 350e6468e4..d72a6fe5e6 100644
--- a/calendar/pcs/cal-backend.c
+++ b/calendar/pcs/cal-backend.c
@@ -134,11 +134,13 @@ cal_backend_class_init (CalBackendClass *class)
class->get_uri = NULL;
class->add_cal = NULL;
class->open = NULL;
+ class->is_loaded = NULL;
class->get_n_objects = NULL;
class->get_object = NULL;
class->get_type_by_uid = NULL;
class->get_uids = NULL;
class->get_objects_in_range = NULL;
+ class->get_free_busy = NULL;
class->get_changes = NULL;
class->get_alarms_in_range = NULL;
class->get_alarms_for_object = NULL;
@@ -326,6 +328,30 @@ cal_backend_get_objects_in_range (CalBackend *backend, CalObjType type,
}
/**
+ * cal_backend_get_free_busy:
+ * @backend: A calendar backend.
+ * @start: Start time for query.
+ * @end: End time for query.
+ *
+ * Builds a list of unique identifiers corresponding to free/busy calendar
+ * objects of the that occur or recur within the specified time range.
+ *
+ * Return value: A list of UID strings. The list should be freed using the
+ * cal_obj_uid_list_free() function.
+ **/
+GList *
+cal_backend_get_free_busy (CalBackend *backend, time_t start, time_t end)
+{
+ g_return_val_if_fail (backend != NULL, NULL);
+ g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL);
+ g_return_val_if_fail (start != -1 && end != -1, NULL);
+ g_return_val_if_fail (start <= end, NULL);
+
+ g_assert (CLASS (backend)->get_free_busy != NULL);
+ return (* CLASS (backend)->get_free_busy) (backend, start, end);
+}
+
+/**
* cal_backend_get_changes:
* @backend: A calendar backend
* @type: Bitmask with types of objects to return.
diff --git a/calendar/pcs/cal-backend.h b/calendar/pcs/cal-backend.h
index dab06b21e8..35cddaa492 100644
--- a/calendar/pcs/cal-backend.h
+++ b/calendar/pcs/cal-backend.h
@@ -88,6 +88,7 @@ struct _CalBackendClass {
GList *(* get_objects_in_range) (CalBackend *backend, CalObjType type,
time_t start, time_t end);
+ GList *(* get_free_busy) (CalBackend *backend, time_t start, time_t end);
/* Change related virtual methods */
GNOME_Evolution_Calendar_CalObjChangeSeq * (* get_changes) (
@@ -125,6 +126,8 @@ GList *cal_backend_get_uids (CalBackend *backend, CalObjType type);
GList *cal_backend_get_objects_in_range (CalBackend *backend, CalObjType type,
time_t start, time_t end);
+GList *cal_backend_get_free_busy (CalBackend *backend, time_t start, time_t end);
+
GNOME_Evolution_Calendar_CalObjChangeSeq * cal_backend_get_changes (
CalBackend *backend, CalObjType type, const char *change_id);
diff --git a/calendar/pcs/cal.c b/calendar/pcs/cal.c
index 42ccbf3cee..3bcc0c1f6b 100644
--- a/calendar/pcs/cal.c
+++ b/calendar/pcs/cal.c
@@ -227,6 +227,40 @@ impl_Cal_get_objects_in_range (PortableServer_Servant servant,
return seq;
}
+/* Cal::get_free_busy method */
+static GNOME_Evolution_Calendar_CalObjUIDSeq *
+impl_Cal_get_free_busy (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_Time_t start,
+ GNOME_Evolution_Calendar_Time_t end,
+ CORBA_Environment *ev)
+{
+ Cal *cal;
+ CalPrivate *priv;
+ time_t t_start, t_end;
+ GNOME_Evolution_Calendar_CalObjUIDSeq *seq;
+ GList *uids;
+
+ cal = CAL (bonobo_object_from_servant (servant));
+ priv = cal->priv;
+
+ t_start = (time_t) start;
+ t_end = (time_t) end;
+
+ if (t_start > t_end || t_start == -1 || t_end == -1) {
+ CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
+ ex_GNOME_Evolution_Calendar_Cal_InvalidRange,
+ NULL);
+ return NULL;
+ }
+
+ uids = cal_backend_get_free_busy (priv->backend, t_start, t_end);
+ seq = build_uid_seq (uids);
+
+ cal_obj_uid_list_free (uids);
+
+ return seq;
+}
+
/* Cal::get_alarms_in_range method */
static GNOME_Evolution_Calendar_CalComponentAlarmsSeq *
impl_Cal_get_alarms_in_range (PortableServer_Servant servant,
@@ -503,6 +537,7 @@ cal_class_init (CalClass *klass)
epv->getUIDs = impl_Cal_get_uids;
epv->getChanges = impl_Cal_get_changes;
epv->getObjectsInRange = impl_Cal_get_objects_in_range;
+ epv->getFreeBusy = impl_Cal_get_free_busy;
epv->getAlarmsInRange = impl_Cal_get_alarms_in_range;
epv->getAlarmsForObject = impl_Cal_get_alarms_for_object;
epv->updateObject = impl_Cal_update_object;