aboutsummaryrefslogtreecommitdiffstats
path: root/calendar
diff options
context:
space:
mode:
Diffstat (limited to 'calendar')
-rw-r--r--calendar/ChangeLog18
-rw-r--r--calendar/gui/dialogs/comp-editor.c50
-rw-r--r--calendar/gui/e-cal-popup.c357
-rw-r--r--calendar/gui/e-cal-popup.h4
-rw-r--r--calendar/gui/e-calendar-table.c2
-rw-r--r--calendar/gui/e-calendar-view.c2
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;