aboutsummaryrefslogtreecommitdiffstats
path: root/calendar
diff options
context:
space:
mode:
Diffstat (limited to 'calendar')
-rw-r--r--calendar/gui/dialogs/comp-editor.c153
-rw-r--r--calendar/gui/dialogs/comp-editor.h2
-rw-r--r--calendar/gui/e-cal-list-view.h3
-rw-r--r--calendar/gui/e-calendar-table.c540
-rw-r--r--calendar/gui/e-calendar-table.h5
-rw-r--r--calendar/gui/e-calendar-view.c682
-rw-r--r--calendar/gui/e-calendar-view.h3
-rw-r--r--calendar/gui/e-day-view-main-item.c1
-rw-r--r--calendar/gui/e-memo-table.c544
-rw-r--r--calendar/gui/e-memo-table.h5
-rw-r--r--calendar/gui/gnome-cal.h2
-rw-r--r--calendar/gui/goto.c1
-rw-r--r--calendar/gui/print.h1
13 files changed, 1101 insertions, 841 deletions
diff --git a/calendar/gui/dialogs/comp-editor.c b/calendar/gui/dialogs/comp-editor.c
index 18bd574728..21384032d9 100644
--- a/calendar/gui/dialogs/comp-editor.c
+++ b/calendar/gui/dialogs/comp-editor.c
@@ -80,6 +80,9 @@ struct _CompEditorPrivate {
gpointer shell; /* weak pointer */
+ /* EFocusTracker keeps selection actions up-to-date. */
+ EFocusTracker *focus_tracker;
+
/* Each CompEditor window gets its own GtkWindowGroup, so it
* doesn't block the main window or other CompEditor windows. */
GtkWindowGroup *window_group;
@@ -133,6 +136,7 @@ enum {
PROP_CHANGED,
PROP_CLIENT,
PROP_FLAGS,
+ PROP_FOCUS_TRACKER,
PROP_SHELL,
PROP_SUMMARY
};
@@ -149,9 +153,10 @@ static const gchar *ui =
" <menuitem action='close'/>"
" </menu>"
" <menu action='edit-menu'>"
-" <menuitem action='cut'/>"
-" <menuitem action='copy'/>"
-" <menuitem action='paste'/>"
+" <menuitem action='cut-clipboard'/>"
+" <menuitem action='copy-clipboard'/>"
+" <menuitem action='paste-clipboard'/>"
+" <menuitem action='delete-selection'/>"
" <separator/>"
" <menuitem action='select-all'/>"
" </menu>"
@@ -677,36 +682,6 @@ action_close_cb (GtkAction *action,
}
static void
-action_copy_cb (GtkAction *action,
- CompEditor *editor)
-{
- GtkWidget *focus;
-
- focus = gtk_window_get_focus (GTK_WINDOW (editor));
-
- if (GTK_IS_ENTRY (focus))
- gtk_editable_copy_clipboard (GTK_EDITABLE (focus));
-
- if (GTK_IS_TEXT_VIEW (focus))
- g_signal_emit_by_name (focus, "copy-clipboard");
-}
-
-static void
-action_cut_cb (GtkAction *action,
- CompEditor *editor)
-{
- GtkWidget *focus;
-
- focus = gtk_window_get_focus (GTK_WINDOW (editor));
-
- if (GTK_IS_ENTRY (focus))
- gtk_editable_cut_clipboard (GTK_EDITABLE (focus));
-
- if (GTK_IS_TEXT_VIEW (focus))
- g_signal_emit_by_name (focus, "cut-clipboard");
-}
-
-static void
action_help_cb (GtkAction *action,
CompEditor *editor)
{
@@ -714,21 +689,6 @@ action_help_cb (GtkAction *action,
}
static void
-action_paste_cb (GtkAction *action,
- CompEditor *editor)
-{
- GtkWidget *focus;
-
- focus = gtk_window_get_focus (GTK_WINDOW (editor));
-
- if (GTK_IS_ENTRY (focus))
- gtk_editable_paste_clipboard (GTK_EDITABLE (focus));
-
- if (GTK_IS_TEXT_VIEW (focus))
- g_signal_emit_by_name (focus, "paste-clipboard");
-}
-
-static void
action_print_cb (GtkAction *action,
CompEditor *editor)
{
@@ -886,23 +846,6 @@ action_save_cb (GtkAction *action,
}
static void
-action_select_all_cb (GtkAction *action,
- CompEditor *editor)
-{
- GtkWidget *focus;
-
- focus = gtk_window_get_focus (GTK_WINDOW (editor));
-
- if (GTK_IS_ENTRY (focus)) {
- gtk_editable_set_position (GTK_EDITABLE (focus), -1);
- gtk_editable_select_region (GTK_EDITABLE (focus), 0, -1);
- }
-
- if (GTK_IS_TEXT_VIEW (focus))
- g_signal_emit_by_name (focus, "select-all", TRUE);
-}
-
-static void
action_view_categories_cb (GtkToggleAction *action,
CompEditor *editor)
{
@@ -995,19 +938,26 @@ static GtkActionEntry core_entries[] = {
N_("Click here to close the current window"),
G_CALLBACK (action_close_cb) },
- { "copy",
+ { "copy-clipboard",
GTK_STOCK_COPY,
NULL,
NULL,
- N_("Copy selected text to the clipboard"),
- G_CALLBACK (action_copy_cb) },
+ N_("Copy the selection"),
+ NULL }, /* Handled by EFocusTracker */
- { "cut",
+ { "cut-clipboard",
GTK_STOCK_CUT,
NULL,
NULL,
- N_("Cut selected text to the clipboard"),
- G_CALLBACK (action_cut_cb) },
+ N_("Cut the selection"),
+ NULL }, /* Handled by EFocusTracker */
+
+ { "delete-selection",
+ GTK_STOCK_DELETE,
+ NULL,
+ NULL,
+ N_("Delete the selection"),
+ NULL }, /* Handled by EFocusTracker */
{ "help",
GTK_STOCK_HELP,
@@ -1016,12 +966,12 @@ static GtkActionEntry core_entries[] = {
N_("Click here to view help available"),
G_CALLBACK (action_help_cb) },
- { "paste",
+ { "paste-clipboard",
GTK_STOCK_PASTE,
NULL,
NULL,
- N_("Paste text from the clipboard"),
- G_CALLBACK (action_paste_cb) },
+ N_("Paste the clipboard"),
+ NULL }, /* Handled by EFocusTracker */
{ "print",
GTK_STOCK_PRINT,
@@ -1047,9 +997,9 @@ static GtkActionEntry core_entries[] = {
{ "select-all",
GTK_STOCK_SELECT_ALL,
NULL,
- NULL,
+ "<Control>a",
N_("Select all text"),
- G_CALLBACK (action_select_all_cb) },
+ NULL }, /* Handled by EFocusTracker */
/* Menus */
@@ -1302,6 +1252,12 @@ comp_editor_get_property (GObject *object,
COMP_EDITOR (object)));
return;
+ case PROP_FOCUS_TRACKER:
+ g_value_set_object (
+ value, comp_editor_get_focus_tracker (
+ COMP_EDITOR (object)));
+ return;
+
case PROP_SHELL:
g_value_set_object (
value, comp_editor_get_shell (
@@ -1331,6 +1287,11 @@ comp_editor_dispose (GObject *object)
priv->shell = NULL;
}
+ if (priv->focus_tracker != NULL) {
+ g_object_unref (priv->focus_tracker);
+ priv->focus_tracker = NULL;
+ }
+
if (priv->window_group != NULL) {
g_object_unref (priv->window_group);
priv->window_group = NULL;
@@ -1566,6 +1527,16 @@ comp_editor_class_init (CompEditorClass *class)
g_object_class_install_property (
object_class,
+ PROP_FOCUS_TRACKER,
+ g_param_spec_object (
+ "focus-tracker",
+ NULL,
+ NULL,
+ E_TYPE_FOCUS_TRACKER,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (
+ object_class,
PROP_SHELL,
g_param_spec_object (
"shell",
@@ -1601,6 +1572,7 @@ comp_editor_init (CompEditor *editor)
CompEditorPrivate *priv;
EAttachmentView *view;
EAttachmentStore *store;
+ EFocusTracker *focus_tracker;
GdkDragAction drag_actions;
GtkTargetList *target_list;
GtkTargetEntry *targets;
@@ -1684,6 +1656,27 @@ comp_editor_init (CompEditor *editor)
priv->ui_manager, action_group, 0);
g_object_unref (action_group);
+ /* Configure an EFocusTracker to manage selection actions. */
+
+ focus_tracker = e_focus_tracker_new (GTK_WINDOW (editor));
+
+ action = comp_editor_get_action (editor, "cut-clipboard");
+ e_focus_tracker_set_cut_clipboard_action (focus_tracker, action);
+
+ action = comp_editor_get_action (editor, "copy-clipboard");
+ e_focus_tracker_set_copy_clipboard_action (focus_tracker, action);
+
+ action = comp_editor_get_action (editor, "paste-clipboard");
+ e_focus_tracker_set_paste_clipboard_action (focus_tracker, action);
+
+ action = comp_editor_get_action (editor, "delete-selection");
+ e_focus_tracker_set_delete_selection_action (focus_tracker, action);
+
+ action = comp_editor_get_action (editor, "select-all");
+ e_focus_tracker_set_select_all_action (focus_tracker, action);
+
+ priv->focus_tracker = focus_tracker;
+
/* Fine Tuning */
action = comp_editor_get_action (editor, "attach");
@@ -2093,6 +2086,14 @@ comp_editor_get_changed (CompEditor *editor)
return editor->priv->changed;
}
+EFocusTracker *
+comp_editor_get_focus_tracker (CompEditor *editor)
+{
+ g_return_val_if_fail (IS_COMP_EDITOR (editor), NULL);
+
+ return editor->priv->focus_tracker;
+}
+
void
comp_editor_set_flags (CompEditor *editor,
CompEditorFlags flags)
diff --git a/calendar/gui/dialogs/comp-editor.h b/calendar/gui/dialogs/comp-editor.h
index 0b3ea047e7..54672ec3b8 100644
--- a/calendar/gui/dialogs/comp-editor.h
+++ b/calendar/gui/dialogs/comp-editor.h
@@ -30,6 +30,7 @@
#include "../itip-utils.h"
#include "comp-editor-page.h"
#include <shell/e-shell.h>
+#include <misc/e-focus-tracker.h>
/* Standard GObject macros */
#define TYPE_COMP_EDITOR \
@@ -92,6 +93,7 @@ GType comp_editor_get_type (void);
void comp_editor_set_changed (CompEditor *editor,
gboolean changed);
gboolean comp_editor_get_changed (CompEditor *editor);
+EFocusTracker * comp_editor_get_focus_tracker (CompEditor *editor);
void comp_editor_set_needs_send (CompEditor *editor,
gboolean needs_send);
gboolean comp_editor_get_needs_send (CompEditor *editor);
diff --git a/calendar/gui/e-cal-list-view.h b/calendar/gui/e-cal-list-view.h
index 0874b73c5b..faf37bbc9f 100644
--- a/calendar/gui/e-cal-list-view.h
+++ b/calendar/gui/e-cal-list-view.h
@@ -27,6 +27,9 @@
#include <time.h>
#include <gtk/gtk.h>
+#include <table/e-table.h>
+#include <table/e-cell-date-edit.h>
+
#include "e-calendar-view.h"
#include "gnome-cal.h"
diff --git a/calendar/gui/e-calendar-table.c b/calendar/gui/e-calendar-table.c
index a1495fb005..9ac534e333 100644
--- a/calendar/gui/e-calendar-table.c
+++ b/calendar/gui/e-calendar-table.c
@@ -37,6 +37,7 @@
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include <misc/e-gui-utils.h>
+#include <misc/e-selectable.h>
#include <table/e-cell-checkbox.h>
#include <table/e-cell-toggle.h>
#include <table/e-cell-text.h>
@@ -248,6 +249,32 @@ calendar_table_model_cal_view_done_cb (ECalendarTable *cal_table,
calendar_table_emit_status_message (cal_table, NULL, -1.0);
}
+/* Deletes all of the selected components in the table */
+static void
+delete_selected_components (ECalendarTable *cal_table)
+{
+ GSList *objs, *l;
+ const gchar *status_message;
+
+ objs = e_calendar_table_get_selected (cal_table);
+
+ status_message = _("Deleting selected objects");
+ calendar_table_emit_status_message (cal_table, status_message, -1.0);
+
+ for (l = objs; l; l = l->next) {
+ ECalModelComponent *comp_data = (ECalModelComponent *) l->data;
+ GError *error = NULL;
+
+ e_cal_remove_object (comp_data->client,
+ icalcomponent_get_uid (comp_data->icalcomp), &error);
+ delete_error_dialog (error, E_CAL_COMPONENT_TODO);
+ g_clear_error (&error);
+ }
+
+ calendar_table_emit_status_message (cal_table, NULL, -1.0);
+
+ g_slist_free (objs);
+}
static void
calendar_table_set_model (ECalendarTable *cal_table,
ECalModel *model)
@@ -846,6 +873,270 @@ calendar_table_right_click (ETable *table,
}
static void
+calendar_table_update_actions (ESelectable *selectable,
+ EFocusTracker *focus_tracker,
+ GdkAtom *clipboard_targets,
+ gint n_clipboard_targets)
+{
+ ECalendarTable *cal_table;
+ GtkAction *action;
+ GSList *list, *iter;
+ gboolean sources_are_editable = TRUE;
+ gboolean clipboard_has_calendar;
+ gboolean sensitive;
+ const gchar *tooltip;
+ gint n_selected;
+
+ cal_table = E_CALENDAR_TABLE (selectable);
+ n_selected = e_table_selected_count (E_TABLE (cal_table));
+
+ list = e_calendar_table_get_selected (cal_table);
+ for (iter = list; iter != NULL; iter = iter->next) {
+ ECalModelComponent *comp_data = iter->data;
+ gboolean read_only;
+
+ e_cal_is_read_only (comp_data->client, &read_only, NULL);
+ sources_are_editable &= !read_only;
+ }
+ g_slist_free (list);
+
+ clipboard_has_calendar = (clipboard_targets != NULL) &&
+ e_targets_include_calendar (
+ clipboard_targets, n_clipboard_targets);
+
+ action = e_focus_tracker_get_cut_clipboard_action (focus_tracker);
+ sensitive = (n_selected > 0) && sources_are_editable;
+ tooltip = _("Cut selected tasks to the clipboard");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+
+ action = e_focus_tracker_get_copy_clipboard_action (focus_tracker);
+ sensitive = (n_selected > 0);
+ tooltip = _("Copy selected tasks to the clipboard");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+
+ action = e_focus_tracker_get_paste_clipboard_action (focus_tracker);
+ sensitive = sources_are_editable && clipboard_has_calendar;
+ tooltip = _("Paste tasks from the clipboard");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+
+ action = e_focus_tracker_get_select_all_action (focus_tracker);
+ sensitive = TRUE;
+ tooltip = _("Select all visible tasks");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+}
+
+static void
+calendar_table_cut_clipboard (ESelectable *selectable)
+{
+ ECalendarTable *cal_table;
+
+ cal_table = E_CALENDAR_TABLE (selectable);
+
+ e_selectable_copy_clipboard (selectable);
+ delete_selected_components (cal_table);
+}
+
+/* Helper for calendar_table_copy_clipboard() */
+static void
+copy_row_cb (gint model_row, gpointer data)
+{
+ ECalendarTable *cal_table;
+ ECalModelComponent *comp_data;
+ ECalModel *model;
+ gchar *comp_str;
+ icalcomponent *child;
+
+ cal_table = E_CALENDAR_TABLE (data);
+
+ g_return_if_fail (cal_table->tmp_vcal != NULL);
+
+ model = e_calendar_table_get_model (cal_table);
+ comp_data = e_cal_model_get_component_at (model, model_row);
+ if (!comp_data)
+ return;
+
+ /* Add timezones to the VCALENDAR component. */
+ e_cal_util_add_timezones_from_component (
+ cal_table->tmp_vcal, comp_data->icalcomp);
+
+ /* Add the new component to the VCALENDAR component. */
+ comp_str = icalcomponent_as_ical_string_r (comp_data->icalcomp);
+ child = icalparser_parse_string (comp_str);
+ if (child) {
+ icalcomponent_add_component (
+ cal_table->tmp_vcal,
+ icalcomponent_new_clone (child));
+ icalcomponent_free (child);
+ }
+ g_free (comp_str);
+}
+
+static void
+calendar_table_copy_clipboard (ESelectable *selectable)
+{
+ ECalendarTable *cal_table;
+ GtkClipboard *clipboard;
+ gchar *comp_str;
+
+ cal_table = E_CALENDAR_TABLE (selectable);
+
+ /* Create a temporary VCALENDAR object. */
+ cal_table->tmp_vcal = e_cal_util_new_top_level ();
+
+ e_table_selected_row_foreach (
+ E_TABLE (cal_table), copy_row_cb, cal_table);
+ comp_str = icalcomponent_as_ical_string_r (cal_table->tmp_vcal);
+
+ clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+ e_clipboard_set_calendar (clipboard, comp_str, -1);
+ gtk_clipboard_store (clipboard);
+
+ g_free (comp_str);
+
+ icalcomponent_free (cal_table->tmp_vcal);
+ cal_table->tmp_vcal = NULL;
+}
+
+/* Helper for calenable_table_paste_clipboard() */
+static void
+clipboard_get_calendar_data (ECalendarTable *cal_table,
+ const gchar *text)
+{
+ icalcomponent *icalcomp;
+ gchar *uid;
+ ECalComponent *comp;
+ ECalModel *model;
+ ECal *client;
+ icalcomponent_kind kind;
+ const gchar *status_message;
+
+ g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table));
+
+ if (!text || !*text)
+ return;
+
+ icalcomp = icalparser_parse_string (text);
+ if (!icalcomp)
+ return;
+
+ /* 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;
+ }
+
+ model = e_calendar_table_get_model (cal_table);
+ client = e_cal_model_get_default_client (model);
+
+ status_message = _("Updating objects");
+ calendar_table_emit_status_message (cal_table, status_message, -1.0);
+
+ if (kind == ICAL_VCALENDAR_COMPONENT) {
+ icalcomponent_kind child_kind;
+ icalcomponent *subcomp;
+ icalcomponent *vcal_comp;
+
+ vcal_comp = icalcomp;
+ subcomp = icalcomponent_get_first_component (
+ vcal_comp, 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) {
+ ECalComponent *tmp_comp;
+
+ uid = e_cal_component_gen_uid ();
+ tmp_comp = e_cal_component_new ();
+ e_cal_component_set_icalcomponent (
+ tmp_comp,
+ icalcomponent_new_clone (subcomp));
+ e_cal_component_set_uid (tmp_comp, uid);
+ free (uid);
+
+ /* FIXME should we convert start/due/complete
+ * times? Also, need error handling. */
+ e_cal_create_object (
+ client, e_cal_component_get_icalcomponent (tmp_comp),
+ NULL, NULL);
+
+ g_object_unref (tmp_comp);
+ }
+ subcomp = icalcomponent_get_next_component (
+ vcal_comp, ICAL_ANY_COMPONENT);
+ }
+ } else {
+ comp = e_cal_component_new ();
+ e_cal_component_set_icalcomponent (comp, icalcomp);
+ uid = e_cal_component_gen_uid ();
+ e_cal_component_set_uid (comp, (const gchar *) uid);
+ free (uid);
+
+ e_cal_create_object (
+ client, e_cal_component_get_icalcomponent (comp),
+ NULL, NULL);
+
+ g_object_unref (comp);
+ }
+
+ calendar_table_emit_status_message (cal_table, NULL, -1.0);
+}
+
+static void
+calendar_table_paste_clipboard (ESelectable *selectable)
+{
+ ECalendarTable *cal_table;
+ GtkClipboard *clipboard;
+ GnomeCanvasItem *item;
+ GnomeCanvas *table_canvas;
+
+ cal_table = E_CALENDAR_TABLE (selectable);
+
+ clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+
+ table_canvas = E_TABLE (cal_table)->table_canvas;
+ item = table_canvas->focused_item;
+
+ /* XXX Should ECellText implement GtkEditable? */
+
+ /* Paste text into a cell being edited. */
+ if (gtk_clipboard_wait_is_text_available (clipboard) &&
+ GTK_WIDGET_HAS_FOCUS (table_canvas) &&
+ E_IS_TABLE_ITEM (item) &&
+ E_TABLE_ITEM (item)->editing_col >= 0 &&
+ E_TABLE_ITEM (item)->editing_row >= 0) {
+
+ ETableItem *etable_item = E_TABLE_ITEM (item);
+
+ e_cell_text_paste_clipboard (
+ etable_item->cell_views[etable_item->editing_col],
+ etable_item->editing_col,
+ etable_item->editing_row);
+
+ /* Paste iCalendar data into the table. */
+ } else if (e_clipboard_wait_is_calendar_available (clipboard)) {
+ gchar *calendar_source;
+
+ calendar_source = e_clipboard_wait_for_calendar (clipboard);
+ clipboard_get_calendar_data (cal_table, calendar_source);
+ g_free (calendar_source);
+ }
+}
+
+static void
+calendar_table_select_all (ESelectable *selectable)
+{
+ e_table_select_all (E_TABLE (selectable));
+}
+
+static void
calendar_table_class_init (ECalendarTableClass *class)
{
GObjectClass *object_class;
@@ -937,6 +1228,16 @@ calendar_table_init (ECalendarTable *cal_table)
cal_table->priv = E_CALENDAR_TABLE_GET_PRIVATE (cal_table);
}
+static void
+calendar_table_selectable_init (ESelectableInterface *interface)
+{
+ interface->update_actions = calendar_table_update_actions;
+ interface->cut_clipboard = calendar_table_cut_clipboard;
+ interface->copy_clipboard = calendar_table_copy_clipboard;
+ interface->paste_clipboard = calendar_table_paste_clipboard;
+ interface->select_all = calendar_table_select_all;
+}
+
GType
e_calendar_table_get_type (void)
{
@@ -956,8 +1257,17 @@ e_calendar_table_get_type (void)
NULL /* value_table */
};
+ static const GInterfaceInfo selectable_info = {
+ (GInterfaceInitFunc) calendar_table_selectable_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL /* interface_data */
+ };
+
type = g_type_register_static (
E_TABLE_TYPE, "ECalendarTable", &type_info, 0);
+
+ g_type_add_interface_static (
+ type, E_TYPE_SELECTABLE, &selectable_info);
}
return type;
@@ -1061,32 +1371,6 @@ add_uid_cb (gint model_row, gpointer data)
closure->objects = g_slist_prepend (closure->objects, comp_data);
}
-/* Deletes all of the selected components in the table */
-static void
-delete_selected_components (ECalendarTable *cal_table)
-{
- GSList *objs, *l;
- const gchar *status_message;
-
- objs = e_calendar_table_get_selected (cal_table);
-
- status_message = _("Deleting selected objects");
- calendar_table_emit_status_message (cal_table, status_message, -1.0);
-
- for (l = objs; l; l = l->next) {
- ECalModelComponent *comp_data = (ECalModelComponent *) l->data;
- GError *error = NULL;
-
- e_cal_remove_object (comp_data->client,
- icalcomponent_get_uid (comp_data->icalcomp), &error);
- delete_error_dialog (error, E_CAL_COMPONENT_TODO);
- g_clear_error (&error);
- }
-
- calendar_table_emit_status_message (cal_table, NULL, -1.0);
-
- g_slist_free (objs);
-}
static void
add_retract_data (ECalComponent *comp, const gchar *retract_comment)
{
@@ -1223,210 +1507,6 @@ e_calendar_table_get_selected (ECalendarTable *cal_table)
return closure.objects;
}
-/**
- * e_calendar_table_cut_clipboard:
- * @cal_table: A calendar table.
- *
- * Cuts selected tasks in the given calendar table
- */
-void
-e_calendar_table_cut_clipboard (ECalendarTable *cal_table)
-{
- g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table));
-
- e_calendar_table_copy_clipboard (cal_table);
- delete_selected_components (cal_table);
-}
-
-/* callback for e_table_selected_row_foreach */
-static void
-copy_row_cb (gint model_row, gpointer data)
-{
- ECalendarTable *cal_table;
- ECalModelComponent *comp_data;
- ECalModel *model;
- gchar *comp_str;
- icalcomponent *child;
-
- cal_table = E_CALENDAR_TABLE (data);
-
- g_return_if_fail (cal_table->tmp_vcal != NULL);
-
- model = e_calendar_table_get_model (cal_table);
- comp_data = e_cal_model_get_component_at (model, model_row);
- if (!comp_data)
- return;
-
- /* add timezones to the VCALENDAR component */
- e_cal_util_add_timezones_from_component (cal_table->tmp_vcal, comp_data->icalcomp);
-
- /* add the new component to the VCALENDAR component */
- comp_str = icalcomponent_as_ical_string_r (comp_data->icalcomp);
- child = icalparser_parse_string (comp_str);
- if (child) {
- icalcomponent_add_component (cal_table->tmp_vcal,
- icalcomponent_new_clone (child));
- icalcomponent_free (child);
- }
- g_free (comp_str);
-}
-
-/**
- * e_calendar_table_copy_clipboard:
- * @cal_table: A calendar table.
- *
- * Copies selected tasks into the clipboard
- */
-void
-e_calendar_table_copy_clipboard (ECalendarTable *cal_table)
-{
- GtkClipboard *clipboard;
- gchar *comp_str;
-
- g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table));
-
- /* create temporary VCALENDAR object */
- cal_table->tmp_vcal = e_cal_util_new_top_level ();
-
- e_table_selected_row_foreach (
- E_TABLE (cal_table), copy_row_cb, cal_table);
- comp_str = icalcomponent_as_ical_string_r (cal_table->tmp_vcal);
-
- clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
- e_clipboard_set_calendar (clipboard, comp_str, -1);
- gtk_clipboard_store (clipboard);
-
- /* free memory */
- icalcomponent_free (cal_table->tmp_vcal);
- g_free (comp_str);
- cal_table->tmp_vcal = NULL;
-}
-
-static void
-clipboard_get_calendar_data (ECalendarTable *cal_table, const gchar *text)
-{
- icalcomponent *icalcomp;
- gchar *uid;
- ECalComponent *comp;
- ECalModel *model;
- ECal *client;
- icalcomponent_kind kind;
- const gchar *status_message;
-
- g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table));
-
- if (!text || !*text)
- return;
-
- icalcomp = icalparser_parse_string (text);
- if (!icalcomp)
- return;
-
- /* 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;
- }
-
- model = e_calendar_table_get_model (cal_table);
- client = e_cal_model_get_default_client (model);
-
- status_message = _("Updating objects");
- calendar_table_emit_status_message (cal_table, status_message, -1.0);
-
- if (kind == ICAL_VCALENDAR_COMPONENT) {
- icalcomponent_kind child_kind;
- icalcomponent *subcomp;
- icalcomponent *vcal_comp;
-
- vcal_comp = icalcomp;
- subcomp = icalcomponent_get_first_component (
- vcal_comp, 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) {
- ECalComponent *tmp_comp;
-
- uid = e_cal_component_gen_uid ();
- tmp_comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (
- tmp_comp, icalcomponent_new_clone (subcomp));
- e_cal_component_set_uid (tmp_comp, uid);
- free (uid);
-
- /* FIXME should we convert start/due/complete times? */
- /* FIXME Error handling */
- e_cal_create_object (client, e_cal_component_get_icalcomponent (tmp_comp), NULL, NULL);
-
- g_object_unref (tmp_comp);
- }
- subcomp = icalcomponent_get_next_component (
- vcal_comp, ICAL_ANY_COMPONENT);
- }
- } else {
- comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (comp, icalcomp);
- uid = e_cal_component_gen_uid ();
- e_cal_component_set_uid (comp, (const gchar *) uid);
- free (uid);
-
- e_cal_create_object (client, e_cal_component_get_icalcomponent (comp), NULL, NULL);
-
- g_object_unref (comp);
- }
-
- calendar_table_emit_status_message (cal_table, NULL, -1.0);
-}
-
-/**
- * e_calendar_table_paste_clipboard:
- * @cal_table: A calendar table.
- *
- * Pastes tasks currently in the clipboard into the given calendar table
- */
-void
-e_calendar_table_paste_clipboard (ECalendarTable *cal_table)
-{
- GtkClipboard *clipboard;
- GnomeCanvasItem *item;
- GnomeCanvas *table_canvas;
-
- g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table));
-
- clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
-
- table_canvas = E_TABLE (cal_table)->table_canvas;
- item = table_canvas->focused_item;
-
- /* Paste text into a cell being edited. */
- if (gtk_clipboard_wait_is_text_available (clipboard) &&
- GTK_WIDGET_HAS_FOCUS (table_canvas) &&
- E_IS_TABLE_ITEM (item) &&
- E_TABLE_ITEM (item)->editing_col >= 0 &&
- E_TABLE_ITEM (item)->editing_row >= 0) {
-
- ETableItem *etable_item = E_TABLE_ITEM (item);
-
- e_cell_text_paste_clipboard (
- etable_item->cell_views[etable_item->editing_col],
- etable_item->editing_col,
- etable_item->editing_row);
-
- /* Paste iCalendar data into the table. */
- } else if (e_clipboard_wait_is_calendar_available (clipboard)) {
- gchar *calendar_source;
-
- calendar_source = e_clipboard_wait_for_calendar (clipboard);
- clipboard_get_calendar_data (cal_table, calendar_source);
- g_free (calendar_source);
- }
-}
-
static void
hide_completed_rows (ECalModel *model, GList *clients_list, gchar *hide_sexp, GPtrArray *comp_objects)
{
diff --git a/calendar/gui/e-calendar-table.h b/calendar/gui/e-calendar-table.h
index aa98aee7fa..71c7b716f2 100644
--- a/calendar/gui/e-calendar-table.h
+++ b/calendar/gui/e-calendar-table.h
@@ -92,11 +92,6 @@ EShellView * e_calendar_table_get_shell_view (ECalendarTable *cal_table);
void e_calendar_table_delete_selected(ECalendarTable *cal_table);
GSList * e_calendar_table_get_selected (ECalendarTable *cal_table);
-/* Clipboard related functions */
-void e_calendar_table_cut_clipboard (ECalendarTable *cal_table);
-void e_calendar_table_copy_clipboard (ECalendarTable *cal_table);
-void e_calendar_table_paste_clipboard(ECalendarTable *cal_table);
-
ECalModelComponent *
e_calendar_table_get_selected_comp
(ECalendarTable *cal_table);
diff --git a/calendar/gui/e-calendar-view.c b/calendar/gui/e-calendar-view.c
index f23088af83..5c04c7848b 100644
--- a/calendar/gui/e-calendar-view.c
+++ b/calendar/gui/e-calendar-view.c
@@ -39,6 +39,7 @@
#include <e-util/e-icon-factory.h>
#include <libecal/e-cal-time-util.h>
#include <libecal/e-cal-component.h>
+#include <misc/e-selectable.h>
#include <shell/e-shell.h>
#include "common/authentication.h"
@@ -94,10 +95,9 @@ enum {
LAST_SIGNAL
};
+static gpointer parent_class;
static guint signals[LAST_SIGNAL];
-G_DEFINE_TYPE (ECalendarView, e_calendar_view, GTK_TYPE_TABLE)
-
static void
calendar_view_set_model (ECalendarView *calendar_view,
ECalModel *model)
@@ -158,7 +158,7 @@ calendar_view_dispose (GObject *object)
}
/* Chain up to parent's dispose() method. */
- G_OBJECT_CLASS (e_calendar_view_parent_class)->dispose (object);
+ G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
@@ -171,11 +171,352 @@ calendar_view_finalize (GObject *object)
g_free (priv->default_category);
/* Chain up to parent's finalize() method. */
- G_OBJECT_CLASS (e_calendar_view_parent_class)->finalize (object);
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+calendar_view_update_actions (ESelectable *selectable,
+ EFocusTracker *focus_tracker,
+ GdkAtom *clipboard_targets,
+ gint n_clipboard_targets)
+{
+ ECalendarView *view;
+ GtkAction *action;
+ GList *list, *iter;
+ gboolean sources_are_editable = TRUE;
+ gboolean clipboard_has_calendar;
+ gboolean sensitive;
+ const gchar *tooltip;
+ gint n_selected;
+
+ view = E_CALENDAR_VIEW (selectable);
+
+ list = e_calendar_view_get_selected_events (view);
+ n_selected = g_list_length (list);
+
+ for (iter = list; iter != NULL; iter = iter->next) {
+ ECalendarViewEvent *event = iter->data;
+ gboolean read_only;
+
+ if (event == NULL || event->comp_data == NULL)
+ continue;
+
+ e_cal_is_read_only (event->comp_data->client, &read_only, NULL);
+ sources_are_editable &= !read_only;
+ }
+
+ g_list_free (list);
+
+ clipboard_has_calendar = (clipboard_targets != NULL) &&
+ e_targets_include_calendar (
+ clipboard_targets, n_clipboard_targets);
+
+ action = e_focus_tracker_get_cut_clipboard_action (focus_tracker);
+ sensitive = (n_selected > 0) && sources_are_editable;
+ tooltip = _("Cut selected events to the clipboard");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+
+ action = e_focus_tracker_get_copy_clipboard_action (focus_tracker);
+ sensitive = (n_selected > 0);
+ tooltip = _("Copy selected events to the clipboard");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+
+ action = e_focus_tracker_get_paste_clipboard_action (focus_tracker);
+ sensitive = sources_are_editable && clipboard_has_calendar;
+ tooltip = _("Paste events from the clipboard");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+}
+
+static void
+calendar_view_cut_clipboard (ESelectable *selectable)
+{
+ ECalendarView *cal_view;
+ GList *selected, *l;
+ const gchar *uid;
+
+ cal_view = E_CALENDAR_VIEW (selectable);
+
+ selected = e_calendar_view_get_selected_events (cal_view);
+ if (!selected)
+ return;
+
+#if 0 /* KILL-BONOBO */
+ e_calendar_view_set_status_message (cal_view, _("Deleting selected objects"), -1);
+#endif
+
+ e_selectable_copy_clipboard (selectable);
+
+ for (l = selected; l != NULL; l = l->next) {
+ ECalComponent *comp;
+ ECalendarViewEvent *event = (ECalendarViewEvent *) l->data;
+ GError *error = NULL;
+
+ if (!event)
+ continue;
+
+ comp = e_cal_component_new ();
+ e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp));
+
+ if ((itip_organizer_is_user (comp, event->comp_data->client) || itip_sentby_is_user (comp, event->comp_data->client))
+ && cancel_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)),
+ event->comp_data->client, comp, TRUE))
+ itip_send_comp (E_CAL_COMPONENT_METHOD_CANCEL, comp,
+ event->comp_data->client, NULL, NULL, NULL, TRUE, FALSE);
+
+ e_cal_component_get_uid (comp, &uid);
+ if (e_cal_component_is_instance (comp)) {
+ gchar *rid = NULL;
+ icalcomponent *icalcomp;
+
+ /* when cutting detached instances, only cut that instance */
+ rid = e_cal_component_get_recurid_as_string (comp);
+ if (e_cal_get_object (event->comp_data->client, uid, rid, &icalcomp, NULL)) {
+ e_cal_remove_object_with_mod (event->comp_data->client, uid,
+ rid, CALOBJ_MOD_THIS,
+ &error);
+ icalcomponent_free (icalcomp);
+ } else
+ e_cal_remove_object_with_mod (event->comp_data->client, uid, NULL,
+ CALOBJ_MOD_ALL, &error);
+ g_free (rid);
+ } else
+ e_cal_remove_object (event->comp_data->client, uid, &error);
+ delete_error_dialog (error, E_CAL_COMPONENT_EVENT);
+
+ g_clear_error (&error);
+
+ g_object_unref (comp);
+ }
+
+#if 0 /* KILL-BONOBO */
+ e_calendar_view_set_status_message (cal_view, NULL, -1);
+#endif
+
+ g_list_free (selected);
+}
+
+static void
+add_related_timezones (icalcomponent *des_icalcomp, icalcomponent *src_icalcomp, ECal *client)
+{
+ icalproperty_kind look_in[] = {
+ ICAL_DTSTART_PROPERTY,
+ ICAL_DTEND_PROPERTY,
+ ICAL_NO_PROPERTY
+ };
+ gint i;
+
+ g_return_if_fail (des_icalcomp != NULL);
+ g_return_if_fail (src_icalcomp != NULL);
+ g_return_if_fail (client != NULL);
+
+ for (i = 0; look_in[i] != ICAL_NO_PROPERTY; i++) {
+ icalproperty *prop = icalcomponent_get_first_property (src_icalcomp, look_in[i]);
+
+ if (prop) {
+ icalparameter *par = icalproperty_get_first_parameter (prop, ICAL_TZID_PARAMETER);
+
+ if (par) {
+ const gchar *tzid = icalparameter_get_tzid (par);
+
+ if (tzid) {
+ GError *error = NULL;
+ icaltimezone *zone = NULL;
+
+ if (!e_cal_get_timezone (client, tzid, &zone, &error)) {
+ g_warning ("%s: Cannot get timezone for '%s'. %s", G_STRFUNC, tzid, error ? error->message : "");
+ if (error)
+ g_error_free (error);
+ } else if (zone &&
+ icalcomponent_get_timezone (des_icalcomp, icaltimezone_get_tzid (zone)) == NULL) {
+ /* do not duplicate timezones in the component */
+ icalcomponent *vtz_comp;
+
+ vtz_comp = icaltimezone_get_component (zone);
+ if (vtz_comp)
+ icalcomponent_add_component (des_icalcomp, icalcomponent_new_clone (vtz_comp));
+ }
+ }
+ }
+ }
+ }
+}
+
+static void
+calendar_view_copy_clipboard (ESelectable *selectable)
+{
+ ECalendarView *cal_view;
+ GList *selected, *l;
+ gchar *comp_str;
+ icalcomponent *vcal_comp;
+ icalcomponent *new_icalcomp;
+ ECalendarViewEvent *event;
+ GtkClipboard *clipboard;
+
+ cal_view = E_CALENDAR_VIEW (selectable);
+
+ selected = e_calendar_view_get_selected_events (cal_view);
+ if (!selected)
+ return;
+
+ /* create top-level VCALENDAR component and add VTIMEZONE's */
+ vcal_comp = e_cal_util_new_top_level ();
+ for (l = selected; l != NULL; l = l->next) {
+ event = (ECalendarViewEvent *) l->data;
+
+ if (event) {
+ e_cal_util_add_timezones_from_component (vcal_comp, event->comp_data->icalcomp);
+
+ add_related_timezones (vcal_comp, event->comp_data->icalcomp, event->comp_data->client);
+ }
+ }
+
+ for (l = selected; l != NULL; l = l->next) {
+ event = (ECalendarViewEvent *) l->data;
+
+ new_icalcomp = icalcomponent_new_clone (event->comp_data->icalcomp);
+
+ /* remove RECURRENCE-IDs from copied objects */
+ if (e_cal_util_component_is_instance (new_icalcomp)) {
+ icalproperty *prop;
+
+ prop = icalcomponent_get_first_property (new_icalcomp, ICAL_RECURRENCEID_PROPERTY);
+ if (prop)
+ icalcomponent_remove_property (new_icalcomp, prop);
+ }
+ icalcomponent_add_component (vcal_comp, new_icalcomp);
+ }
+
+ comp_str = icalcomponent_as_ical_string_r (vcal_comp);
+
+ /* copy the VCALENDAR to the clipboard */
+ clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+ e_clipboard_set_calendar (clipboard, comp_str, -1);
+ gtk_clipboard_store (clipboard);
+
+ /* free memory */
+ icalcomponent_free (vcal_comp);
+ g_free (comp_str);
+ g_list_free (selected);
+}
+
+static void
+clipboard_get_calendar_data (ECalendarView *cal_view,
+ const gchar *text)
+{
+ icalcomponent *icalcomp;
+ icalcomponent_kind kind;
+ time_t selected_time_start, selected_time_end;
+ icaltimezone *default_zone;
+ ECal *client;
+ gboolean in_top_canvas;
+
+ g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view));
+
+ if (!text || !*text)
+ return;
+
+ icalcomp = icalparser_parse_string ((const gchar *) text);
+ if (!icalcomp)
+ return;
+
+ default_zone = calendar_config_get_icaltimezone ();
+ client = e_cal_model_get_default_client (cal_view->priv->model);
+
+ /* check the type of the component */
+ /* FIXME An error dialog if we return? */
+ kind = icalcomponent_isa (icalcomp);
+ if (kind != ICAL_VCALENDAR_COMPONENT && kind != ICAL_VEVENT_COMPONENT)
+ return;
+
+#if 0 /* KILL-BONOBO */
+ e_calendar_view_set_status_message (cal_view, _("Updating objects"), -1);
+#endif
+ e_calendar_view_get_selected_time_range (cal_view, &selected_time_start, &selected_time_end);
+
+ if ((selected_time_end - selected_time_start) == 60 * 60 * 24)
+ in_top_canvas = TRUE;
+ else
+ in_top_canvas = FALSE;
+
+ if (kind == ICAL_VCALENDAR_COMPONENT) {
+ icalcomponent *subcomp;
+
+ /* add timezones first, to have them ready */
+ for (subcomp = icalcomponent_get_first_component (icalcomp, ICAL_VTIMEZONE_COMPONENT);
+ subcomp;
+ subcomp = icalcomponent_get_next_component (icalcomp, ICAL_VTIMEZONE_COMPONENT)) {
+ icaltimezone *zone;
+ GError *error = NULL;
+
+ zone = icaltimezone_new ();
+ icaltimezone_set_component (zone, subcomp);
+ if (!e_cal_add_timezone (client, zone, &error)) {
+ icalproperty *tzidprop = icalcomponent_get_first_property (subcomp, ICAL_TZID_PROPERTY);
+
+ g_warning ("%s: Add zone '%s' failed. %s", G_STRFUNC, tzidprop ? icalproperty_get_tzid (tzidprop) : "???", error ? error->message : "");
+ if (error)
+ g_error_free (error);
+ }
+
+ icaltimezone_free (zone, 1);
+ }
+
+ for (subcomp = icalcomponent_get_first_component (icalcomp, ICAL_VEVENT_COMPONENT);
+ subcomp;
+ subcomp = icalcomponent_get_next_component (icalcomp, ICAL_VEVENT_COMPONENT)) {
+ if (e_cal_util_component_has_recurrences (subcomp)) {
+ icalproperty *icalprop = icalcomponent_get_first_property (subcomp, ICAL_RRULE_PROPERTY);
+ if (icalprop)
+ icalproperty_remove_parameter_by_name (icalprop, "X-EVOLUTION-ENDDATE");
+ }
+
+ e_calendar_view_add_event (cal_view, client, selected_time_start, default_zone, subcomp, in_top_canvas);
+ }
+
+ icalcomponent_free (icalcomp);
+ } else {
+ e_calendar_view_add_event (cal_view, client, selected_time_start, default_zone, icalcomp, in_top_canvas);
+ }
+
+#if 0 /* KILL-BONOBO */
+ e_calendar_view_set_status_message (cal_view, NULL, -1);
+#endif
+}
+
+static void
+calendar_view_paste_clipboard (ESelectable *selectable)
+{
+ ECalendarView *cal_view;
+ GtkClipboard *clipboard;
+
+ cal_view = E_CALENDAR_VIEW (selectable);
+
+ clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+
+ /* Paste text into an event being edited. */
+ if (gtk_clipboard_wait_is_text_available (clipboard)) {
+ ECalendarViewClass *class;
+
+ class = E_CALENDAR_VIEW_GET_CLASS (cal_view);
+ g_return_if_fail (class->paste_text != NULL);
+
+ class->paste_text (cal_view);
+
+ /* Paste iCalendar data into the view. */
+ } else if (e_clipboard_wait_is_calendar_available (clipboard)) {
+ gchar *calendar_source;
+
+ calendar_source = e_clipboard_wait_for_calendar (clipboard);
+ clipboard_get_calendar_data (cal_view, calendar_source);
+ g_free (calendar_source);
+ }
}
static void
-e_calendar_view_class_init (ECalendarViewClass *class)
+calendar_view_class_init (ECalendarViewClass *class)
{
GObjectClass *object_class;
GtkBindingSet *binding_set;
@@ -290,9 +631,7 @@ e_calendar_view_class_init (ECalendarViewClass *class)
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
- /*
- * Key bindings
- */
+ /* Key bindings */
binding_set = gtk_binding_set_by_class (class);
@@ -304,11 +643,56 @@ e_calendar_view_class_init (ECalendarViewClass *class)
}
static void
-e_calendar_view_init (ECalendarView *calendar_view)
+calendar_view_init (ECalendarView *calendar_view)
{
calendar_view->priv = E_CALENDAR_VIEW_GET_PRIVATE (calendar_view);
}
+static void
+calendar_view_selectable_init (ESelectableInterface *interface)
+{
+ interface->update_actions = calendar_view_update_actions;
+ interface->cut_clipboard = calendar_view_cut_clipboard;
+ interface->copy_clipboard = calendar_view_copy_clipboard;
+ interface->paste_clipboard = calendar_view_paste_clipboard;
+}
+
+GType
+e_calendar_view_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (ECalendarViewClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) calendar_view_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (ECalendarView),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) calendar_view_init,
+ NULL /* value_table */
+ };
+
+ static const GInterfaceInfo selectable_info = {
+ (GInterfaceInitFunc) calendar_view_selectable_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL /* interface_data */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_TABLE, "ECalendarView", &type_info,
+ G_TYPE_FLAG_ABSTRACT);
+
+ g_type_add_interface_static (
+ type, E_TYPE_SELECTABLE, &selectable_info);
+ }
+
+ return type;
+}
+
void
e_calendar_view_popup_event (ECalendarView *calendar_view,
GdkEventButton *event)
@@ -586,286 +970,6 @@ e_calendar_view_update_query (ECalendarView *cal_view)
class->update_query (cal_view);
}
-void
-e_calendar_view_cut_clipboard (ECalendarView *cal_view)
-{
- GList *selected, *l;
- const gchar *uid;
-
- g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view));
-
- selected = e_calendar_view_get_selected_events (cal_view);
- if (!selected)
- return;
-
-#if 0 /* KILL-BONOBO */
- e_calendar_view_set_status_message (cal_view, _("Deleting selected objects"), -1);
-#endif
-
- e_calendar_view_copy_clipboard (cal_view);
- for (l = selected; l != NULL; l = l->next) {
- ECalComponent *comp;
- ECalendarViewEvent *event = (ECalendarViewEvent *) l->data;
- GError *error = NULL;
-
- if (!event)
- continue;
-
- comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp));
-
- if ((itip_organizer_is_user (comp, event->comp_data->client) || itip_sentby_is_user (comp, event->comp_data->client))
- && cancel_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)),
- event->comp_data->client, comp, TRUE))
- itip_send_comp (E_CAL_COMPONENT_METHOD_CANCEL, comp,
- event->comp_data->client, NULL, NULL, NULL, TRUE, FALSE);
-
- e_cal_component_get_uid (comp, &uid);
- if (e_cal_component_is_instance (comp)) {
- gchar *rid = NULL;
- icalcomponent *icalcomp;
-
- /* when cutting detached instances, only cut that instance */
- rid = e_cal_component_get_recurid_as_string (comp);
- if (e_cal_get_object (event->comp_data->client, uid, rid, &icalcomp, NULL)) {
- e_cal_remove_object_with_mod (event->comp_data->client, uid,
- rid, CALOBJ_MOD_THIS,
- &error);
- icalcomponent_free (icalcomp);
- } else
- e_cal_remove_object_with_mod (event->comp_data->client, uid, NULL,
- CALOBJ_MOD_ALL, &error);
- g_free (rid);
- } else
- e_cal_remove_object (event->comp_data->client, uid, &error);
- delete_error_dialog (error, E_CAL_COMPONENT_EVENT);
-
- g_clear_error (&error);
-
- g_object_unref (comp);
- }
-
-#if 0 /* KILL-BONOBO */
- e_calendar_view_set_status_message (cal_view, NULL, -1);
-#endif
-
- g_list_free (selected);
-}
-
-static void
-add_related_timezones (icalcomponent *des_icalcomp, icalcomponent *src_icalcomp, ECal *client)
-{
- icalproperty_kind look_in[] = {
- ICAL_DTSTART_PROPERTY,
- ICAL_DTEND_PROPERTY,
- ICAL_NO_PROPERTY
- };
- gint i;
-
- g_return_if_fail (des_icalcomp != NULL);
- g_return_if_fail (src_icalcomp != NULL);
- g_return_if_fail (client != NULL);
-
- for (i = 0; look_in[i] != ICAL_NO_PROPERTY; i++) {
- icalproperty *prop = icalcomponent_get_first_property (src_icalcomp, look_in[i]);
-
- if (prop) {
- icalparameter *par = icalproperty_get_first_parameter (prop, ICAL_TZID_PARAMETER);
-
- if (par) {
- const gchar *tzid = icalparameter_get_tzid (par);
-
- if (tzid) {
- GError *error = NULL;
- icaltimezone *zone = NULL;
-
- if (!e_cal_get_timezone (client, tzid, &zone, &error)) {
- g_warning ("%s: Cannot get timezone for '%s'. %s", G_STRFUNC, tzid, error ? error->message : "");
- if (error)
- g_error_free (error);
- } else if (zone &&
- icalcomponent_get_timezone (des_icalcomp, icaltimezone_get_tzid (zone)) == NULL) {
- /* do not duplicate timezones in the component */
- icalcomponent *vtz_comp;
-
- vtz_comp = icaltimezone_get_component (zone);
- if (vtz_comp)
- icalcomponent_add_component (des_icalcomp, icalcomponent_new_clone (vtz_comp));
- }
- }
- }
- }
- }
-}
-
-void
-e_calendar_view_copy_clipboard (ECalendarView *cal_view)
-{
- GList *selected, *l;
- gchar *comp_str;
- icalcomponent *vcal_comp;
- icalcomponent *new_icalcomp;
- ECalendarViewEvent *event;
- GtkClipboard *clipboard;
-
- g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view));
-
- selected = e_calendar_view_get_selected_events (cal_view);
- if (!selected)
- return;
-
- /* create top-level VCALENDAR component and add VTIMEZONE's */
- vcal_comp = e_cal_util_new_top_level ();
- for (l = selected; l != NULL; l = l->next) {
- event = (ECalendarViewEvent *) l->data;
-
- if (event) {
- e_cal_util_add_timezones_from_component (vcal_comp, event->comp_data->icalcomp);
-
- add_related_timezones (vcal_comp, event->comp_data->icalcomp, event->comp_data->client);
- }
- }
-
- for (l = selected; l != NULL; l = l->next) {
- event = (ECalendarViewEvent *) l->data;
-
- new_icalcomp = icalcomponent_new_clone (event->comp_data->icalcomp);
-
- /* remove RECURRENCE-IDs from copied objects */
- if (e_cal_util_component_is_instance (new_icalcomp)) {
- icalproperty *prop;
-
- prop = icalcomponent_get_first_property (new_icalcomp, ICAL_RECURRENCEID_PROPERTY);
- if (prop)
- icalcomponent_remove_property (new_icalcomp, prop);
- }
- icalcomponent_add_component (vcal_comp, new_icalcomp);
- }
-
- comp_str = icalcomponent_as_ical_string_r (vcal_comp);
-
- /* copy the VCALENDAR to the clipboard */
- clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
- e_clipboard_set_calendar (clipboard, comp_str, -1);
- gtk_clipboard_store (clipboard);
-
- /* free memory */
- icalcomponent_free (vcal_comp);
- g_free (comp_str);
- g_list_free (selected);
-}
-
-static void
-clipboard_get_calendar_data (ECalendarView *cal_view, const gchar *text)
-{
- icalcomponent *icalcomp;
- icalcomponent_kind kind;
- time_t selected_time_start, selected_time_end;
- icaltimezone *default_zone;
- ECal *client;
- gboolean in_top_canvas;
-
- g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view));
-
- if (!text || !*text)
- return;
-
- icalcomp = icalparser_parse_string ((const gchar *) text);
- if (!icalcomp)
- return;
-
- default_zone = calendar_config_get_icaltimezone ();
- client = e_cal_model_get_default_client (cal_view->priv->model);
-
- /* check the type of the component */
- /* FIXME An error dialog if we return? */
- kind = icalcomponent_isa (icalcomp);
- if (kind != ICAL_VCALENDAR_COMPONENT && kind != ICAL_VEVENT_COMPONENT)
- return;
-
-#if 0 /* KILL-BONOBO */
- e_calendar_view_set_status_message (cal_view, _("Updating objects"), -1);
-#endif
- e_calendar_view_get_selected_time_range (cal_view, &selected_time_start, &selected_time_end);
-
- if ((selected_time_end - selected_time_start) == 60 * 60 * 24)
- in_top_canvas = TRUE;
- else
- in_top_canvas = FALSE;
-
- if (kind == ICAL_VCALENDAR_COMPONENT) {
- icalcomponent *subcomp;
-
- /* add timezones first, to have them ready */
- for (subcomp = icalcomponent_get_first_component (icalcomp, ICAL_VTIMEZONE_COMPONENT);
- subcomp;
- subcomp = icalcomponent_get_next_component (icalcomp, ICAL_VTIMEZONE_COMPONENT)) {
- icaltimezone *zone;
- GError *error = NULL;
-
- zone = icaltimezone_new ();
- icaltimezone_set_component (zone, subcomp);
- if (!e_cal_add_timezone (client, zone, &error)) {
- icalproperty *tzidprop = icalcomponent_get_first_property (subcomp, ICAL_TZID_PROPERTY);
-
- g_warning ("%s: Add zone '%s' failed. %s", G_STRFUNC, tzidprop ? icalproperty_get_tzid (tzidprop) : "???", error ? error->message : "");
- if (error)
- g_error_free (error);
- }
-
- icaltimezone_free (zone, 1);
- }
-
- for (subcomp = icalcomponent_get_first_component (icalcomp, ICAL_VEVENT_COMPONENT);
- subcomp;
- subcomp = icalcomponent_get_next_component (icalcomp, ICAL_VEVENT_COMPONENT)) {
- if (e_cal_util_component_has_recurrences (subcomp)) {
- icalproperty *icalprop = icalcomponent_get_first_property (subcomp, ICAL_RRULE_PROPERTY);
- if (icalprop)
- icalproperty_remove_parameter_by_name (icalprop, "X-EVOLUTION-ENDDATE");
- }
-
- e_calendar_view_add_event (cal_view, client, selected_time_start, default_zone, subcomp, in_top_canvas);
- }
-
- icalcomponent_free (icalcomp);
- } else {
- e_calendar_view_add_event (cal_view, client, selected_time_start, default_zone, icalcomp, in_top_canvas);
- }
-
-#if 0 /* KILL-BONOBO */
- e_calendar_view_set_status_message (cal_view, NULL, -1);
-#endif
-}
-
-void
-e_calendar_view_paste_clipboard (ECalendarView *cal_view)
-{
- GtkClipboard *clipboard;
-
- g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view));
-
- clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
-
- /* Paste text into an event being edited. */
- if (gtk_clipboard_wait_is_text_available (clipboard)) {
- ECalendarViewClass *class;
-
- class = E_CALENDAR_VIEW_GET_CLASS (cal_view);
- g_return_if_fail (class->paste_text != NULL);
-
- class->paste_text (cal_view);
-
- /* Paste iCalendar data into the view. */
- } else if (e_clipboard_wait_is_calendar_available (clipboard)) {
- gchar *calendar_source;
-
- calendar_source = e_clipboard_wait_for_calendar (clipboard);
- clipboard_get_calendar_data (cal_view, calendar_source);
- g_free (calendar_source);
- }
-}
-
static void
add_retract_data (ECalComponent *comp, const gchar *retract_comment, CalObjModType mod)
{
diff --git a/calendar/gui/e-calendar-view.h b/calendar/gui/e-calendar-view.h
index 7ae643a707..a7ed224fcb 100644
--- a/calendar/gui/e-calendar-view.h
+++ b/calendar/gui/e-calendar-view.h
@@ -174,9 +174,6 @@ gboolean e_calendar_view_get_visible_time_range
time_t *end_time);
void e_calendar_view_update_query (ECalendarView *cal_view);
-void e_calendar_view_cut_clipboard (ECalendarView *cal_view);
-void e_calendar_view_copy_clipboard (ECalendarView *cal_view);
-void e_calendar_view_paste_clipboard (ECalendarView *cal_view);
void e_calendar_view_delete_selected_event
(ECalendarView *cal_view);
void e_calendar_view_delete_selected_events
diff --git a/calendar/gui/e-day-view-main-item.c b/calendar/gui/e-day-view-main-item.c
index 6b34018fe7..16be4ffc89 100644
--- a/calendar/gui/e-day-view-main-item.c
+++ b/calendar/gui/e-day-view-main-item.c
@@ -33,6 +33,7 @@
#include <e-calendar-view.h>
#include "e-util/e-categories-config.h"
+#include "e-util/e-util.h"
#include "e-day-view-layout.h"
#include "e-day-view-main-item.h"
#include "ea-calendar.h"
diff --git a/calendar/gui/e-memo-table.c b/calendar/gui/e-memo-table.c
index 977715898e..4df17c5487 100644
--- a/calendar/gui/e-memo-table.c
+++ b/calendar/gui/e-memo-table.c
@@ -36,7 +36,8 @@
#include <glib/gi18n.h>
#include <glib/gstdio.h>
#include <e-util/e-binding.h>
-#include <widgets/misc/e-gui-utils.h>
+#include <misc/e-gui-utils.h>
+#include <misc/e-selectable.h>
#include <table/e-cell-checkbox.h>
#include <table/e-cell-toggle.h>
#include <table/e-cell-text.h>
@@ -181,6 +182,33 @@ memo_table_model_cal_view_done_cb (EMemoTable *memo_table,
memo_table_emit_status_message (memo_table, NULL, -1.0);
}
+/* Deletes all of the selected components in the table */
+static void
+delete_selected_components (EMemoTable *memo_table)
+{
+ GSList *objs, *l;
+ const gchar *status_message;
+
+ objs = e_memo_table_get_selected (memo_table);
+
+ status_message = _("Deleting selected objects");
+ memo_table_emit_status_message (memo_table, status_message, -1.0);
+
+ for (l = objs; l; l = l->next) {
+ ECalModelComponent *comp_data = (ECalModelComponent *) l->data;
+ GError *error = NULL;
+
+ e_cal_remove_object (comp_data->client,
+ icalcomponent_get_uid (comp_data->icalcomp), &error);
+ delete_error_dialog (error, E_CAL_COMPONENT_JOURNAL);
+ g_clear_error (&error);
+ }
+
+ memo_table_emit_status_message (memo_table, NULL, -1.0);
+
+ g_slist_free (objs);
+}
+
static void
memo_table_set_model (EMemoTable *memo_table,
ECalModel *model)
@@ -629,6 +657,270 @@ memo_table_right_click (ETable *table,
}
static void
+memo_table_update_actions (ESelectable *selectable,
+ EFocusTracker *focus_tracker,
+ GdkAtom *clipboard_targets,
+ gint n_clipboard_targets)
+{
+ EMemoTable *memo_table;
+ GtkAction *action;
+ GSList *list, *iter;
+ gboolean sources_are_editable = TRUE;
+ gboolean clipboard_has_calendar;
+ gboolean sensitive;
+ const gchar *tooltip;
+ gint n_selected;
+
+ memo_table = E_MEMO_TABLE (selectable);
+ n_selected = e_table_selected_count (E_TABLE (memo_table));
+
+ list = e_memo_table_get_selected (memo_table);
+ for (iter = list; iter != NULL; iter = iter->next) {
+ ECalModelComponent *comp_data = iter->data;
+ gboolean read_only;
+
+ e_cal_is_read_only (comp_data->client, &read_only, NULL);
+ sources_are_editable &= !read_only;
+ }
+ g_slist_free (list);
+
+ clipboard_has_calendar = (clipboard_targets != NULL) &&
+ e_targets_include_calendar (
+ clipboard_targets, n_clipboard_targets);
+
+ action = e_focus_tracker_get_cut_clipboard_action (focus_tracker);
+ sensitive = (n_selected > 0) && sources_are_editable;
+ tooltip = _("Cut selected memos to the clipboard");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+
+ action = e_focus_tracker_get_copy_clipboard_action (focus_tracker);
+ sensitive = (n_selected > 0);
+ tooltip = _("Copy selected memos to the clipboard");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+
+ action = e_focus_tracker_get_paste_clipboard_action (focus_tracker);
+ sensitive = sources_are_editable && clipboard_has_calendar;
+ tooltip = _("Paste memos from the clipboard");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+
+ action = e_focus_tracker_get_select_all_action (focus_tracker);
+ sensitive = TRUE;
+ tooltip = _("Select all visible memos");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+}
+
+static void
+memo_table_cut_clipboard (ESelectable *selectable)
+{
+ EMemoTable *memo_table;
+
+ memo_table = E_MEMO_TABLE (selectable);
+
+ e_selectable_copy_clipboard (selectable);
+ delete_selected_components (memo_table);
+}
+
+/* Helper for memo_table_copy_clipboard() */
+static void
+copy_row_cb (gint model_row, gpointer data)
+{
+ EMemoTable *memo_table;
+ ECalModelComponent *comp_data;
+ ECalModel *model;
+ gchar *comp_str;
+ icalcomponent *child;
+
+ memo_table = E_MEMO_TABLE (data);
+
+ g_return_if_fail (memo_table->tmp_vcal != NULL);
+
+ model = e_memo_table_get_model (memo_table);
+ comp_data = e_cal_model_get_component_at (model, model_row);
+ if (comp_data == NULL)
+ return;
+
+ /* Add timezones to the VCALENDAR component. */
+ e_cal_util_add_timezones_from_component (
+ memo_table->tmp_vcal, comp_data->icalcomp);
+
+ /* Add the new component to the VCALENDAR component. */
+ comp_str = icalcomponent_as_ical_string_r (comp_data->icalcomp);
+ child = icalparser_parse_string (comp_str);
+ if (child) {
+ icalcomponent_add_component (
+ memo_table->tmp_vcal,
+ icalcomponent_new_clone (child));
+ icalcomponent_free (child);
+ }
+ g_free (comp_str);
+}
+
+static void
+memo_table_copy_clipboard (ESelectable *selectable)
+{
+ EMemoTable *memo_table;
+ GtkClipboard *clipboard;
+ gchar *comp_str;
+
+ memo_table = E_MEMO_TABLE (selectable);
+
+ /* Create a temporary VCALENDAR object. */
+ memo_table->tmp_vcal = e_cal_util_new_top_level ();
+
+ e_table_selected_row_foreach (
+ E_TABLE (memo_table), copy_row_cb, memo_table);
+ comp_str = icalcomponent_as_ical_string_r (memo_table->tmp_vcal);
+
+ clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+ e_clipboard_set_calendar (clipboard, comp_str, -1);
+ gtk_clipboard_store (clipboard);
+
+ g_free (comp_str);
+
+ icalcomponent_free (memo_table->tmp_vcal);
+ memo_table->tmp_vcal = NULL;
+}
+
+/* Helper for memo_table_paste_clipboard() */
+static void
+clipboard_get_calendar_data (EMemoTable *memo_table,
+ const gchar *text)
+{
+ icalcomponent *icalcomp;
+ gchar *uid;
+ ECalComponent *comp;
+ ECal *client;
+ ECalModel *model;
+ icalcomponent_kind kind;
+ const gchar *status_message;
+
+ g_return_if_fail (E_IS_MEMO_TABLE (memo_table));
+
+ if (!text || !*text)
+ return;
+
+ icalcomp = icalparser_parse_string (text);
+ if (!icalcomp)
+ return;
+
+ /* 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;
+ }
+
+ model = e_memo_table_get_model (memo_table);
+ client = e_cal_model_get_default_client (model);
+
+ status_message = _("Updating objects");
+ memo_table_emit_status_message (memo_table, status_message, -1.0);
+
+ if (kind == ICAL_VCALENDAR_COMPONENT) {
+ icalcomponent_kind child_kind;
+ icalcomponent *subcomp;
+ icalcomponent *vcal_comp;
+
+ vcal_comp = icalcomp;
+ subcomp = icalcomponent_get_first_component (
+ vcal_comp, 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) {
+ ECalComponent *tmp_comp;
+
+ uid = e_cal_component_gen_uid ();
+ tmp_comp = e_cal_component_new ();
+ e_cal_component_set_icalcomponent (
+ tmp_comp,
+ icalcomponent_new_clone (subcomp));
+ e_cal_component_set_uid (tmp_comp, uid);
+ free (uid);
+
+ /* FIXME Should we convert start/due/complete
+ * times? Also, need error handling.*/
+ e_cal_create_object (
+ client, e_cal_component_get_icalcomponent (tmp_comp),
+ NULL, NULL);
+
+ g_object_unref (tmp_comp);
+ }
+ subcomp = icalcomponent_get_next_component (
+ vcal_comp, ICAL_ANY_COMPONENT);
+ }
+ } else {
+ comp = e_cal_component_new ();
+ e_cal_component_set_icalcomponent (comp, icalcomp);
+ uid = e_cal_component_gen_uid ();
+ e_cal_component_set_uid (comp, (const gchar *) uid);
+ free (uid);
+
+ e_cal_create_object (
+ client, e_cal_component_get_icalcomponent (comp),
+ NULL, NULL);
+
+ g_object_unref (comp);
+ }
+
+ memo_table_emit_status_message (memo_table, NULL, -1.0);
+}
+
+static void
+memo_table_paste_clipboard (ESelectable *selectable)
+{
+ EMemoTable *memo_table;
+ GtkClipboard *clipboard;
+ GnomeCanvasItem *item;
+ GnomeCanvas *table_canvas;
+
+ memo_table = E_MEMO_TABLE (selectable);
+
+ clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+
+ table_canvas = E_TABLE (memo_table)->table_canvas;
+ item = table_canvas->focused_item;
+
+ /* XXX Should ECellText implement GtkEditable? */
+
+ /* Paste text into a cell being edited. */
+ if (gtk_clipboard_wait_is_text_available (clipboard) &&
+ GTK_WIDGET_HAS_FOCUS (table_canvas) &&
+ E_IS_TABLE_ITEM (item) &&
+ E_TABLE_ITEM (item)->editing_col >= 0 &&
+ E_TABLE_ITEM (item)->editing_row >= 0) {
+
+ ETableItem *etable_item = E_TABLE_ITEM (item);
+
+ e_cell_text_paste_clipboard (
+ etable_item->cell_views[etable_item->editing_col],
+ etable_item->editing_col,
+ etable_item->editing_row);
+
+ /* Paste iCalendar data into the table. */
+ } else if (e_clipboard_wait_is_calendar_available (clipboard)) {
+ gchar *calendar_source;
+
+ calendar_source = e_clipboard_wait_for_calendar (clipboard);
+ clipboard_get_calendar_data (memo_table, calendar_source);
+ g_free (calendar_source);
+ }
+}
+
+static void
+memo_table_select_all (ESelectable *selectable)
+{
+ e_table_select_all (E_TABLE (selectable));
+}
+
+static void
memo_table_class_init (EMemoTableClass *class)
{
GObjectClass *object_class;
@@ -720,6 +1012,16 @@ memo_table_init (EMemoTable *memo_table)
memo_table->priv = E_MEMO_TABLE_GET_PRIVATE (memo_table);
}
+static void
+memo_table_selectable_init (ESelectableInterface *interface)
+{
+ interface->update_actions = memo_table_update_actions;
+ interface->cut_clipboard = memo_table_cut_clipboard;
+ interface->copy_clipboard = memo_table_copy_clipboard;
+ interface->paste_clipboard = memo_table_paste_clipboard;
+ interface->select_all = memo_table_select_all;
+}
+
GType
e_memo_table_get_type (void)
{
@@ -739,8 +1041,17 @@ e_memo_table_get_type (void)
NULL /* value_table */
};
+ static const GInterfaceInfo selectable_info = {
+ (GInterfaceInitFunc) memo_table_selectable_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL /* interface_data */
+ };
+
type = g_type_register_static (
E_TABLE_TYPE, "EMemoTable", &type_info, 0);
+
+ g_type_add_interface_static (
+ type, E_TYPE_SELECTABLE, &selectable_info);
}
return type;
@@ -847,33 +1158,6 @@ add_uid_cb (gint model_row, gpointer data)
closure->objects = g_slist_prepend (closure->objects, comp_data);
}
-/* Deletes all of the selected components in the table */
-static void
-delete_selected_components (EMemoTable *memo_table)
-{
- GSList *objs, *l;
- const gchar *status_message;
-
- objs = e_memo_table_get_selected (memo_table);
-
- status_message = _("Deleting selected objects");
- memo_table_emit_status_message (memo_table, status_message, -1.0);
-
- for (l = objs; l; l = l->next) {
- ECalModelComponent *comp_data = (ECalModelComponent *) l->data;
- GError *error = NULL;
-
- e_cal_remove_object (comp_data->client,
- icalcomponent_get_uid (comp_data->icalcomp), &error);
- delete_error_dialog (error, E_CAL_COMPONENT_JOURNAL);
- g_clear_error (&error);
- }
-
- memo_table_emit_status_message (memo_table, NULL, -1.0);
-
- g_slist_free (objs);
-}
-
/**
* e_memo_table_delete_selected:
* @memo_table: A memo table.
@@ -938,210 +1222,6 @@ e_memo_table_get_selected (EMemoTable *memo_table)
return closure.objects;
}
-/**
- * e_memo_table_cut_clipboard:
- * @memo_table: A calendar table.
- *
- * Cuts selected tasks in the given calendar table
- */
-void
-e_memo_table_cut_clipboard (EMemoTable *memo_table)
-{
- g_return_if_fail (E_IS_MEMO_TABLE (memo_table));
-
- e_memo_table_copy_clipboard (memo_table);
- delete_selected_components (memo_table);
-}
-
-/* callback for e_table_selected_row_foreach */
-static void
-copy_row_cb (gint model_row, gpointer data)
-{
- EMemoTable *memo_table;
- ECalModelComponent *comp_data;
- ECalModel *model;
- gchar *comp_str;
- icalcomponent *child;
-
- memo_table = E_MEMO_TABLE (data);
-
- g_return_if_fail (memo_table->tmp_vcal != NULL);
-
- model = e_memo_table_get_model (memo_table);
- comp_data = e_cal_model_get_component_at (model, model_row);
- if (!comp_data)
- return;
-
- /* add timezones to the VCALENDAR component */
- e_cal_util_add_timezones_from_component (memo_table->tmp_vcal, comp_data->icalcomp);
-
- /* add the new component to the VCALENDAR component */
- comp_str = icalcomponent_as_ical_string_r (comp_data->icalcomp);
- child = icalparser_parse_string (comp_str);
- if (child) {
- icalcomponent_add_component (memo_table->tmp_vcal,
- icalcomponent_new_clone (child));
- icalcomponent_free (child);
- }
- g_free (comp_str);
-}
-
-/**
- * e_memo_table_copy_clipboard:
- * @memo_table: A calendar table.
- *
- * Copies selected tasks into the clipboard
- */
-void
-e_memo_table_copy_clipboard (EMemoTable *memo_table)
-{
- GtkClipboard *clipboard;
- gchar *comp_str;
-
- g_return_if_fail (E_IS_MEMO_TABLE (memo_table));
-
- /* create temporary VCALENDAR object */
- memo_table->tmp_vcal = e_cal_util_new_top_level ();
-
- e_table_selected_row_foreach (
- E_TABLE (memo_table), copy_row_cb, memo_table);
- comp_str = icalcomponent_as_ical_string_r (memo_table->tmp_vcal);
-
- clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
- e_clipboard_set_calendar (clipboard, comp_str, -1);
- gtk_clipboard_store (clipboard);
-
- /* free memory */
- icalcomponent_free (memo_table->tmp_vcal);
- g_free (comp_str);
- memo_table->tmp_vcal = NULL;
-}
-
-static void
-clipboard_get_calendar_data (EMemoTable *memo_table, const gchar *text)
-{
- icalcomponent *icalcomp;
- gchar *uid;
- ECalComponent *comp;
- ECal *client;
- ECalModel *model;
- icalcomponent_kind kind;
- const gchar *status_message;
-
- g_return_if_fail (E_IS_MEMO_TABLE (memo_table));
-
- if (!text || !*text)
- return;
-
- icalcomp = icalparser_parse_string (text);
- if (!icalcomp)
- return;
-
- /* 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;
- }
-
- model = e_memo_table_get_model (memo_table);
- client = e_cal_model_get_default_client (model);
-
- status_message = _("Updating objects");
- memo_table_emit_status_message (memo_table, status_message, -1.0);
-
- if (kind == ICAL_VCALENDAR_COMPONENT) {
- icalcomponent_kind child_kind;
- icalcomponent *subcomp;
- icalcomponent *vcal_comp;
-
- vcal_comp = icalcomp;
- subcomp = icalcomponent_get_first_component (
- vcal_comp, 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) {
- ECalComponent *tmp_comp;
-
- uid = e_cal_component_gen_uid ();
- tmp_comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (
- tmp_comp, icalcomponent_new_clone (subcomp));
- e_cal_component_set_uid (tmp_comp, uid);
- free (uid);
-
- /* FIXME should we convert start/due/complete times? */
- /* FIXME Error handling */
- e_cal_create_object (client, e_cal_component_get_icalcomponent (tmp_comp), NULL, NULL);
-
- g_object_unref (tmp_comp);
- }
- subcomp = icalcomponent_get_next_component (
- vcal_comp, ICAL_ANY_COMPONENT);
- }
- } else {
- comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (comp, icalcomp);
- uid = e_cal_component_gen_uid ();
- e_cal_component_set_uid (comp, (const gchar *) uid);
- free (uid);
-
- e_cal_create_object (client, e_cal_component_get_icalcomponent (comp), NULL, NULL);
-
- g_object_unref (comp);
- }
-
- memo_table_emit_status_message (memo_table, NULL, -1.0);
-}
-
-/**
- * e_memo_table_paste_clipboard:
- * @memo_table: A calendar table.
- *
- * Pastes tasks currently in the clipboard into the given calendar table
- */
-void
-e_memo_table_paste_clipboard (EMemoTable *memo_table)
-{
- GtkClipboard *clipboard;
- GnomeCanvasItem *item;
- GnomeCanvas *table_canvas;
-
- g_return_if_fail (E_IS_MEMO_TABLE (memo_table));
-
- clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
-
- table_canvas = E_TABLE (memo_table)->table_canvas;
- item = table_canvas->focused_item;
-
- /* Paste text into a cell being edited. */
- if (gtk_clipboard_wait_is_text_available (clipboard) &&
- GTK_WIDGET_HAS_FOCUS (table_canvas) &&
- E_IS_TABLE_ITEM (item) &&
- E_TABLE_ITEM (item)->editing_col >= 0 &&
- E_TABLE_ITEM (item)->editing_row >= 0) {
-
- ETableItem *etable_item = E_TABLE_ITEM (item);
-
- e_cell_text_paste_clipboard (
- etable_item->cell_views[etable_item->editing_col],
- etable_item->editing_col,
- etable_item->editing_row);
-
- /* Paste iCalendar data into the table. */
- } else if (e_clipboard_wait_is_calendar_available (clipboard)) {
- gchar *calendar_source;
-
- calendar_source = e_clipboard_wait_for_calendar (clipboard);
- clipboard_get_calendar_data (memo_table, calendar_source);
- g_free (calendar_source);
- }
-}
-
/* Returns the current time, for the ECellDateEdit items.
FIXME: Should probably use the timezone of the item rather than the
current timezone, though that may be difficult to get from here. */
diff --git a/calendar/gui/e-memo-table.h b/calendar/gui/e-memo-table.h
index 4d4347db4a..b55ddc5e66 100644
--- a/calendar/gui/e-memo-table.h
+++ b/calendar/gui/e-memo-table.h
@@ -106,11 +106,6 @@ void e_memo_table_set_use_24_hour_format
void e_memo_table_delete_selected (EMemoTable *memo_table);
GSList * e_memo_table_get_selected (EMemoTable *memo_table);
-/* Clipboard related functions */
-void e_memo_table_cut_clipboard (EMemoTable *memo_table);
-void e_memo_table_copy_clipboard (EMemoTable *memo_table);
-void e_memo_table_paste_clipboard (EMemoTable *memo_table);
-
G_END_DECLS
#endif /* _E_MEMO_TABLE_H_ */
diff --git a/calendar/gui/gnome-cal.h b/calendar/gui/gnome-cal.h
index 0cc528fe3c..197396dbd6 100644
--- a/calendar/gui/gnome-cal.h
+++ b/calendar/gui/gnome-cal.h
@@ -33,7 +33,7 @@
#include <libecal/e-cal.h>
#include <shell/e-shell-settings.h>
-#include "e-calendar-table.h"
+#include "e-cal-model.h"
/* Standard GObject macros */
#define GNOME_TYPE_CALENDAR \
diff --git a/calendar/gui/goto.c b/calendar/gui/goto.c
index 86f06f32dc..569c15f38f 100644
--- a/calendar/gui/goto.c
+++ b/calendar/gui/goto.c
@@ -26,6 +26,7 @@
#include <config.h>
#include <gtk/gtk.h>
+#include "e-util/e-util.h"
#include "e-util/e-util-private.h"
#include "calendar-config.h"
#include "tag-calendar.h"
diff --git a/calendar/gui/print.h b/calendar/gui/print.h
index 39d5608222..5217c473a1 100644
--- a/calendar/gui/print.h
+++ b/calendar/gui/print.h
@@ -25,6 +25,7 @@
#ifndef PRINT_H
#define PRINT_H
+#include <table/e-table.h>
#include "calendar/gui/gnome-cal.h"
typedef enum {