diff options
-rw-r--r-- | composer/ChangeLog | 25 | ||||
-rw-r--r-- | composer/e-msg-composer-attachment-bar.c | 30 | ||||
-rw-r--r-- | composer/e-msg-composer-select-file.c | 150 | ||||
-rw-r--r-- | composer/e-msg-composer-select-file.h | 12 | ||||
-rw-r--r-- | composer/e-msg-composer.c | 83 |
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); } |