diff options
Diffstat (limited to 'calendar')
-rw-r--r-- | calendar/gui/Makefile.am | 2 | ||||
-rw-r--r-- | calendar/gui/calendar-component.c | 4 | ||||
-rw-r--r-- | calendar/gui/dialogs/comp-editor.c | 1229 | ||||
-rw-r--r-- | calendar/gui/dialogs/event-editor.c | 2 | ||||
-rw-r--r-- | calendar/gui/e-cal-popup.c | 417 | ||||
-rw-r--r-- | calendar/gui/e-cal-popup.h | 2 |
6 files changed, 295 insertions, 1361 deletions
diff --git a/calendar/gui/Makefile.am b/calendar/gui/Makefile.am index e61f6a1f91..b5dab7aeac 100644 --- a/calendar/gui/Makefile.am +++ b/calendar/gui/Makefile.am @@ -69,6 +69,8 @@ etspec_DATA = \ libevolution_calendar_la_SOURCES = \ $(IDL_GENERATED) \ + e-attachment-handler-calendar.c \ + e-attachment-handler-calendar.h \ cal-search-bar.c \ cal-search-bar.h \ calendar-config.c \ diff --git a/calendar/gui/calendar-component.c b/calendar/gui/calendar-component.c index 942960bff5..4d30929272 100644 --- a/calendar/gui/calendar-component.c +++ b/calendar/gui/calendar-component.c @@ -58,6 +58,7 @@ #include "e-util/e-error.h" #include "e-cal-menu.h" #include "e-cal-popup.h" +#include "e-attachment-handler-calendar.h" /* IDs for user creatable items */ #define CREATE_EVENT_ID "event" @@ -1576,6 +1577,9 @@ calendar_component_class_init (CalendarComponentClass *class) object_class->dispose = impl_dispose; object_class->finalize = impl_finalize; + + /* Register attachment handler types. */ + e_attachment_handler_calendar_get_type (); } static void diff --git a/calendar/gui/dialogs/comp-editor.c b/calendar/gui/dialogs/comp-editor.c index f3034359c6..6456a5ce04 100644 --- a/calendar/gui/dialogs/comp-editor.c +++ b/calendar/gui/dialogs/comp-editor.c @@ -63,9 +63,9 @@ #include "../e-cal-popup.h" #include "../calendar-config-keys.h" #include "cal-attachment-select-file.h" +#include "widgets/misc/e-attachment-view.h" +#include "widgets/misc/e-attachment-paned.h" -#include "e-attachment-bar.h" -#include "misc/e-expander.h" #include "e-util/e-error.h" #define COMP_EDITOR_GET_PRIVATE(obj) \ @@ -95,12 +95,7 @@ struct _CompEditorPrivate { GtkNotebook *notebook; /* Attachment handling */ - GtkWidget *attachment_bar; - GtkWidget *attachment_scrolled_window; - GtkWidget *attachment_expander; - GtkWidget *attachment_expander_label; - GtkWidget *attachment_expander_icon; - GtkWidget *attachment_expander_num; + GtkWidget *attachment_view; /* Manages menus and toolbars */ GtkUIManager *manager; @@ -151,7 +146,7 @@ static const gchar *ui = " <menu action='view-menu'/>" " <menu action='insert-menu'>" " <menuitem action='attach'/>" -" <menuitem action='attach-recent'/>" +" <placeholder name='recent-placeholder'/>" " </menu>" " <menu action='options-menu'/>" " <menu action='help-menu'>" @@ -163,13 +158,10 @@ static const gchar *ui = " <toolitem action='print'/>" " <toolitem action='close'/>" " <separator/>" -" <toolitem action='attach'/>" -" <separator/>" " </toolbar>" "</ui>"; static void comp_editor_show_help (CompEditor *editor); -static void setup_widgets (CompEditor *editor); static void real_edit_comp (CompEditor *editor, ECalComponent *comp); static gboolean real_send_comp (CompEditor *editor, ECalComponentItipMethod method, gboolean strip_alarms); @@ -180,441 +172,63 @@ static void page_dates_changed_cb (CompEditor *editor, CompEditorPageDates *date static void obj_modified_cb (ECal *client, GList *objs, gpointer data); static void obj_removed_cb (ECal *client, GList *uids, gpointer data); -static gboolean open_attachment (EAttachmentBar *bar, CompEditor *editor); G_DEFINE_TYPE (CompEditor, comp_editor, GTK_TYPE_WINDOW) enum { - DND_TYPE_MESSAGE_RFC822, - DND_TYPE_X_UID_LIST, - DND_TYPE_TEXT_URI_LIST, - DND_TYPE_NETSCAPE_URL, - DND_TYPE_TEXT_VCARD, - DND_TYPE_TEXT_CALENDAR, -}; - -static GtkTargetEntry drop_types[] = { - { "message/rfc822", 0, DND_TYPE_MESSAGE_RFC822 }, - { "x-uid-list", 0, DND_TYPE_X_UID_LIST }, - { "text/uri-list", 0, DND_TYPE_TEXT_URI_LIST }, - { "_NETSCAPE_URL", 0, DND_TYPE_NETSCAPE_URL }, - { "text/x-vcard", 0, DND_TYPE_TEXT_VCARD }, - { "text/calendar", 0, DND_TYPE_TEXT_CALENDAR }, -}; - -#define num_drop_types (sizeof (drop_types) / sizeof (drop_types[0])) - -static struct { - char *target; - GdkAtom atom; - guint32 actions; -} drag_info[] = { - { "message/rfc822", NULL, GDK_ACTION_COPY }, - { "x-uid-list", NULL, GDK_ACTION_ASK|GDK_ACTION_MOVE|GDK_ACTION_COPY }, - { "text/uri-list", NULL, GDK_ACTION_COPY }, - { "_NETSCAPE_URL", NULL, GDK_ACTION_COPY }, - { "text/x-vcard", NULL, GDK_ACTION_COPY }, - { "text/calendar", NULL, GDK_ACTION_COPY }, -}; - -enum { OBJECT_CREATED, LAST_SIGNAL }; static guint comp_editor_signals[LAST_SIGNAL] = { 0 }; -static void -attach_message(CompEditor *editor, CamelMimeMessage *msg) -{ - CamelMimePart *mime_part; - const char *subject; - guint i; - char *filename = NULL; - - mime_part = camel_mime_part_new(); - camel_mime_part_set_disposition(mime_part, "inline"); - subject = camel_mime_message_get_subject(msg); - if (subject) { - char *desc = g_strdup_printf(_("Attached message - %s"), subject); - - camel_mime_part_set_description(mime_part, desc); - g_free(desc); - } else - camel_mime_part_set_description(mime_part, _("Attached message")); - - i = e_attachment_bar_get_num_attachments (E_ATTACHMENT_BAR (editor->priv->attachment_bar)); - i++; - filename = g_strdup_printf ("email%d",i); - camel_mime_part_set_filename (mime_part, filename); - - camel_medium_set_content_object((CamelMedium *)mime_part, (CamelDataWrapper *)msg); - camel_mime_part_set_content_type(mime_part, "message/rfc822"); - e_attachment_bar_attach_mime_part(E_ATTACHMENT_BAR(editor->priv->attachment_bar), mime_part); - camel_object_unref(mime_part); - g_free (filename); -} - -struct _drop_data { - CompEditor *editor; - - GdkDragContext *context; - /* Only selection->data and selection->length are valid */ - GtkSelectionData *selection; - - guint32 action; - guint info; - guint time; - - unsigned int move:1; - unsigned int moved:1; - unsigned int aborted:1; -}; - -static void -drop_action(CompEditor *editor, GdkDragContext *context, guint32 action, GtkSelectionData *selection, guint info, guint time) -{ - char *tmp, *str, **urls; - CamelMimePart *mime_part; - CamelStream *stream; - CamelURL *url; - CamelMimeMessage *msg; - char *content_type; - int i, success=FALSE, delete=FALSE; - - switch (info) { - case DND_TYPE_MESSAGE_RFC822: - d(printf ("dropping a message/rfc822\n")); - /* write the message(s) out to a CamelStream so we can use it */ - stream = camel_stream_mem_new (); - camel_stream_write (stream, (char *)selection->data, selection->length); - camel_stream_reset (stream); - - msg = camel_mime_message_new (); - if (camel_data_wrapper_construct_from_stream((CamelDataWrapper *)msg, stream) != -1) { - attach_message(editor, msg); - success = TRUE; - delete = action == GDK_ACTION_MOVE; - } - - camel_object_unref(msg); - camel_object_unref(stream); - break; - case DND_TYPE_TEXT_URI_LIST: - case DND_TYPE_NETSCAPE_URL: - d(printf ("dropping a text/uri-list\n")); - tmp = g_strndup ((char *)selection->data, selection->length); - urls = g_strsplit (tmp, "\n", 0); - g_free (tmp); - - for (i = 0; urls[i] != NULL; i++) { - str = g_strstrip (urls[i]); - if (urls[i][0] == '#') - continue; - - if (!g_ascii_strncasecmp (str, "mailto:", 7)) { - /* TODO does not handle mailto now */ - } else { - url = camel_url_new (str, NULL); - - if (url == NULL) - continue; - - if (!g_ascii_strcasecmp (url->protocol, "file")) - e_attachment_bar_attach - (E_ATTACHMENT_BAR (editor->priv->attachment_bar), - url->path, - "attachment"); - else - e_attachment_bar_attach_remote_file - (E_ATTACHMENT_BAR (editor->priv->attachment_bar), - str, "attachment"); - - camel_url_free (url); - } - } - - g_strfreev (urls); - success = TRUE; - break; - case DND_TYPE_TEXT_VCARD: - case DND_TYPE_TEXT_CALENDAR: - content_type = gdk_atom_name (selection->type); - d(printf ("dropping a %s\n", content_type)); - - mime_part = camel_mime_part_new (); - camel_mime_part_set_content (mime_part, (char *)selection->data, selection->length, content_type); - camel_mime_part_set_disposition (mime_part, "inline"); - - e_attachment_bar_attach_mime_part - (E_ATTACHMENT_BAR (editor->priv->attachment_bar), - mime_part); - - camel_object_unref (mime_part); - g_free (content_type); - - success = TRUE; - break; - case DND_TYPE_X_UID_LIST: { - GPtrArray *uids; - char *inptr, *inend; - CamelFolder *folder; - CamelException ex = CAMEL_EXCEPTION_INITIALISER; - - /* NB: This all runs synchronously, could be very slow/hang/block the ui */ - - uids = g_ptr_array_new(); - - inptr = (char *)selection->data; - inend = (char *)(selection->data + selection->length); - while (inptr < inend) { - char *start = inptr; - - while (inptr < inend && *inptr) - inptr++; - - if (start > (char *)selection->data) - g_ptr_array_add(uids, g_strndup(start, inptr-start)); - - inptr++; - } - - if (uids->len > 0) { - folder = mail_tool_uri_to_folder((char *)selection->data, 0, &ex); - if (folder) { - if (uids->len == 1) { - msg = camel_folder_get_message(folder, uids->pdata[0], &ex); - if (msg == NULL) - goto fail; - attach_message(editor, msg); - } else { - CamelMultipart *mp = camel_multipart_new(); - char *desc; - char *filename = NULL; - guint num; - - camel_data_wrapper_set_mime_type((CamelDataWrapper *)mp, "multipart/digest"); - camel_multipart_set_boundary(mp, NULL); - for (i=0;i<uids->len;i++) { - - msg = camel_folder_get_message(folder, uids->pdata[i], &ex); - if (msg) { - mime_part = camel_mime_part_new(); - camel_mime_part_set_disposition(mime_part, "inline"); - camel_medium_set_content_object((CamelMedium *)mime_part, (CamelDataWrapper *)msg); - camel_mime_part_set_content_type(mime_part, "message/rfc822"); - camel_multipart_add_part(mp, mime_part); - camel_object_unref(mime_part); - camel_object_unref(msg); - } else { - camel_object_unref(mp); - goto fail; - } - } - mime_part = camel_mime_part_new(); - camel_medium_set_content_object((CamelMedium *)mime_part, (CamelDataWrapper *)mp); - /* translators, this count will always be >1 */ - desc = g_strdup_printf(ngettext("Attached message", "%d attached messages", uids->len), uids->len); - camel_mime_part_set_description(mime_part, desc); - g_free(desc); - - num = e_attachment_bar_get_num_attachments (E_ATTACHMENT_BAR (editor->priv->attachment_bar)); - num++; - filename = g_strdup_printf ("email%d", num); - camel_mime_part_set_filename (mime_part, filename); - - e_attachment_bar_attach_mime_part - (E_ATTACHMENT_BAR(editor->priv->attachment_bar), mime_part); - camel_object_unref(mime_part); - camel_object_unref(mp); - g_free (filename); - } - success = TRUE; - delete = action == GDK_ACTION_MOVE; - fail: - if (camel_exception_is_set(&ex)) { - char *name; - - camel_object_get(folder, NULL, CAMEL_FOLDER_NAME, &name, NULL); - e_error_run((GtkWindow *)editor, "mail-editor:attach-nomessages", - name?name:(char *)selection->data, camel_exception_get_description(&ex), NULL); - camel_object_free(folder, CAMEL_FOLDER_NAME, name); - } - camel_object_unref(folder); - } else { - e_error_run((GtkWindow *)editor, "mail-editor:attach-nomessages", - (char *)selection->data, camel_exception_get_description(&ex), NULL); - } - - camel_exception_clear(&ex); - } - - g_ptr_array_free(uids, TRUE); - - break; } - default: - d(printf ("dropping an unknown\n")); - break; - } - - printf("Drag finished, success %d delete %d\n", success, delete); - - gtk_drag_finish(context, success, delete, time); -} - -static void -drop_popup_copy (EPopup *ep, EPopupItem *item, void *data) -{ - struct _drop_data *m = data; - drop_action(m->editor, m->context, GDK_ACTION_COPY, m->selection, m->info, m->time); -} - -static void -drop_popup_move (EPopup *ep, EPopupItem *item, void *data) -{ - struct _drop_data *m = data; - drop_action(m->editor, m->context, GDK_ACTION_MOVE, m->selection, m->info, m->time); -} - -static void -drop_popup_cancel(EPopup *ep, EPopupItem *item, void *data) -{ - struct _drop_data *m = data; - gtk_drag_finish(m->context, FALSE, FALSE, m->time); -} - -static EPopupItem drop_popup_menu[] = { - { E_POPUP_ITEM, "00.emc.02", N_("_Copy"), drop_popup_copy, NULL, "mail-copy", 0 }, - { E_POPUP_ITEM, "00.emc.03", N_("_Move"), drop_popup_move, NULL, "mail-move", 0 }, - { E_POPUP_BAR, "10.emc" }, - { E_POPUP_ITEM, "99.emc.00", N_("Cancel _Drag"), drop_popup_cancel, NULL, NULL, 0 }, -}; - -static void -drop_popup_free(EPopup *ep, GSList *items, void *data) -{ - struct _drop_data *m = data; - - g_slist_free(items); - - g_object_unref(m->context); - g_object_unref(m->editor); - g_free(m->selection->data); - g_free(m->selection); - g_free(m); -} - -static void -drag_data_received (CompEditor *editor, GdkDragContext *context, - int x, int y, GtkSelectionData *selection, - guint info, guint time) -{ - if (selection->data == NULL || selection->length == -1) - return; - - if (context->action == GDK_ACTION_ASK) { - ECalPopup *ecp; - GSList *menus = NULL; - GtkMenu *menu; - int i; - struct _drop_data *m; - - m = g_malloc0(sizeof(*m)); - m->context = context; - g_object_ref(context); - m->editor = editor; - g_object_ref(editor); - m->action = context->action; - m->info = info; - m->time = time; - m->selection = g_malloc0(sizeof(*m->selection)); - m->selection->data = g_malloc(selection->length); - memcpy(m->selection->data, selection->data, selection->length); - m->selection->length = selection->length; - - ecp = e_cal_popup_new("org.gnome.evolution.calendar.editor.popup.drop"); - for (i=0;i<sizeof(drop_popup_menu)/sizeof(drop_popup_menu[0]);i++) - menus = g_slist_append(menus, &drop_popup_menu[i]); - - e_popup_add_items((EPopup *)ecp, menus, NULL, drop_popup_free, m); - menu = e_popup_create_menu_once((EPopup *)ecp, NULL, 0); - gtk_menu_popup(menu, NULL, NULL, NULL, NULL, 0, time); - } else { - drop_action(editor, context, context->action, selection, info, time); - } -} - -static gboolean -drag_motion(GObject *o, GdkDragContext *context, gint x, gint y, guint time, CompEditor *editor) -{ - GList *targets; - GdkDragAction action, actions = 0; - - for (targets = context->targets; targets; targets = targets->next) { - int i; - - for (i=0;i<sizeof(drag_info)/sizeof(drag_info[0]);i++) - if (targets->data == (void *)drag_info[i].atom) - actions |= drag_info[i].actions; - } - - actions &= context->actions; - action = context->suggested_action; - /* we default to copy */ - if (action == GDK_ACTION_ASK && (actions & (GDK_ACTION_MOVE|GDK_ACTION_COPY)) != (GDK_ACTION_MOVE|GDK_ACTION_COPY)) - action = GDK_ACTION_COPY; - - gdk_drag_status(context, action, time); - - return action != 0; -} - -static void -add_to_bar (CompEditor *editor, GPtrArray *file_list, int is_inline) -{ - CompEditorPrivate *priv = editor->priv; - int i; - - for (i = 0; i < file_list->len; i++) { - CamelURL *url; - - if (!(url = camel_url_new (file_list->pdata[i], NULL))) - continue; - - if (!g_ascii_strcasecmp (url->protocol, "file")) { - e_attachment_bar_attach((EAttachmentBar *)priv->attachment_bar, url->path, is_inline ? "inline" : "attachment"); - } else { - e_attachment_bar_attach_remote_file ((EAttachmentBar *)priv->attachment_bar, file_list->pdata[i], is_inline ? "inline" : "attachment"); - } - - camel_url_free (url); - } -} - static GSList * get_attachment_list (CompEditor *editor) { - GSList *parts = NULL, *list = NULL, *p = NULL; + EAttachmentStore *store; + EAttachmentView *view; + GtkTreeModel *model; + GtkTreeIter iter; + GSList *parts = NULL, *list = NULL; const char *comp_uid = NULL; const char *local_store = e_cal_get_local_attachment_store (editor->priv->client); + gboolean valid; int ticker=0; + e_cal_component_get_uid (editor->priv->comp, &comp_uid); - parts = e_attachment_bar_get_parts((EAttachmentBar *)editor->priv->attachment_bar); + view = E_ATTACHMENT_VIEW (editor->priv->attachment_view); + store = e_attachment_view_get_store (view); - for (p = parts; p!=NULL ; p = p->next) { + model = GTK_TREE_MODEL (store); + valid = gtk_tree_model_get_iter_first (model, &iter); + + while (valid) { + EAttachment *attachment; CamelDataWrapper *wrapper; + CamelMimePart *mime_part; CamelStream *stream; char *attach_file_url; char *safe_fname, *utf8_safe_fname; char *filename; + gint column_id; + + column_id = E_ATTACHMENT_STORE_COLUMN_ATTACHMENT; + gtk_tree_model_get (model, &iter, column_id, &attachment, -1); + mime_part = e_attachment_get_mime_part (attachment); + g_object_unref (attachment); + + valid = gtk_tree_model_iter_next (model, &iter); - wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (p->data)); + if (mime_part == NULL) + continue; + + wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)); /* Extract the content from the stream and write it down * as a mime part file into the directory denoting the * calendar source */ - utf8_safe_fname = camel_file_util_safe_filename (camel_mime_part_get_filename ((CamelMimePart *) p->data)); + utf8_safe_fname = camel_file_util_safe_filename (camel_mime_part_get_filename (mime_part)); /* It is absolutely fine to get a NULL from the filename of * mime part. We assume that it is named "Attachment" @@ -993,20 +607,21 @@ static void action_attach_cb (GtkAction *action, CompEditor *editor) { - GPtrArray *file_list; - gboolean is_inline = FALSE; - int i; - - file_list = comp_editor_select_file_attachments (editor, &is_inline); + EAttachmentStore *store; + EAttachmentView *view; - if (file_list) { - add_to_bar (editor, file_list, is_inline); + view = E_ATTACHMENT_VIEW (editor->priv->attachment_view); + store = e_attachment_view_get_store (view); - for (i = 0; i < file_list->len; i++) - g_free (file_list->pdata[i]); + e_attachment_store_run_load_dialog (store, GTK_WINDOW (editor)); +} - g_ptr_array_free (file_list, TRUE); - } +static void +action_classification_cb (GtkRadioAction *action, + GtkRadioAction *current, + CompEditor *editor) +{ + comp_editor_set_changed (editor, TRUE); } static void @@ -1132,12 +747,17 @@ action_save_cb (GtkAction *action, CompEditor *editor) { CompEditorPrivate *priv = editor->priv; + EAttachmentStore *store; + EAttachmentView *view; ECalComponentText text; gboolean delegated = FALSE; gboolean read_only, correct = FALSE; ECalComponent *comp; - if (e_attachment_bar_get_download_count (E_ATTACHMENT_BAR (editor->priv->attachment_bar)) ){ + view = E_ATTACHMENT_VIEW (priv->attachment_view); + store = e_attachment_view_get_store (view); + + if (e_attachment_store_get_num_loading (store) > 0) { gboolean response = 1; /*FIXME: Cannot use mail functions from calendar!!!! */ #if 0 @@ -1520,6 +1140,40 @@ static GtkToggleActionEntry coordinated_toggle_entries[] = { }; static void +comp_editor_setup_recent_menu (CompEditor *editor) +{ + EAttachmentView *view; + GtkUIManager *ui_manager; + GtkAction *action; + GtkActionGroup *action_group; + const gchar *action_name; + const gchar *path; + guint merge_id; + + ui_manager = editor->priv->manager; + view = E_ATTACHMENT_VIEW (editor->priv->attachment_view); + action_group = comp_editor_get_action_group (editor, "individual"); + merge_id = gtk_ui_manager_new_merge_id (ui_manager); + path = "/main-menu/insert-menu/recent-placeholder"; + action_name = "recent-menu"; + + action = e_attachment_view_recent_action_new ( + view, action_name, _("Recent _Documents")); + + if (action != NULL) { + gtk_action_group_add_action (action_group, action); + g_object_unref (action); + + gtk_ui_manager_add_ui ( + ui_manager, merge_id, path, + action_name, action_name, + GTK_UI_MANAGER_AUTO, FALSE); + } + + gtk_ui_manager_ensure_update (ui_manager); +} + +static void comp_editor_set_property (GObject *object, guint property_id, const GValue *value, @@ -1695,15 +1349,89 @@ comp_editor_map (GtkWidget *widget) GTK_WIDGET_CLASS (comp_editor_parent_class)->map (widget); } +static gboolean +comp_editor_delete_event (GtkWidget *widget, + GdkEventAny *event) +{ + CompEditor *editor; + + editor = COMP_EDITOR (widget); + + commit_all_fields (editor); + + if (prompt_and_save_changes (editor, TRUE)) + close_dialog (editor); + + return TRUE; +} + +static gboolean +comp_editor_key_press_event (GtkWidget *widget, + GdkEventKey *event) +{ + CompEditor *editor; + + editor = COMP_EDITOR (widget); + + if (event->keyval == GDK_Escape) { + commit_all_fields (editor); + + if (prompt_and_save_changes (editor, TRUE)) + close_dialog (editor); + + return TRUE; + } + + /* Chain up to parent's key_press_event() method. */ + return GTK_WIDGET_CLASS (comp_editor_parent_class)-> + key_press_event (widget, event); +} + +static gboolean +comp_editor_drag_motion (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + guint time) +{ + CompEditorPrivate *priv; + EAttachmentView *view; + + priv = COMP_EDITOR_GET_PRIVATE (widget); + view = E_ATTACHMENT_VIEW (priv->attachment_view); + + return e_attachment_view_drag_motion (view, context, x, y, time); +} + +static void +comp_editor_drag_data_received (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *selection, + guint info, + guint time) +{ + CompEditorPrivate *priv; + EAttachmentView *view; + + priv = COMP_EDITOR_GET_PRIVATE (widget); + view = E_ATTACHMENT_VIEW (priv->attachment_view); + + /* Forward the data to the attachment view. Note that calling + * e_attachment_view_drag_data_received() will not work because + * that function only handles the case where all the other drag + * handlers have failed. */ + e_attachment_paned_drag_data_received ( + E_ATTACHMENT_PANED (view), + context, x, y, selection, info, time); +} + static void comp_editor_class_init (CompEditorClass *class) { GObjectClass *object_class; GtkWidgetClass *widget_class; - int i; - - for (i = 0; i < G_N_ELEMENTS (drag_info); i++) - drag_info[i].atom = gdk_atom_intern(drag_info[i].target, FALSE); g_type_class_add_private (class, sizeof (CompEditorPrivate)); @@ -1715,6 +1443,10 @@ comp_editor_class_init (CompEditorClass *class) widget_class = GTK_WIDGET_CLASS (class); widget_class->map = comp_editor_map; + widget_class->delete_event = comp_editor_delete_event; + widget_class->key_press_event = comp_editor_key_press_event; + widget_class->drag_motion = comp_editor_drag_motion; + widget_class->drag_data_received = comp_editor_drag_data_received; class->help_section = "usage-calendar"; class->edit_comp = real_edit_comp; @@ -1777,19 +1509,18 @@ comp_editor_class_init (CompEditorClass *class) } static void -classification_changed_cb (GtkRadioAction *action, GtkRadioAction *current, CompEditor *editor) -{ - g_return_if_fail (IS_COMP_EDITOR (editor)); - - comp_editor_set_changed (editor, TRUE); -} - -static void comp_editor_init (CompEditor *editor) { CompEditorPrivate *priv; + EAttachmentView *view; + GdkDragAction drag_actions; + GtkTargetList *target_list; + GtkTargetEntry *targets; GtkActionGroup *action_group; GtkAction *action; + GtkWidget *container; + GtkWidget *widget; + gint n_targets; GError *error = NULL; editor->priv = priv = COMP_EDITOR_GET_PRIVATE (editor); @@ -1798,17 +1529,18 @@ comp_editor_init (CompEditor *editor) priv->changed = FALSE; priv->needs_send = FALSE; priv->mod = CALOBJ_MOD_ALL; - priv->existing_org = FALSE; - priv->user_org = FALSE; - priv->warned = FALSE; + priv->existing_org = FALSE; + priv->user_org = FALSE; + priv->warned = FALSE; priv->is_group_item = FALSE; - priv->attachment_bar = e_attachment_bar_new (NULL); priv->manager = gtk_ui_manager_new (); - gtk_window_add_accel_group ( - GTK_WINDOW (editor), - gtk_ui_manager_get_accel_group (priv->manager)); + gtk_window_add_accel_group ( + GTK_WINDOW (editor), + gtk_ui_manager_get_accel_group (priv->manager)); + + /* Setup Action Groups */ action_group = gtk_action_group_new ("core"); gtk_action_group_set_translation_domain ( @@ -1833,11 +1565,7 @@ comp_editor_init (CompEditor *editor) action_group, classification_radio_entries, G_N_ELEMENTS (classification_radio_entries), E_CAL_COMPONENT_CLASS_PUBLIC, - G_CALLBACK (classification_changed_cb), editor); - action = e_attachment_bar_recent_action_new ( - E_ATTACHMENT_BAR (priv->attachment_bar), - "attach-recent", _("Recent _Documents")); - gtk_action_group_add_action (action_group, action); + G_CALLBACK (action_classification_cb), editor); gtk_ui_manager_insert_action_group ( priv->manager, action_group, 0); g_object_unref (action_group); @@ -1867,14 +1595,57 @@ comp_editor_init (CompEditor *editor) g_error_free (error); } - setup_widgets (editor); + /* Setup Widgets */ + + container = GTK_WIDGET (editor); + + widget = gtk_vbox_new (FALSE, 0); + gtk_container_add (GTK_CONTAINER (container), widget); + gtk_widget_show (widget); + + container = widget; + + widget = comp_editor_get_managed_widget (editor, "/main-menu"); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + gtk_widget_show (widget); + + widget = comp_editor_get_managed_widget (editor, "/main-toolbar"); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + gtk_widget_show (widget); + + widget = e_attachment_paned_new (); + gtk_container_set_border_width (GTK_CONTAINER (widget), 6); + gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); + priv->attachment_view = g_object_ref (widget); + gtk_widget_show (widget); + + container = e_attachment_paned_get_content_area ( + E_ATTACHMENT_PANED (priv->attachment_view)); + + widget = gtk_notebook_new (); + gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE); + gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); + priv->notebook = GTK_NOTEBOOK (widget); + gtk_widget_show (widget); + + comp_editor_setup_recent_menu (editor); - /* DND support */ - gtk_drag_dest_set (GTK_WIDGET (editor), GTK_DEST_DEFAULT_ALL, drop_types, num_drop_types, GDK_ACTION_COPY|GDK_ACTION_ASK|GDK_ACTION_MOVE); - g_signal_connect(editor, "drag_data_received", G_CALLBACK (drag_data_received), NULL); - g_signal_connect(editor, "drag-motion", G_CALLBACK(drag_motion), editor); + /* Drag-and-Drop Support */ - gtk_window_set_type_hint (GTK_WINDOW (editor), GDK_WINDOW_TYPE_HINT_NORMAL); + view = E_ATTACHMENT_VIEW (priv->attachment_view); + target_list = e_attachment_view_get_target_list (view); + drag_actions = e_attachment_view_get_drag_actions (view); + + targets = gtk_target_table_new_from_list (target_list, &n_targets); + + gtk_drag_dest_set ( + GTK_WIDGET (editor), GTK_DEST_DEFAULT_ALL, + targets, n_targets, drag_actions); + + gtk_target_table_free (targets, n_targets); + + gtk_window_set_type_hint ( + GTK_WINDOW (editor), GDK_WINDOW_TYPE_HINT_NORMAL); } static gboolean @@ -1927,402 +1698,17 @@ prompt_and_save_changes (CompEditor *editor, gboolean send) } } -static int -delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data) -{ - CompEditor *editor = COMP_EDITOR (data); - - commit_all_fields (editor); - - if (prompt_and_save_changes (editor, TRUE)) - close_dialog (editor); - - return TRUE; -} - static void -attachment_bar_changed_cb (EAttachmentBar *bar, - void *data) +attachment_store_changed_cb (CompEditor *editor) { - CompEditor *editor = COMP_EDITOR (data); - - guint attachment_num = e_attachment_bar_get_num_attachments ( - E_ATTACHMENT_BAR (editor->priv->attachment_bar)); - if (attachment_num) { - gchar *num_text = g_strdup_printf ( - ngettext ("<b>%d</b> Attachment", "<b>%d</b> Attachments", attachment_num), - attachment_num); - gtk_label_set_markup (GTK_LABEL (editor->priv->attachment_expander_num), - num_text); - g_free (num_text); - - gtk_widget_show (editor->priv->attachment_expander_icon); - e_expander_set_expanded(E_EXPANDER(editor->priv->attachment_expander),TRUE); - - } else { - gtk_label_set_text (GTK_LABEL (editor->priv->attachment_expander_num), ""); - gtk_widget_hide (editor->priv->attachment_expander_icon); - e_expander_set_expanded(E_EXPANDER(editor->priv->attachment_expander),FALSE); - } - - /* Mark the editor as changed so it prompts about unsaved changes on close */ comp_editor_set_changed (editor, TRUE); - -} - -static void -attachment_expander_activate_cb (EExpander *expander, - void *data) -{ - CompEditor *editor = COMP_EDITOR (data); - gboolean show = e_expander_get_expanded (expander); - - /* Update the expander label */ - if (show) - gtk_label_set_text_with_mnemonic (GTK_LABEL (editor->priv->attachment_expander_label), - _("Hide Attachment _Bar")); - else - gtk_label_set_text_with_mnemonic (GTK_LABEL (editor->priv->attachment_expander_label), - _("Show Attachment _Bar")); -} - -static gboolean -open_attachment (EAttachmentBar *bar, CompEditor *editor) -{ - GnomeIconList *icon_list; - GList *p; - int num; - char *attach_file_url; - - if (E_IS_ATTACHMENT_BAR (bar)) { - icon_list = GNOME_ICON_LIST (bar); - p = gnome_icon_list_get_selection (icon_list); - if (p) { - EAttachment *attachment; - GSList *list; - const char *comp_uid = NULL; - char *filename = NULL; - const char *local_store = e_cal_get_local_attachment_store (editor->priv->client); - - e_cal_component_get_uid (editor->priv->comp, &comp_uid); - num = GPOINTER_TO_INT (p->data); - list = e_attachment_bar_get_attachment (bar, num); - attachment = list->data; - g_slist_free (list); - - filename = g_strdup_printf ("%s-%s", - comp_uid, - camel_mime_part_get_filename(attachment->body)); - - attach_file_url = g_build_path ("/", local_store, filename, NULL); - - /* launch the url now */ - e_show_uri (GTK_WINDOW (editor), attach_file_url); - - g_free (filename); - g_free (attach_file_url); } - return TRUE; - } else - return FALSE; -} - -static gboolean -attachment_bar_icon_clicked_cb (EAttachmentBar *bar, GdkEvent *event, CompEditor *editor) -{ - if (E_IS_ATTACHMENT_BAR (bar) && event->type == GDK_2BUTTON_PRESS) - if (open_attachment (bar, editor)) - return TRUE; - return FALSE; -} - -/* Callbacks. */ - -static void -cab_open(EPopup *ep, EPopupItem *item, void *data) -{ - EAttachmentBar *bar = data; - CompEditor *editor = COMP_EDITOR (gtk_widget_get_toplevel (GTK_WIDGET (bar))); - - if (!open_attachment (bar, editor)) - g_message ("\n Open failed"); -} - -static void -cab_add(EPopup *ep, EPopupItem *item, void *data) -{ - EAttachmentBar *bar = data; - CompEditor *editor = COMP_EDITOR (gtk_widget_get_toplevel (GTK_WIDGET (bar))); - GPtrArray *file_list; - gboolean is_inline = FALSE; - int i; - - file_list = comp_editor_select_file_attachments (editor, &is_inline); - /*TODO add a good implementation here */ - if (!file_list) - return; - for (i = 0; i < file_list->len; i++) { - CamelURL *url; - - url = camel_url_new (file_list->pdata[i], NULL); - if (url == NULL) - continue; - - if (!g_ascii_strcasecmp (url->protocol, "file")) - e_attachment_bar_attach (bar, url->path, is_inline ? "inline" : "attachment"); - else - e_attachment_bar_attach_remote_file (bar, file_list->pdata[i], is_inline ? "inline" : "attachment"); - g_free (file_list->pdata[i]); - camel_url_free (url); - } - - g_ptr_array_free (file_list, TRUE); -} - -static void -cab_properties(EPopup *ep, EPopupItem *item, void *data) -{ - EAttachmentBar *bar = data; - - e_attachment_bar_edit_selected(bar); -} - -static void -cab_remove(EPopup *ep, EPopupItem *item, void *data) -{ - EAttachmentBar *bar = data; - - e_attachment_bar_remove_selected(bar); -} - -/* Popup menu handling. */ -static EPopupItem cab_popups[] = { - { E_POPUP_ITEM, "10.attach", N_("_Open"), cab_open, NULL, GTK_STOCK_OPEN, E_CAL_POPUP_ATTACHMENTS_ONE}, - { E_POPUP_ITEM, "20.attach", N_("_Remove"), cab_remove, NULL, GTK_STOCK_REMOVE, E_CAL_POPUP_ATTACHMENTS_MANY | E_CAL_POPUP_ATTACHMENTS_MODIFY }, - { E_POPUP_ITEM, "30.attach", N_("_Properties"), cab_properties, NULL, GTK_STOCK_PROPERTIES, E_CAL_POPUP_ATTACHMENTS_ONE }, - { E_POPUP_BAR, "40.attach.00", NULL, NULL, NULL, NULL, E_CAL_POPUP_ATTACHMENTS_MANY|E_CAL_POPUP_ATTACHMENTS_ONE }, - { E_POPUP_ITEM, "40.attach.01", N_("_Add attachment..."), cab_add, NULL, GTK_STOCK_ADD, E_CAL_POPUP_ATTACHMENTS_MODIFY}, -}; - -static void -cab_popup_position(GtkMenu *menu, int *x, int *y, gboolean *push_in, gpointer user_data) -{ - EAttachmentBar *bar = user_data; - GnomeIconList *icon_list = user_data; - GList *selection; - GnomeCanvasPixbuf *image; - - gdk_window_get_origin (((GtkWidget*) bar)->window, x, y); - - selection = gnome_icon_list_get_selection (icon_list); - if (selection == NULL) - return; - - image = gnome_icon_list_get_icon_pixbuf_item (icon_list, GPOINTER_TO_INT(selection->data)); - if (image == NULL) - return; - - /* Put menu to the center of icon. */ - *x += (int)(image->item.x1 + image->item.x2) / 2; - *y += (int)(image->item.y1 + image->item.y2) / 2; -} - -static void -cab_popups_free(EPopup *ep, GSList *l, void *data) -{ - g_slist_free(l); -} - -/* if id != -1, then use it as an index for target of the popup */ -static void -cab_popup(EAttachmentBar *bar, GdkEventButton *event, int id) -{ - GSList *attachments = NULL, *menus = NULL; - int i; - ECalPopup *ecp; - ECalPopupTargetAttachments *t; - GtkMenu *menu; - CompEditor *editor = COMP_EDITOR (gtk_widget_get_toplevel (GTK_WIDGET (bar))); - - attachments = e_attachment_bar_get_attachment(bar, id); - - for (i=0;i<sizeof(cab_popups)/sizeof(cab_popups[0]);i++) - menus = g_slist_prepend(menus, &cab_popups[i]); - - /** @HookPoint-ECalPopup: Calendar Attachment Bar Context Menu - * @Id: org.gnome.evolution.calendar.attachmentbar.popup - * @Class: org.gnome.evolution.mail.popup:1.0 - * @Target: ECalPopupTargetAttachments - * - * This is the context menu on the calendar attachment bar. - */ - ecp = e_cal_popup_new("org.gnome.evolution.calendar.attachmentbar.popup"); - e_popup_add_items((EPopup *)ecp, menus, NULL, cab_popups_free, bar); - t = e_cal_popup_target_new_attachments(ecp, editor, attachments); - t->target.widget = (GtkWidget *)bar; - menu = e_popup_create_menu_once((EPopup *)ecp, (EPopupTarget *)t, 0); - - if (event == NULL) - gtk_menu_popup(menu, NULL, NULL, cab_popup_position, bar, 0, gtk_get_current_event_time()); - else - gtk_menu_popup(menu, NULL, NULL, NULL, NULL, event->button, event->time); -} - -/* GtkWidget methods. */ - -static gboolean -popup_menu_event (EAttachmentBar *bar) -{ - cab_popup (bar, NULL, -1); - - return TRUE; -} - - -static int -button_press_event (EAttachmentBar *bar, - GdkEventButton *event) -{ - GnomeIconList *icon_list = GNOME_ICON_LIST (bar); - int icon_number = -1; - - if (event->button != 3) - return FALSE; - - if (!gnome_icon_list_get_selection (icon_list)) { - icon_number = gnome_icon_list_get_icon_at (icon_list, event->x, event->y); - if (icon_number >= 0) { - gnome_icon_list_unselect_all(icon_list); - gnome_icon_list_select_icon (icon_list, icon_number); - } - } - - cab_popup(bar, event, icon_number); - - return TRUE; -} - -static gint -key_press_event (EAttachmentBar *bar, - GdkEventKey *event) -{ - if (event->keyval == GDK_Delete) { - e_attachment_bar_remove_selected (bar); - return TRUE; - } - - return FALSE; -} - -static gint -editor_key_press_event (CompEditor *editor, - GdkEventKey *event) -{ - if (event->keyval == GDK_Escape) { - commit_all_fields (editor); - - if (prompt_and_save_changes (editor, TRUE)) - close_dialog (editor); - - return TRUE; - } - - return FALSE; } /* Menu callbacks */ static void -setup_widgets (CompEditor *editor) -{ - CompEditorPrivate *priv; - GtkWidget *expander_hbox; - GtkWidget *widget; - GtkWidget *vbox; - - priv = editor->priv; - - /* Useful vbox */ - vbox = gtk_vbox_new (FALSE, 0); - gtk_container_add (GTK_CONTAINER (editor), vbox); - gtk_widget_show (vbox); - - /* Main Menu */ - widget = comp_editor_get_managed_widget (editor, "/main-menu"); - gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0); - gtk_widget_show (widget); - - /* Main Toolbar */ - widget = comp_editor_get_managed_widget (editor, "/main-toolbar"); - gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0); - gtk_widget_show (widget); - - /* Notebook */ - widget = gtk_notebook_new (); - gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE); - gtk_box_pack_start (GTK_BOX (vbox), widget, TRUE, TRUE, 0); - gtk_widget_show (widget); - priv->notebook = GTK_NOTEBOOK (widget); - - g_signal_connect (editor, "delete_event", G_CALLBACK (delete_event_cb), editor); - g_signal_connect (editor, "key_press_event", G_CALLBACK (editor_key_press_event), editor); - - /*Attachments */ - priv->attachment_scrolled_window = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->attachment_scrolled_window), - GTK_SHADOW_IN); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->attachment_scrolled_window), - GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - - g_signal_connect (priv->attachment_bar, "button_press_event", G_CALLBACK (button_press_event), NULL); - g_signal_connect (priv->attachment_bar, "key_press_event", G_CALLBACK (key_press_event), NULL); - g_signal_connect (priv->attachment_bar, "popup-menu", G_CALLBACK (popup_menu_event), NULL); - - GTK_WIDGET_SET_FLAGS (priv->attachment_bar, GTK_CAN_FOCUS); - gtk_container_add (GTK_CONTAINER (priv->attachment_scrolled_window), - priv->attachment_bar); - gtk_widget_show (priv->attachment_bar); - g_signal_connect (priv->attachment_bar, "changed", - G_CALLBACK (attachment_bar_changed_cb), editor); - g_signal_connect (GNOME_ICON_LIST (priv->attachment_bar), "event", - G_CALLBACK (attachment_bar_icon_clicked_cb), editor); - priv->attachment_expander_label = - gtk_label_new_with_mnemonic (_("Show Attachment _Bar")); - priv->attachment_expander_num = gtk_label_new (""); - gtk_label_set_use_markup (GTK_LABEL (priv->attachment_expander_num), TRUE); - gtk_misc_set_alignment (GTK_MISC (priv->attachment_expander_label), 0.0, 0.5); - gtk_misc_set_alignment (GTK_MISC (priv->attachment_expander_num), 1.0, 0.5); - expander_hbox = gtk_hbox_new (FALSE, 0); - - priv->attachment_expander_icon = gtk_image_new_from_icon_name ("mail-attachment", GTK_ICON_SIZE_MENU); - gtk_misc_set_alignment (GTK_MISC (priv->attachment_expander_icon), 1, 0.5); - gtk_widget_set_size_request (priv->attachment_expander_icon, 100, -1); - - gtk_box_pack_start (GTK_BOX (expander_hbox), priv->attachment_expander_label, - TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (expander_hbox), priv->attachment_expander_icon, - TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (expander_hbox), priv->attachment_expander_num, - TRUE, TRUE, 0); - gtk_widget_show_all (expander_hbox); - gtk_widget_hide (priv->attachment_expander_icon); - - priv->attachment_expander = e_expander_new (""); - e_expander_set_label_widget (E_EXPANDER (priv->attachment_expander), expander_hbox); - atk_object_set_name (gtk_widget_get_accessible (priv->attachment_expander), _("Show Attachments")); - atk_object_set_description (gtk_widget_get_accessible (priv->attachment_expander), _("Press space key to toggle attachment bar")); - gtk_container_add (GTK_CONTAINER (priv->attachment_expander), priv->attachment_scrolled_window); - - gtk_box_pack_start (GTK_BOX (vbox), priv->attachment_expander, FALSE, FALSE, 4); - gtk_widget_show (priv->attachment_expander); - e_expander_set_expanded (E_EXPANDER (priv->attachment_expander), FALSE); - g_signal_connect_after (priv->attachment_expander, "activate", - G_CALLBACK (attachment_expander_activate_cb), editor); -} - - -static void comp_editor_show_help (CompEditor *editor) { CompEditorClass *class; @@ -2861,12 +2247,14 @@ comp_editor_get_client (CompEditor *editor) static void set_attachment_list (CompEditor *editor, GSList *attach_list) { - GSList *p = NULL; - const char *comp_uid= NULL; + EAttachmentStore *store; + EAttachmentView *view; + GSList *iter = NULL; - e_cal_component_get_uid (editor->priv->comp, &comp_uid); + view = E_ATTACHMENT_VIEW (editor->priv->attachment_view); + store = e_attachment_view_get_store (view); - if (e_attachment_bar_get_num_attachments (E_ATTACHMENT_BAR (editor->priv->attachment_bar))) { + if (e_attachment_store_get_num_attachments (store) > 0) { /* To prevent repopulating the * bar due to redraw functions in fill_widget. * Assumes it can be set only once. @@ -2874,112 +2262,55 @@ set_attachment_list (CompEditor *editor, GSList *attach_list) return; } - for (p = attach_list; p != NULL; p = p->next) { - char *attach_filename; - CamelMimePart *part; - CamelDataWrapper *wrapper; - CamelStream *stream; - struct stat statbuf; - char *mime_type, *file_name; - char *ptr; - - attach_filename = (char *) p->data; - /* should we assert if g_str_has_prefix (attach_filename, "file://")) - * here - */ - /* get url sans protocol and add it to the bar. - * how to set the filename properly */ - file_name = g_filename_from_uri (attach_filename, NULL, NULL); - if (!file_name) - continue; - - if (g_stat (file_name, &statbuf) < 0) { - g_warning ("Cannot attach file %s: %s", file_name, g_strerror (errno)); - g_free (file_name); - continue; - } - - /* return if it's not a regular file */ - if (!S_ISREG (statbuf.st_mode)) { - g_warning ("Cannot attach file %s: not a regular file", file_name); - g_free (file_name); - return; - } - - stream = camel_stream_fs_new_with_name (file_name, O_RDONLY, 0); - if (!stream) { - g_warning ("Cannot attach file %s: %s", file_name, g_strerror (errno)); - g_free (file_name); - return; - } - - mime_type = e_util_guess_mime_type (file_name, TRUE); - if (mime_type) { - if (!g_ascii_strcasecmp (mime_type, "message/rfc822")) { - wrapper = (CamelDataWrapper *) camel_mime_message_new (); - } else { - wrapper = camel_data_wrapper_new (); - } - - camel_data_wrapper_construct_from_stream (wrapper, stream); - camel_data_wrapper_set_mime_type (wrapper, mime_type); - g_free (mime_type); - } else { - wrapper = camel_data_wrapper_new (); - camel_data_wrapper_construct_from_stream (wrapper, stream); - camel_data_wrapper_set_mime_type (wrapper, "application/octet-stream"); - } - - camel_object_unref (stream); - - part = camel_mime_part_new (); - camel_medium_set_content_object (CAMEL_MEDIUM (part), wrapper); - camel_object_unref (wrapper); + for (iter = attach_list; iter != NULL; iter = iter->next) { + EAttachment *attachment; + const gchar *uri = iter->data; - camel_mime_part_set_disposition (part, "attachment"); - - ptr = strstr (file_name, comp_uid); - if (ptr) { - ptr += strlen(comp_uid); - if (*ptr++ == '-') - camel_mime_part_set_filename (part, ptr); - } - g_free (file_name); - - e_attachment_bar_attach_mime_part ((EAttachmentBar *) editor->priv->attachment_bar, part); - e_expander_set_expanded (E_EXPANDER (editor->priv->attachment_expander), TRUE); - - camel_object_unref (part); + attachment = e_attachment_new_for_uri (uri); + e_attachment_store_add_attachment (store, attachment); + e_attachment_load_async ( + attachment, (GAsyncReadyCallback) + e_attachment_load_handle_error, editor); + g_object_unref (attachment); } } static void fill_widgets (CompEditor *editor) { + EAttachmentStore *store; + EAttachmentView *view; CompEditorPrivate *priv; GList *l; GtkAction *action; + view = E_ATTACHMENT_VIEW (editor->priv->attachment_view); + store = e_attachment_view_get_store (view); + priv = editor->priv; /*Check if attachments are available here and set them*/ if (e_cal_component_has_attachments (priv->comp)) { GSList *attachment_list = NULL; e_cal_component_get_attachment_list (priv->comp, &attachment_list); - g_signal_handlers_block_by_func(priv->attachment_bar, G_CALLBACK (attachment_bar_changed_cb), editor); + g_signal_handlers_block_by_func ( + store, G_CALLBACK (attachment_store_changed_cb), + editor); set_attachment_list (editor, attachment_list); - g_signal_handlers_unblock_by_func(priv->attachment_bar, G_CALLBACK (attachment_bar_changed_cb), editor); + g_signal_handlers_unblock_by_func ( + store, G_CALLBACK (attachment_store_changed_cb), + editor); g_slist_foreach (attachment_list, (GFunc)g_free, NULL); g_slist_free (attachment_list); } action = comp_editor_get_action (editor, "classify-public"); - g_signal_handlers_block_by_func (action, G_CALLBACK (classification_changed_cb), editor); + g_signal_handlers_block_by_func (action, G_CALLBACK (action_classification_cb), editor); for (l = priv->pages; l != NULL; l = l->next) comp_editor_page_fill_widgets (l->data, priv->comp); - g_signal_handlers_unblock_by_func (action, G_CALLBACK (classification_changed_cb), editor); + g_signal_handlers_unblock_by_func (action, G_CALLBACK (action_classification_cb), editor); } static void @@ -3303,20 +2634,41 @@ comp_editor_close (CompEditor *editor) GSList * comp_editor_get_mime_attach_list (CompEditor *editor) { + EAttachmentStore *store; + EAttachmentView *view; + GtkTreeModel *model; + GtkTreeIter iter; struct CalMimeAttach *cal_mime_attach; - GSList *attach_list = NULL, *l, *parts; + GSList *attach_list = NULL; + gboolean valid; + + view = E_ATTACHMENT_VIEW (editor->priv->attachment_view); + store = e_attachment_view_get_store (view); - /* TODO assert sanity of bar */ - parts = e_attachment_bar_get_parts (E_ATTACHMENT_BAR (editor->priv->attachment_bar)); - for (l = parts; l ; l = l->next) { + model = GTK_TREE_MODEL (store); + valid = gtk_tree_model_get_iter_first (model, &iter); + while (valid) { + EAttachment *attachment; CamelDataWrapper *wrapper; + CamelMimePart *mime_part; CamelStreamMem *mstream; unsigned char *buffer = NULL; const char *desc, *disp; + gint column_id; + + column_id = E_ATTACHMENT_STORE_COLUMN_ATTACHMENT; + gtk_tree_model_get (model, &iter, column_id, &attachment, -1); + mime_part = e_attachment_get_mime_part (attachment); + g_object_unref (attachment); + + valid = gtk_tree_model_iter_next (model, &iter); + + if (mime_part == NULL) + continue; cal_mime_attach = g_malloc0 (sizeof (struct CalMimeAttach)); - wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (l->data)); + wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)); mstream = (CamelStreamMem *) camel_stream_mem_new (); camel_data_wrapper_decode_to_stream (wrapper, (CamelStream *) mstream); @@ -3324,15 +2676,14 @@ comp_editor_get_mime_attach_list (CompEditor *editor) cal_mime_attach->encoded_data = (char *)buffer; cal_mime_attach->length = mstream->buffer->len; - cal_mime_attach->filename = g_strdup (camel_mime_part_get_filename - ((CamelMimePart *) l->data)); - desc = camel_mime_part_get_description ((CamelMimePart *) l->data); + cal_mime_attach->filename = g_strdup (camel_mime_part_get_filename (mime_part)); + desc = camel_mime_part_get_description (mime_part); if (!desc || *desc == '\0') desc = _("attachment"); cal_mime_attach->description = g_strdup (desc); cal_mime_attach->content_type = g_strdup (camel_data_wrapper_get_mime_type (wrapper)); - disp = camel_mime_part_get_disposition ((CamelMimePart *)l->data); + disp = camel_mime_part_get_disposition (mime_part); if (disp && !g_ascii_strcasecmp(disp, "inline")) cal_mime_attach->disposition = TRUE; @@ -3342,8 +2693,6 @@ comp_editor_get_mime_attach_list (CompEditor *editor) } - g_slist_free (parts); - return attach_list; } diff --git a/calendar/gui/dialogs/event-editor.c b/calendar/gui/dialogs/event-editor.c index a579d77348..f32f24501d 100644 --- a/calendar/gui/dialogs/event-editor.c +++ b/calendar/gui/dialogs/event-editor.c @@ -512,8 +512,6 @@ event_editor_init (EventEditor *ee) g_signal_connect_swapped ( ee->priv->model, "row_deleted", G_CALLBACK (event_editor_model_changed_cb), ee); - - gtk_window_set_default_size (GTK_WINDOW (ee), 300, 225); } static void diff --git a/calendar/gui/e-cal-popup.c b/calendar/gui/e-cal-popup.c index b9f0d5f8d5..0292f16c71 100644 --- a/calendar/gui/e-cal-popup.c +++ b/calendar/gui/e-cal-popup.c @@ -86,378 +86,11 @@ ecalp_target_free(EPopup *ep, EPopupTarget *t) /* Standard menu code */ -static char * -temp_save_part(CamelMimePart *part, char *path, gboolean file) -{ - const char *filename; - char *tmpdir, *utf8_mfilename = NULL, *mfilename = NULL, *usepath; - CamelStream *stream; - CamelDataWrapper *wrapper; - - if (!path) { - tmpdir = e_mkdtemp("evolution-tmp-XXXXXX"); - if (tmpdir == NULL) { - return NULL; - } - - filename = camel_mime_part_get_filename (part); - if (filename == NULL) { - /* This is the default filename used for temporary file creation */ - filename = _("Unknown"); - } else { - utf8_mfilename = g_strdup (filename); - e_filename_make_safe (utf8_mfilename); - mfilename = g_filename_from_utf8 ((const char *) utf8_mfilename, -1, NULL, NULL, NULL); - g_free (utf8_mfilename); - filename = (const char *) mfilename; - } - - path = g_build_filename(tmpdir, filename, NULL); - g_free(tmpdir); - g_free(mfilename); - } else if (!file) { - tmpdir = path; - filename = camel_mime_part_get_filename (part); - if (filename == NULL) { - /* This is the default filename used for temporary file creation */ - filename = _("Unknown"); - } else { - utf8_mfilename = g_strdup (filename); - e_filename_make_safe (utf8_mfilename); - mfilename = g_filename_from_utf8 ((const char *)utf8_mfilename, -1, NULL, NULL, NULL); - g_free (utf8_mfilename); - filename = (const char *) mfilename; - } - - path = g_build_filename(tmpdir, filename, NULL); - g_free(mfilename); - } - - if (strstr (path, "://")) - usepath = path; - else - usepath = g_strjoin (NULL, "file://", path, NULL); - - wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (part)); - stream = camel_stream_vfs_new_with_uri (usepath, CAMEL_STREAM_VFS_CREATE); - - if (usepath != path) - g_free (usepath); - - if (!stream) { - /* TODO handle error conditions */ - g_message ("DEBUG: could not open the file to write\n"); - return NULL; - } - - if (camel_data_wrapper_decode_to_stream (wrapper, (CamelStream *) stream) == -1) { - camel_stream_close (stream); - camel_object_unref (stream); - g_message ("DEBUG: could not write to file\n"); - return NULL; - } - - camel_stream_close(stream); - camel_object_unref(stream); - - return path; -} - -static void -ecalp_part_popup_saveas(EPopup *ep, EPopupItem *item, void *data) -{ - EPopupTarget *t = ep->target; - CamelMimePart *part = NULL; - char *file, *mfilename = NULL; - const char *filename; - - part = ((EAttachment *) ((ECalPopupTargetAttachments *) t)->attachments->data)->body; - filename = camel_mime_part_get_filename (part); - if (filename == NULL) { - /* This is the default filename used for temporary file creation */ - filename = _("Unknown"); - } else { - mfilename = g_strdup(filename); - e_filename_make_safe(mfilename); - filename = mfilename; - } - file = e_file_dialog_save (_("Save As..."), filename); - - if (file) - temp_save_part (part, file, TRUE); - - g_free (file); - g_free (mfilename); -} - -static void -ecalp_part_popup_save_selected(EPopup *ep, EPopupItem *item, void *data) -{ - GSList *parts; - EPopupTarget *t = ep->target; - char *dir, *path; - - dir = e_file_dialog_save_folder (_("Select folder to save selected attachments...")); - parts = ((ECalPopupTargetAttachments *) t)->attachments; - - for (;parts; parts=parts->next) { - path = temp_save_part (((EAttachment *)parts->data)->body, dir, FALSE); - /* Probably we 'll do some reporting in next release, like listing the saved files and locations */ - g_free (path); - } -} - -static void -ecalp_part_popup_set_background(EPopup *ep, EPopupItem *item, void *data) -{ - EPopupTarget *t = ep->target; - GConfClient *gconf; - char *str, *filename, *path, *extension; - unsigned int i=1; - CamelMimePart *part = NULL; - - part = ((EAttachment *) ((ECalPopupTargetAttachments *) t)->attachments->data)->body; - - if (!part) - return; - - filename = g_strdup(camel_mime_part_get_filename(part)); - - /* if filename is blank, create a default filename based on MIME type */ - if (!filename || !filename[0]) { - CamelContentType *ct; - - ct = camel_mime_part_get_content_type(part); - g_free (filename); - filename = g_strdup_printf (_("untitled_image.%s"), ct->subtype); - } - - e_filename_make_safe(filename); - - path = g_build_filename(g_get_home_dir(), ".gnome2", "wallpapers", filename, NULL); - - extension = strrchr(filename, '.'); - if (extension) - *extension++ = 0; - - /* if file exists, stick a (number) on the end */ - while (g_file_test(path, G_FILE_TEST_EXISTS)) { - char *name; - name = g_strdup_printf(extension?"%s (%d).%s":"%s (%d)", filename, i++, extension); - g_free(path); - path = g_build_filename(g_get_home_dir(), ".gnome2", "wallpapers", name, NULL); - g_free(name); - } - - g_free(filename); - - if (temp_save_part(part, path, TRUE)) { - gconf = gconf_client_get_default(); - - /* if the filename hasn't changed, blank the filename before - * setting it so that gconf detects a change and updates it */ - if ((str = gconf_client_get_string(gconf, "/desktop/gnome/background/picture_filename", NULL)) != NULL - && strcmp (str, path) == 0) { - gconf_client_set_string(gconf, "/desktop/gnome/background/picture_filename", "", NULL); - } - - g_free (str); - gconf_client_set_string(gconf, "/desktop/gnome/background/picture_filename", path, NULL); - - /* if GNOME currently doesn't display a picture, set to "wallpaper" - * display mode, otherwise leave it alone */ - if ((str = gconf_client_get_string(gconf, "/desktop/gnome/background/picture_options", NULL)) == NULL - || strcmp(str, "none") == 0) { - gconf_client_set_string(gconf, "/desktop/gnome/background/picture_options", "wallpaper", NULL); - } - - gconf_client_suggest_sync(gconf, NULL); - - g_free(str); - g_object_unref(gconf); - } - - g_free(path); -} - -static const EPopupItem ecalp_standard_part_apps_bar = { E_POPUP_BAR, "99.object" }; - -static ECalPopupItem ecalp_attachment_object_popups[] = { - { E_POPUP_ITEM, "00.attach.00", N_("_Save As..."), ecalp_part_popup_saveas, NULL, "document-save-as", E_CAL_POPUP_ATTACHMENTS_ONE }, - { E_POPUP_ITEM, "00.attach.10", N_("Set as _Background"), ecalp_part_popup_set_background, NULL, NULL, E_CAL_POPUP_ATTACHMENTS_IMAGE }, - { E_POPUP_ITEM, "00.attach.20", N_("_Save Selected"), ecalp_part_popup_save_selected, NULL, "document-save-as", E_CAL_POPUP_ATTACHMENTS_MULTIPLE }, - { E_POPUP_BAR, "05.attach", }, -}; - -static void -ecalp_apps_open_in(EPopup *ep, EPopupItem *item, void *data) -{ - char *path; - EPopupTarget *target = ep->target; - CamelMimePart *part; - - part = ((EAttachment *) ((ECalPopupTargetAttachments *) target)->attachments->data)->body; - - path = temp_save_part(part, NULL, FALSE); - if (path) { - GAppInfo *app = item->user_data; - GList *uris = NULL; - GError *error = NULL; - - if (g_app_info_supports_files (app)) { - GFile *file = g_file_new_for_path (path); - - uris = g_list_append (uris, file); - g_app_info_launch (app, uris, NULL, &error); - g_object_unref (file); - } else { - char *uri; - - uri = e_util_filename_to_uri (path); - uris = g_list_append (uris, uri); - - g_app_info_launch_uris (app, uris, NULL, &error); - g_free (uri); - } - - if (error) { - g_warning ("%s", error->message); - g_error_free (error); - } - - g_list_free (uris); - g_free (path); - } -} - -static void -ecalp_apps_popup_free(EPopup *ep, GSList *free_list, void *data) -{ - while (free_list) { - GSList *n = free_list->next; - EPopupItem *item = free_list->data; - - if (item->user_data && item->activate == ecalp_apps_open_in) - g_object_unref (item->user_data); - - g_free(item->path); - g_free(item->label); - g_free(item); - g_slist_free_1(free_list); - - free_list = n; - } -} - -static void -ecalp_standard_items_free(EPopup *ep, GSList *items, void *data) -{ - g_slist_free(items); -} - -static void -ecalp_standard_menu_factory (EPopup *ecalp, void *data) -{ - int i, len; - EPopupItem *items; - GSList *menus = NULL; - GList *apps = NULL; - char *mime_type = NULL; - const char *filename = NULL; - - switch (ecalp->target->type) { - case E_CAL_POPUP_TARGET_ATTACHMENTS: { - ECalPopupTargetAttachments *t = (ECalPopupTargetAttachments *)ecalp->target; - GSList *list = t->attachments; - EAttachment *attachment; - - items = ecalp_attachment_object_popups; - len = G_N_ELEMENTS(ecalp_attachment_object_popups); - - if (g_slist_length(list) != 1 || !((EAttachment *)list->data)->is_available_local) { - break; - } - - /* Only one attachment selected */ - attachment = list->data; - mime_type = camel_data_wrapper_get_mime_type((CamelDataWrapper *)attachment->body); - filename = camel_mime_part_get_filename(attachment->body); - - - break; } - default: - items = NULL; - len = 0; - } - - if (mime_type) { - gchar *cp; - - /* does gvfs expect lowercase MIME types? */ - for (cp = mime_type; *cp != '\0'; cp++) - *cp = g_ascii_tolower (*cp); - - cp = g_content_type_from_mime_type (mime_type); - apps = g_app_info_get_all_for_type (cp ? cp : mime_type); - g_free (cp); - - if (apps == NULL || strcmp(mime_type, "application/octet-stream") == 0) { - if (filename) { - gchar *name_type; - - name_type = e_util_guess_mime_type (filename, FALSE); - cp = g_content_type_from_mime_type (name_type); - /* show alternative apps first */ - apps = g_list_concat (g_app_info_get_all_for_type (cp ? cp : name_type), apps); - g_free (cp); - g_free (name_type); - } - } - g_free (mime_type); - - if (apps) { - GSList *open_menus = NULL; - GList *l; - - menus = g_slist_prepend(menus, (void *)&ecalp_standard_part_apps_bar); - - for (l = apps, i = 0; l; l = l->next, i++) { - GAppInfo *app = l->data; - EPopupItem *item; - - item = g_malloc0(sizeof(*item)); - item->type = E_POPUP_ITEM; - item->path = g_strdup_printf("99.object.%02d", i); - item->label = g_strdup_printf(_("Open in %s..."), g_app_info_get_name (app)); - item->activate = ecalp_apps_open_in; - item->user_data = app; - - open_menus = g_slist_prepend(open_menus, item); - } - - if (open_menus) - e_popup_add_items(ecalp, open_menus, NULL, ecalp_apps_popup_free, NULL); - - g_list_free (apps); - } - } - - for (i=0;i<len;i++) { - if ((items[i].visible & ecalp->target->mask) == 0) - menus = g_slist_prepend(menus, &items[i]); - } - - if (menus) - e_popup_add_items(ecalp, menus, NULL, ecalp_standard_items_free, NULL); -} - static void ecalp_class_init(GObjectClass *klass) { klass->finalize = ecalp_finalise; ((EPopupClass *)klass)->target_free = ecalp_target_free; - - e_popup_class_add_factory((EPopupClass *)klass, NULL, ecalp_standard_menu_factory, NULL); } GType @@ -750,56 +383,6 @@ e_cal_popup_target_new_source(ECalPopup *eabp, ESourceSelector *selector) return t; } -/** - * e_cal_popup_target_new_attachments: - * @ecp: - * @attachments: A list of CalAttachment objects, reffed for - * the list. Will be unreff'd once finished with. - * - * Owns the list @attachments and their items after they're passed in. - * - * Return value: - **/ -ECalPopupTargetAttachments * -e_cal_popup_target_new_attachments(ECalPopup *ecp, CompEditor *editor, GSList *attachments) -{ - ECalPopupTargetAttachments *t = e_popup_target_new(&ecp->popup, E_CAL_POPUP_TARGET_ATTACHMENTS, sizeof(*t)); - guint32 mask = ~0; - int len = g_slist_length(attachments); - ECal *client = comp_editor_get_client (editor); - CompEditorFlags flags = comp_editor_get_flags (editor); - gboolean read_only = FALSE; - GError *error = NULL; - - if (!e_cal_is_read_only (client, &read_only, &error)) { - if (error->code != E_CALENDAR_STATUS_BUSY) - read_only = TRUE; - g_error_free (error); - } - - if (!read_only && (!(flags & COMP_EDITOR_MEETING) || - (flags & COMP_EDITOR_NEW_ITEM) || - (flags & COMP_EDITOR_USER_ORG))) - mask &= ~ E_CAL_POPUP_ATTACHMENTS_MODIFY; - - t->attachments = attachments; - if (len > 0) - mask &= ~ E_CAL_POPUP_ATTACHMENTS_MANY; - - if (len == 1 && ((EAttachment *)attachments->data)->is_available_local) { - if (camel_content_type_is(((CamelDataWrapper *) ((EAttachment *) attachments->data)->body)->mime_type, "image", "*")) - mask &= ~ E_CAL_POPUP_ATTACHMENTS_IMAGE; - mask &= ~ E_CAL_POPUP_ATTACHMENTS_ONE; - } - - if (len > 1) - mask &= ~ E_CAL_POPUP_ATTACHMENTS_MULTIPLE; - - t->target.mask = mask; - - return t; -} - /* ********************************************************************** */ /* Popup menu plugin handler */ diff --git a/calendar/gui/e-cal-popup.h b/calendar/gui/e-cal-popup.h index fb899c3961..34874efdba 100644 --- a/calendar/gui/e-cal-popup.h +++ b/calendar/gui/e-cal-popup.h @@ -195,8 +195,6 @@ ECalPopup *e_cal_popup_new(const char *menuid); ECalPopupTargetSelect *e_cal_popup_target_new_select(ECalPopup *eabp, struct _ECalModel *model, GPtrArray *events); ECalPopupTargetSource *e_cal_popup_target_new_source(ECalPopup *eabp, struct _ESourceSelector *selector); -ECalPopupTargetAttachments * e_cal_popup_target_new_attachments (ECalPopup *ecp, - CompEditor *editor, GSList *attachments); /* ********************************************************************** */ |