diff options
Diffstat (limited to 'calendar')
-rw-r--r-- | calendar/ChangeLog | 18 | ||||
-rw-r--r-- | calendar/gui/dialogs/comp-editor.c | 50 | ||||
-rw-r--r-- | calendar/gui/e-cal-popup.c | 357 | ||||
-rw-r--r-- | calendar/gui/e-cal-popup.h | 4 | ||||
-rw-r--r-- | calendar/gui/e-calendar-table.c | 2 | ||||
-rw-r--r-- | calendar/gui/e-calendar-view.c | 2 |
6 files changed, 416 insertions, 17 deletions
diff --git a/calendar/ChangeLog b/calendar/ChangeLog index 33fa12da9f..aa6c22b673 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,3 +1,21 @@ +2005-10-18 Srinivasa Ragavan <sragavan@novell.com> + + * gui/dialogs/comp-editor.c: (open_attachment) + (attachment_bar_icon_clicked_cb), (cab_open), (cab_popup), + (button_press_event): Handles the popup menu on the attachment + bar. + * gui/e-cal-popup.c: (temp_save_part), (ecalp_part_popup_saveas), + (ecalp_part_popup_save_selected), + (ecalp_part_popup_set_background), (ecalp_apps_open_in), + (ecalp_apps_popup_free), (ecalp_standard_items_free), + (ecalp_standard_menu_factory), (ecalp_class_init), + (e_cal_popup_target_new_attachments): Provides the background + image setting, open with application for each attachment. + * gui/e-cal-popup.h: + * gui/e-calendar-table.c: (e_calendar_table_on_save_as) + * gui/e-calendar-view.c: (on_save_as): Change the parameters to + e_file_dialog_save. + 2005-10-17 Irene Huang <Irene.Huang@sun.com> * gui/e-tasks.c: (e_tasks_show_preview): Should not return a value, so, diff --git a/calendar/gui/dialogs/comp-editor.c b/calendar/gui/dialogs/comp-editor.c index 4eb6d363a7..e205bd5c68 100644 --- a/calendar/gui/dialogs/comp-editor.c +++ b/calendar/gui/dialogs/comp-editor.c @@ -141,6 +141,7 @@ static void page_dates_changed_cb (GtkObject *obj, CompEditorPageDates *dates, g 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_DIALOG); @@ -1010,8 +1011,8 @@ attachment_expander_activate_cb (EExpander *expander, _("Show Attachment _Bar")); } -static gboolean -attachment_bar_icon_clicked_cb (EAttachmentBar *bar, GdkEvent *event, CompEditor *editor) +static gboolean +open_attachment (EAttachmentBar *bar, CompEditor *editor) { GnomeIconList *icon_list; GList *p; @@ -1019,7 +1020,7 @@ attachment_bar_icon_clicked_cb (EAttachmentBar *bar, GdkEvent *event, CompEditor char *attach_file_url; GError *error = NULL; - if (E_IS_ATTACHMENT_BAR (bar) && event->type == GDK_2BUTTON_PRESS) { + if (E_IS_ATTACHMENT_BAR (bar)) { icon_list = GNOME_ICON_LIST (bar); p = gnome_icon_list_get_selection (icon_list); if (p) { @@ -1055,9 +1056,28 @@ attachment_bar_icon_clicked_cb (EAttachmentBar *bar, GdkEvent *event, CompEditor 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; @@ -1096,10 +1116,11 @@ cab_remove(EPopup *ep, EPopupItem *item, void *data) /* Popup menu handling. */ static EPopupItem cab_popups[] = { - { E_POPUP_ITEM, "10.attach", N_("_Remove"), cab_remove, NULL, GTK_STOCK_REMOVE, E_CAL_POPUP_ATTACHMENTS_MANY | E_CAL_POPUP_ATTACHMENTS_MODIFY }, - { E_POPUP_ITEM, "20.attach", N_("_Properties"), cab_properties, NULL, GTK_STOCK_PROPERTIES, E_CAL_POPUP_ATTACHMENTS_ONE }, - { E_POPUP_BAR, "30.attach.00", NULL, NULL, NULL, NULL, E_CAL_POPUP_ATTACHMENTS_MANY|E_CAL_POPUP_ATTACHMENTS_ONE }, - { E_POPUP_ITEM, "30.attach.01", N_("_Add attachment..."), cab_add, NULL, GTK_STOCK_ADD, E_CAL_POPUP_ATTACHMENTS_MODIFY }, + { 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 @@ -1140,7 +1161,7 @@ cab_popup(EAttachmentBar *bar, GdkEventButton *event, int id) ECalPopup *ecp; ECalPopupTargetAttachments *t; GtkMenu *menu; - CompEditor *editor = COMP_EDITOR (gtk_widget_get_toplevel (GTK_WIDGET (bar))); + CompEditor *editor = COMP_EDITOR (gtk_widget_get_toplevel (GTK_WIDGET (bar))); attachments = e_attachment_bar_get_attachment(bar, id); @@ -1181,14 +1202,17 @@ button_press_event (GtkWidget *widget, GdkEventButton *event) { EAttachmentBar *bar = (EAttachmentBar *)widget; GnomeIconList *icon_list = GNOME_ICON_LIST(widget); - int icon_number; + int icon_number = -1; + if (event->button != 3) return FALSE; - 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); + 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); diff --git a/calendar/gui/e-cal-popup.c b/calendar/gui/e-cal-popup.c index 2ceeeb63ad..eb542459a7 100644 --- a/calendar/gui/e-cal-popup.c +++ b/calendar/gui/e-cal-popup.c @@ -24,16 +24,28 @@ #endif #include <string.h> +#include <fcntl.h> #include <stdlib.h> #include <glib.h> +#include <libgnomevfs/gnome-vfs-mime-handlers.h> +#include <libgnomevfs/gnome-vfs-mime.h> + #include "e-cal-popup.h" #include <libedataserverui/e-source-selector.h> +#include <camel/camel-mime-part.h> +#include <camel/camel-stream-fs.h> +#include "e-util/e-util.h" +#include "e-util/e-i18n.h" +#include "e-util/e-mktemp.h" +#include "e-util/e-dialog-utils.h" + #include "gui/e-calendar-view.h" #include "gui/e-cal-model.h" #include "itip-utils.h" +#include "e-attachment.h" static GObjectClass *ecalp_parent; @@ -72,11 +84,344 @@ ecalp_target_free(EPopup *ep, EPopupTarget *t) ((EPopupClass *)ecalp_parent)->target_free(ep, t); } +/* Standard menu code */ + +static char * +temp_save_part(CamelMimePart *part, char *path, gboolean file) +{ + const char *filename; + char *tmpdir, *mfilename = NULL; + 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 { + mfilename = g_strdup(filename); + e_filename_make_safe(mfilename); + filename = 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 { + mfilename = g_strdup(filename); + e_filename_make_safe(mfilename); + filename = mfilename; + } + + path = g_build_filename(tmpdir, filename, NULL); + g_free(mfilename); + } + + wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (part)); + stream = camel_stream_fs_new_with_name (path, O_RDWR|O_CREAT|O_TRUNC, 0600); + + 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, *filename, *mfilename = NULL; + + 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; + + 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, "stock_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, "stock_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) { + GnomeVFSMimeApplication *app = item->user_data; + char *uri; + GList *uris = NULL; + + uri = gnome_vfs_get_uri_from_local_path(path); + uris = g_list_append(uris, uri); + + gnome_vfs_mime_application_launch(app, uris); + + g_free(uri); + 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; + + 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) { + apps = gnome_vfs_mime_get_all_applications(mime_type); + + if (apps == NULL && strcmp(mime_type, "application/octet-stream") == 0) { + const char *name_type; + + if (filename) { + /* GNOME-VFS will misidentify TNEF attachments as MPEG */ + if (!strcmp (filename, "winmail.dat")) + name_type = "application/vnd.ms-tnef"; + else + name_type = gnome_vfs_mime_type_from_name(filename); + if (name_type) + apps = gnome_vfs_mime_get_all_applications(name_type); + } + } + g_free (mime_type); + + if (apps) { + GString *label = g_string_new(""); + 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++) { + GnomeVFSMimeApplication *app = l->data; + EPopupItem *item; + + if (app->requires_terminal) + continue; + + 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..."), app->name); + 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_string_free(label, TRUE); + 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 @@ -373,8 +718,16 @@ e_cal_popup_target_new_attachments(ECalPopup *ecp, CompEditor *editor, GSList *a t->attachments = attachments; if (len > 0) mask &= ~ E_CAL_POPUP_ATTACHMENTS_MANY; - if (len == 1) + + 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; @@ -442,6 +795,8 @@ static const EPopupHookTargetMask ecalph_attachments_masks[] = { { "one", E_CAL_POPUP_ATTACHMENTS_ONE }, { "many", E_CAL_POPUP_ATTACHMENTS_MANY }, { "modify", E_CAL_POPUP_ATTACHMENTS_MODIFY }, + { "multiple", E_CAL_POPUP_ATTACHMENTS_MULTIPLE }, + { "image", E_CAL_POPUP_ATTACHMENTS_IMAGE }, { 0 } }; diff --git a/calendar/gui/e-cal-popup.h b/calendar/gui/e-cal-popup.h index 5dac5ea77e..9f57e6766e 100644 --- a/calendar/gui/e-cal-popup.h +++ b/calendar/gui/e-cal-popup.h @@ -113,7 +113,9 @@ enum _e_cal_popup_target_source_t { enum _e_cal_popup_target_attachments_t { E_CAL_POPUP_ATTACHMENTS_ONE = 1<<0, /* only 1 selected */ E_CAL_POPUP_ATTACHMENTS_MANY = 1<<1, /* one or more selected */ - E_CAL_POPUP_ATTACHMENTS_MODIFY =1<<2, /* check for modify operation */ + E_CAL_POPUP_ATTACHMENTS_MODIFY = 1<<2, /* check for modify operation */ + E_CAL_POPUP_ATTACHMENTS_MULTIPLE = 1<<3, + E_CAL_POPUP_ATTACHMENTS_IMAGE = 1<<4, }; typedef struct _ECalPopupTargetSelect ECalPopupTargetSelect; diff --git a/calendar/gui/e-calendar-table.c b/calendar/gui/e-calendar-table.c index 943a84f533..62718c8aa0 100644 --- a/calendar/gui/e-calendar-table.c +++ b/calendar/gui/e-calendar-table.c @@ -1022,7 +1022,7 @@ e_calendar_table_on_save_as (EPopup *ep, EPopupItem *pitem, void *data) if (comp_data == NULL) return; - filename = e_file_dialog_save (_("Save as...")); + filename = e_file_dialog_save (_("Save as..."), NULL); if (filename == NULL) return; diff --git a/calendar/gui/e-calendar-view.c b/calendar/gui/e-calendar-view.c index 81420ceb14..f2324da1f7 100644 --- a/calendar/gui/e-calendar-view.c +++ b/calendar/gui/e-calendar-view.c @@ -1123,7 +1123,7 @@ on_save_as (EPopup *ep, EPopupItem *pitem, void *data) if (!selected) return; - filename = e_file_dialog_save (_("Save as...")); + filename = e_file_dialog_save (_("Save as..."), NULL); if (filename == NULL) return; |