aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--composer/ChangeLog25
-rw-r--r--composer/e-msg-composer-attachment-bar.c30
-rw-r--r--composer/e-msg-composer-select-file.c150
-rw-r--r--composer/e-msg-composer-select-file.h12
-rw-r--r--composer/e-msg-composer.c83
5 files changed, 173 insertions, 127 deletions
diff --git a/composer/ChangeLog b/composer/ChangeLog
index 2d7e532f33..910502375a 100644
--- a/composer/ChangeLog
+++ b/composer/ChangeLog
@@ -1,3 +1,28 @@
+2005-02-10 Not Zed <NotZed@Ximian.com>
+
+ ** See bug #66126.
+
+ * e-msg-composer-attachment-bar.c (destroy): destroy async file
+ requesters.
+ (add_from_user_response, add_from_user): use async file
+ requesters.
+
+ * e-msg-composer.c (save): don't fallback to saveas if the
+ filename is null.
+ (saveas, saveas_response): new functions for async file
+ requesters.
+ (menu_file_save_cb): call saveas if we have no filename.
+ (menu_file_save_as_cb): call saveas.
+ (menu_file_open_cb, file_open_response): change for async file
+ loading (which doesn't appear to be used anymore).
+ (destroy): destroy async requesters.
+
+ * e-msg-composer-select-file.c (get_selector): make it no longer
+ modal, no longer show the window.
+ (select_file_response, e_msg_composer_select_file): make it async.
+ (select_attach_response, e_msg_composer_select_file_attachments):
+ same.
+
2005-01-24 Hans Petter Jansson <hpj@novell.com>
* e-msg-composer-hdrs.c (create_addressbook_entry): Set pointers to the
diff --git a/composer/e-msg-composer-attachment-bar.c b/composer/e-msg-composer-attachment-bar.c
index 221deb9b37..d2e44ca8b8 100644
--- a/composer/e-msg-composer-attachment-bar.c
+++ b/composer/e-msg-composer-attachment-bar.c
@@ -66,6 +66,8 @@
static GnomeIconListClass *parent_class = NULL;
struct _EMsgComposerAttachmentBarPrivate {
+ GtkWidget *attach; /* attachment file dialogue, if active */
+
GList *attachments;
guint num_attachments;
};
@@ -385,27 +387,22 @@ edit_selected (EMsgComposerAttachmentBar *bar)
}
/* "Attach" dialog. */
+static void
+add_from_user_response(EMsgComposer *composer, GSList *names, int is_inline)
+{
+ while (names) {
+ add_from_file((EMsgComposerAttachmentBar *)composer->attachment_bar, names->data, is_inline ? "inline" : "attachment");
+ names = g_slist_next(names);
+ }
+}
static void
add_from_user (EMsgComposerAttachmentBar *bar)
{
EMsgComposer *composer;
- GPtrArray *file_list;
- gboolean is_inline = FALSE;
- int i;
composer = E_MSG_COMPOSER (gtk_widget_get_toplevel (GTK_WIDGET (bar)));
-
- file_list = e_msg_composer_select_file_attachments (composer, &is_inline);
- if (!file_list)
- return;
-
- for (i = 0; i < file_list->len; i++) {
- add_from_file (bar, file_list->pdata[i], is_inline ? "inline" : "attachment");
- g_free (file_list->pdata[i]);
- }
-
- g_ptr_array_free (file_list, TRUE);
+ e_msg_composer_select_file_attachments(composer, &bar->priv->attach, add_from_user_response);
}
@@ -539,6 +536,10 @@ destroy (GtkObject *object)
if (bar->priv) {
free_attachment_list (bar);
+
+ if (bar->priv->attach)
+ gtk_widget_destroy(bar->priv->attach);
+
g_free (bar->priv);
bar->priv = NULL;
}
@@ -633,6 +634,7 @@ init (EMsgComposerAttachmentBar *bar)
priv = g_new (EMsgComposerAttachmentBarPrivate, 1);
+ priv->attach = NULL;
priv->attachments = NULL;
priv->num_attachments = 0;
diff --git a/composer/e-msg-composer-select-file.c b/composer/e-msg-composer-select-file.c
index 687660f0de..5f319421b6 100644
--- a/composer/e-msg-composer-select-file.c
+++ b/composer/e-msg-composer-select-file.c
@@ -22,7 +22,6 @@
*
*/
-
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@@ -49,11 +48,14 @@
enum {
SELECTOR_MODE_MULTI = (1 << 0),
- SELECTOR_MODE_SAVE = (1 << 1)
+ SELECTOR_MODE_SAVE = (1 << 1),
+ SELECTOR_SHOW_INLINE = 1<<2
};
+/* this is a mess */
+
static GtkWidget*
-run_selector(EMsgComposer *composer, const char *title, guint32 flags, gboolean *showinline_p)
+get_selector(struct _EMsgComposer *composer, const char *title, guint32 flags)
{
GtkWidget *selection;
GtkWidget *showinline = NULL;
@@ -89,10 +91,11 @@ run_selector(EMsgComposer *composer, const char *title, guint32 flags, gboolean
else
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (selection), path);
- if (showinline_p) {
+ if (flags & SELECTOR_SHOW_INLINE) {
showinline = gtk_check_button_new_with_label (_("Suggest automatic display of attachment"));
gtk_widget_show (showinline);
gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (selection), showinline);
+ g_object_set_data((GObject *)selection, "show-inline", showinline);
}
#else
selection = gtk_file_selection_new (title);
@@ -108,16 +111,17 @@ run_selector(EMsgComposer *composer, const char *title, guint32 flags, gboolean
gtk_file_selection_set_filename (GTK_FILE_SELECTION (selection), path);
}
- if (showinline_p) {
+ if (flags & SELECTOR_SHOW_INLINE) {
showinline = gtk_check_button_new_with_label (_("Suggest automatic display of attachment"));
gtk_widget_show (showinline);
gtk_box_pack_end (GTK_BOX (GTK_FILE_SELECTION (selection)->main_vbox), showinline, FALSE, FALSE, 4);
+ g_object_set_data((GObject *)selection, "show-inline", showinline);
}
#endif
gtk_window_set_transient_for ((GtkWindow *) selection, (GtkWindow *) composer);
gtk_window_set_wmclass ((GtkWindow *) selection, "fileselection", "Evolution:composer");
- gtk_window_set_modal ((GtkWindow *) selection, TRUE);
+ gtk_window_set_modal ((GtkWindow *) selection, FALSE);
icon_list = e_icon_factory_get_icon_list ("stock_mail-compose");
if (icon_list) {
@@ -126,96 +130,106 @@ run_selector(EMsgComposer *composer, const char *title, guint32 flags, gboolean
g_list_free (icon_list);
}
- if (gtk_dialog_run ((GtkDialog *) selection) == GTK_RESPONSE_OK) {
- if (showinline_p)
- *showinline_p = gtk_toggle_button_get_active ((GtkToggleButton *) showinline);
-
+ return selection;
+}
+
+static void
+select_file_response(GtkWidget *selector, guint response, struct _EMsgComposer *composer)
+{
+ if (response == GTK_RESPONSE_OK) {
+ const char *name;
+ char *path;
+ EMsgComposerSelectFileFunc func = g_object_get_data((GObject *)selector, "callback");
+
#ifdef USE_GTKFILECHOOSER
- path = g_path_get_dirname (gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (selection)));
+ name = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (selector));
+ path = g_path_get_dirname (gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (selector)));
#else
- path = g_path_get_dirname (gtk_file_selection_get_filename (GTK_FILE_SELECTION (selection)));
+ name = gtk_file_selection_get_filename (GTK_FILE_SELECTION (selector));
+ path = g_path_get_dirname (gtk_file_selection_get_filename (GTK_FILE_SELECTION (selector)));
#endif
-
- g_object_set_data_full ((GObject *) composer, "attach_path", g_strdup_printf ("%s/", path), g_free);
- g_free (path);
- } else {
- gtk_widget_destroy (selection);
- selection = NULL;
+ g_object_set_data_full ((GObject *) composer, "attach_path", path, g_free);
+
+ func(composer, name);
}
-
- return selection;
+
+ gtk_widget_destroy(selector);
}
/**
* e_msg_composer_select_file:
* @composer: a composer
+ * @w: widget pointer, so same dialog is not re-shown
+ * @func: callback invoked if the user selected a file
* @title: the title for the file selection dialog box
- * @save_mode: whether the file selection box should be shown in save mode or not
+ * @save: whether the file selection box should be shown in save mode or not
*
* This pops up a file selection dialog box with the given title
- * and allows the user to select a file.
+ * and allows the user to select a single file.
*
- * Return value: the selected filename, or %NULL if the user
- * cancelled.
**/
-char *
-e_msg_composer_select_file (EMsgComposer *composer, const char *title, gboolean save_mode)
+void e_msg_composer_select_file(struct _EMsgComposer *composer, GtkWidget **w, EMsgComposerSelectFileFunc func, const char *title, int save)
{
- guint32 flags = save_mode ? SELECTOR_MODE_SAVE : SELECTOR_MODE_MULTI;
- GtkWidget *selection;
- char *name = NULL;
-
- selection = run_selector (composer, title, flags, NULL);
- if (selection) {
-#ifdef USE_GTKFILECHOOSER
- name = g_strdup (gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (selection)));
-#else
- name = g_strdup (gtk_file_selection_get_filename (GTK_FILE_SELECTION (selection)));
-#endif
- gtk_widget_destroy (selection);
+ if (*w) {
+ gtk_window_present((GtkWindow *)*w);
+ return;
}
- return name;
+ *w = get_selector (composer, title, save ? SELECTOR_MODE_SAVE : 0);
+ g_signal_connect(*w, "response", G_CALLBACK(select_file_response), composer);
+ g_signal_connect(*w, "destroy", G_CALLBACK(gtk_widget_destroyed), w);
+ g_object_set_data((GObject *)*w, "callback", func);
+ gtk_widget_show(*w);
}
-GPtrArray *
-e_msg_composer_select_file_attachments (EMsgComposer *composer, gboolean *showinline_p)
+
+static void
+select_attach_response(GtkWidget *selector, guint response, struct _EMsgComposer *composer)
{
- GtkWidget *selection;
- GPtrArray *list = NULL;
-
- selection = run_selector (composer, _("Attach file(s)"), SELECTOR_MODE_MULTI, showinline_p);
-
- if (selection) {
+ if (response == GTK_RESPONSE_OK) {
+ GSList *names;
+ EMsgComposerSelectAttachFunc func = g_object_get_data((GObject *)selector, "callback");
+ GtkToggleButton *showinline = g_object_get_data((GObject *)selector, "show-inline");
+ char *path;
+
#ifdef USE_GTKFILECHOOSER
- GSList *files, *l, *n;
-
- if ((l = files = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER (selection)))) {
- list = g_ptr_array_new ();
-
- while (l) {
- n = l->next;
- g_ptr_array_add (list, l->data);
- g_slist_free_1 (l);
- l = n;
- }
- }
+ names = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER (selector));
+ path = g_path_get_dirname (gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (selector)));
#else
char **files;
- int i;
-
- if ((files = gtk_file_selection_get_selections (GTK_FILE_SELECTION (selection)))) {
- list = g_ptr_array_new ();
+
+ names = NULL;
+ if ((files = gtk_file_selection_get_selections (GTK_FILE_SELECTION (selector)))) {
for (i = 0; files[i]; i++)
- g_ptr_array_add (list, files[i]);
+ g_slist_prepend(names, files[i]);
g_free (files);
+ names = g_slist_reverse(names);
}
+
+ path = g_path_get_dirname (gtk_file_selection_get_filename (GTK_FILE_SELECTION (selector)));
#endif
-
- gtk_widget_destroy (selection);
+ g_object_set_data_full ((GObject *) composer, "attach_path", path, g_free);
+
+ func(composer, names, gtk_toggle_button_get_active(showinline));
+
+ g_slist_foreach(names, (GFunc)g_free, NULL);
+ g_slist_free(names);
}
-
- return list;
+
+ gtk_widget_destroy(selector);
}
+void e_msg_composer_select_file_attachments(struct _EMsgComposer *composer, GtkWidget **w, EMsgComposerSelectAttachFunc func)
+{
+ if (*w) {
+ gtk_window_present((GtkWindow *)*w);
+ return;
+ }
+
+ *w = get_selector (composer, _("Attach file(s)"), SELECTOR_MODE_MULTI|SELECTOR_SHOW_INLINE);
+ g_signal_connect(*w, "response", G_CALLBACK(select_attach_response), composer);
+ g_signal_connect(*w, "destroy", G_CALLBACK(gtk_widget_destroyed), w);
+ g_object_set_data((GObject *)*w, "callback", func);
+ gtk_widget_show(*w);
+}
diff --git a/composer/e-msg-composer-select-file.h b/composer/e-msg-composer-select-file.h
index 6a6ad886df..76535b9d91 100644
--- a/composer/e-msg-composer-select-file.h
+++ b/composer/e-msg-composer-select-file.h
@@ -24,13 +24,13 @@
#ifndef E_MSG_COMPOSER_SELECT_FILE_H
#define E_MSG_COMPOSER_SELECT_FILE_H
-#include "e-msg-composer.h"
-char *e_msg_composer_select_file (EMsgComposer *composer,
- const char *title,
- gboolean save_mode);
+struct _EMsgComposer;
-GPtrArray *e_msg_composer_select_file_attachments (EMsgComposer *composer,
- gboolean *inline_p);
+typedef void (*EMsgComposerSelectFileFunc)(struct _EMsgComposer *composer, const char *filename);
+typedef void (*EMsgComposerSelectAttachFunc)(struct _EMsgComposer *composer, GSList *names, int inline);
+
+void e_msg_composer_select_file(struct _EMsgComposer *composer, GtkWidget **w, EMsgComposerSelectFileFunc func, const char *title, int save);
+void e_msg_composer_select_file_attachments(struct _EMsgComposer *composer, GtkWidget **, EMsgComposerSelectAttachFunc func);
#endif /* E_MSG_COMPOSER_SELECT_FILE_H */
diff --git a/composer/e-msg-composer.c b/composer/e-msg-composer.c
index 20772a3afa..f825542999 100644
--- a/composer/e-msg-composer.c
+++ b/composer/e-msg-composer.c
@@ -140,6 +140,9 @@
typedef struct _EMsgComposerPrivate {
EMMenu *menu;
+
+ GtkWidget *saveas; /* saveas async file requester */
+ GtkWidget *load; /* same for load - not used */
} EMsgComposerPrivate;
enum {
@@ -1189,36 +1192,22 @@ show_attachments (EMsgComposer *composer,
}
static void
-save (EMsgComposer *composer, const char *default_filename)
+save (EMsgComposer *composer, const char *filename)
{
CORBA_Environment ev;
- char *filename;
int fd;
- if (default_filename != NULL)
- filename = g_strdup (default_filename);
- else
- filename = e_msg_composer_select_file (composer, _("Save as..."), TRUE);
-
- if (filename == NULL)
- return;
-
/* check to see if we already have the file and that we can create it */
if ((fd = open (filename, O_RDONLY | O_CREAT | O_EXCL, 0777)) == -1) {
int resp, errnosav = errno;
struct stat st;
if (stat (filename, &st) == 0 && S_ISREG (st.st_mode)) {
- resp = e_error_run((GtkWindow *)composer, E_ERROR_ASK_FILE_EXISTS_OVERWRITE,
- filename, NULL);
- if (resp != GTK_RESPONSE_OK) {
- g_free (filename);
+ resp = e_error_run((GtkWindow *)composer, E_ERROR_ASK_FILE_EXISTS_OVERWRITE, filename, NULL);
+ if (resp != GTK_RESPONSE_OK)
return;
- }
} else {
- e_error_run((GtkWindow *)composer, E_ERROR_NO_SAVE_FILE,
- filename, g_strerror(errnosav));
- g_free (filename);
+ e_error_run((GtkWindow *)composer, E_ERROR_NO_SAVE_FILE, filename, g_strerror(errnosav));
return;
}
} else
@@ -1236,8 +1225,20 @@ save (EMsgComposer *composer, const char *default_filename)
e_msg_composer_unset_autosaved (composer);
}
CORBA_exception_free (&ev);
-
- g_free (filename);
+}
+
+static void
+saveas_response(EMsgComposer *composer, const char *name)
+{
+ save(composer, name);
+}
+
+static void
+saveas(EMsgComposer *composer)
+{
+ EMsgComposerPrivate *p = _PRIVATE(composer);
+
+ e_msg_composer_select_file (composer, &p->saveas, saveas_response, _("Save as..."), TRUE);
}
static void
@@ -1585,24 +1586,22 @@ do_exit (EMsgComposer *composer)
}
/* Menu callbacks. */
+static void
+file_open_response(EMsgComposer *composer, const char *name)
+{
+ load (composer, name);
+}
static void
menu_file_open_cb (BonoboUIComponent *uic,
void *data,
const char *path)
{
- EMsgComposer *composer;
- char *file_name;
-
- composer = E_MSG_COMPOSER (data);
-
- file_name = e_msg_composer_select_file (composer, _("Open file"), FALSE);
- if (file_name == NULL)
- return;
-
- load (composer, file_name);
-
- g_free (file_name);
+ EMsgComposerPrivate *p = _PRIVATE(data);
+
+ /* NB: This function is never used anymore */
+
+ e_msg_composer_select_file(E_MSG_COMPOSER (data), &p->load, file_open_response, _("Open File"), FALSE);
}
static void
@@ -1621,7 +1620,7 @@ menu_file_save_cb (BonoboUIComponent *uic,
file_name = Bonobo_PersistFile_getCurrentFile (composer->persist_file_interface, &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
- save (composer, NULL);
+ saveas (composer);
} else {
save (composer, file_name);
CORBA_free (file_name);
@@ -1634,11 +1633,7 @@ menu_file_save_as_cb (BonoboUIComponent *uic,
void *data,
const char *path)
{
- EMsgComposer *composer;
-
- composer = E_MSG_COMPOSER (data);
-
- save (composer, NULL);
+ saveas (E_MSG_COMPOSER(data));
}
static void
@@ -2572,6 +2567,16 @@ destroy (GtkObject *object)
p->menu = NULL;
}
+ if (p->load) {
+ gtk_widget_destroy(p->load);
+ p->load = NULL;
+ }
+
+ if (p->saveas) {
+ gtk_widget_destroy(p->saveas);
+ p->saveas = NULL;
+ }
+
if (composer->uic) {
bonobo_object_unref (BONOBO_OBJECT (composer->uic));
composer->uic = NULL;
@@ -2641,7 +2646,7 @@ destroy (GtkObject *object)
g_signal_handler_disconnect (signatures, composer->sig_changed_id);
composer->sig_changed_id = 0;
}
-
+
if (GTK_OBJECT_CLASS (parent_class)->destroy != NULL)
(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
}