From fbc6a557a6d394fb9749cac6e739b6de63752b74 Mon Sep 17 00:00:00 2001 From: Ettore Perazzoli Date: Sun, 2 Jul 2000 04:46:36 +0000 Subject: Added an extra @allowed_types parameter to the shell's folder selection dialog, and update the code that uses it accordingly. svn path=/trunk/; revision=3854 --- shell/ChangeLog | 49 +++++++++++++ shell/Evolution-Shell.idl | 5 +- shell/e-shell-folder-selection-dialog.c | 126 +++++++++++++++++++++++++++----- shell/e-shell-folder-selection-dialog.h | 10 ++- shell/e-shell-view-menu.c | 41 ++++++----- shell/e-shell.c | 95 ++++++++++++++++-------- shell/evolution-shell-client.c | 30 +++++++- shell/evolution-shell-client.h | 1 + 8 files changed, 281 insertions(+), 76 deletions(-) (limited to 'shell') diff --git a/shell/ChangeLog b/shell/ChangeLog index a60a660b78..338c7798d6 100644 --- a/shell/ChangeLog +++ b/shell/ChangeLog @@ -1,3 +1,52 @@ +2000-07-01 Ettore Perazzoli + + * e-shell.c (impl_Shell_user_select_folder): New arg + @allowed_types. Pass it to the EShellFolderSelectionDialog. + Connect to the "cancelled" and "folder_selected" signals instead + of "clicked". + (corba_listener_destroy_notify): New callback. + (impl_Shell_user_select_folder): Associate it to the DestroyNotify + for the "corba_listener" GtkObject data, so we don't leak it. + (folder_selection_dialog_clicked_cb): Don't release the listener + interface here. + (folder_selection_dialog_cancelled_cb): New callback for the + "cancelled" signal. + (folder_selection_dialog_folder_selected_cb): New callback for the + "folder_selected" signal. + + * e-shell-view-menu.c (command_goto_folder): Don't connect to + "clicked". Connect to "cancelled" and "folder_selected" instead. + (folder_selection_dialog_cancelled_cb): New, callback for the + "cancelled" signal. + (folder_selection_dialog_folder_selected_cb): New, callback for + the "folder_selected" signal. + + * e-shell-folder-selection-dialog.c New members `allowed_types', + `storage_set' in `EShellFolderSelectionDialogPrivate'. + (class_init): Install signals "folder_selected", "cancelled". + (init): Init to NULL. + (impl_destroy): Free/unref them. + (e_shell_folder_selection_dialog_new): New arg @allowed_types. + (e_shell_folder_selection_dialog_construct): New arg + @allowed_types. Initialize `priv->allowed_types' from it. + (check_folder_type): New function. Check if the selected folder + is of the appropriate type and, if not, return FALSE and pop up an + error dialog. Otherwise, return TRUE. + (impl_clicked): Use `check_folder_type()' to check if the folder + type is OK. If it is not, stop emission of the "clicked" signal. + + * e-shell-folder-selection-dialog.h: New signals + "folder_selected", "cancelled". + + * evolution-shell-client.c + (evolution_shell_client_user_select_folder): New arg + @allowed_types. + (user_select_folder): New arg @allowed_types. Pass this to the + ::user_select_folder method. + + * Evolution-Shell.idl: New arg @required_types in + ::user_select_folder. + 2000-07-01 Ettore Perazzoli * e-shell.c (setup_components): Don't ref the component registry. diff --git a/shell/Evolution-Shell.idl b/shell/Evolution-Shell.idl index b1cfaefcc6..3b154cd191 100644 --- a/shell/Evolution-Shell.idl +++ b/shell/Evolution-Shell.idl @@ -22,10 +22,13 @@ module Evolution { ShellComponent get_component_for_type (in string type) raises (NotFound); + typedef sequence FolderTypeList; + /* FIXME: Parent "transient_for" window. */ void user_select_folder (in FolderSelectionListener listener, in string title, - in string default_folder) + in string default_folder, + in FolderTypeList possible_types) raises (Busy); }; diff --git a/shell/e-shell-folder-selection-dialog.c b/shell/e-shell-folder-selection-dialog.c index 16e2c54fe6..95cc1d2141 100644 --- a/shell/e-shell-folder-selection-dialog.c +++ b/shell/e-shell-folder-selection-dialog.c @@ -29,6 +29,7 @@ #include #include +#include "e-util/e-gui-utils.h" #include "e-util/e-util.h" #include "widgets/misc/e-scroll-frame.h" @@ -45,9 +46,57 @@ static GnomeDialogClass *parent_class = NULL; struct _EShellFolderSelectionDialogPrivate { EShell *shell; + GList *allowed_types; + EStorageSet *storage_set; GtkWidget *storage_set_view; }; +enum { + FOLDER_SELECTED, + CANCELLED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + + +static gboolean +check_folder_type (EShellFolderSelectionDialog *folder_selection_dialog) +{ + EShellFolderSelectionDialogPrivate *priv; + const char *selected_path; + EFolder *folder; + const char *folder_type; + GList *p; + + priv = folder_selection_dialog->priv; + if (priv->allowed_types == NULL) + return TRUE; + + selected_path = e_shell_folder_selection_dialog_get_selected_path (folder_selection_dialog); + if (selected_path == NULL) + return FALSE; + + folder = e_storage_set_get_folder (priv->storage_set, selected_path); + if (folder == NULL) + return FALSE; + + folder_type = e_folder_get_type_string (folder); + + for (p = priv->allowed_types; p != NULL; p = p->next) { + const char *type; + + type = (const char *) p->data; + if (strcasecmp (folder_type, type) == 0) + return TRUE; + } + + e_notice (GTK_WINDOW (folder_selection_dialog), GNOME_MESSAGE_BOX_ERROR, + _("The type of the selected folder is not valid for\nthe requested operation.")); + + return FALSE; +} + /* GtkObject methods. */ @@ -60,6 +109,11 @@ impl_destroy (GtkObject *object) folder_selection_dialog = E_SHELL_FOLDER_SELECTION_DIALOG (object); priv = folder_selection_dialog->priv; + if (priv->storage_set != NULL) + gtk_object_unref (GTK_OBJECT (priv->storage_set)); + + e_free_string_list (priv->allowed_types); + g_free (priv); (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); @@ -74,27 +128,32 @@ impl_clicked (GnomeDialog *dialog, { EShellFolderSelectionDialog *folder_selection_dialog; EShellFolderSelectionDialogPrivate *priv; + EStorageSetView *storage_set_view; + const char *default_parent_folder; folder_selection_dialog = E_SHELL_FOLDER_SELECTION_DIALOG (dialog); priv = folder_selection_dialog->priv; - /* Check for the "Add..." button. */ - if (button_number == 2) { - EStorageSetView *storage_set_view; - const char *default_parent_folder; - -#if 0 - /* (FIXME: The stupid GnomeDialog defines the "clicked" signal as - GTK_RUN_LAST so this does not work. Grrr.) */ - /* We don't want the user of the widget to handle this directly. */ - gtk_signal_emit_stop_by_name (GTK_OBJECT (dialog), "clicked"); -#endif - + switch (button_number) { + case 0: /* OK */ + if (check_folder_type (folder_selection_dialog)) { + gtk_signal_emit (GTK_OBJECT (folder_selection_dialog), signals[FOLDER_SELECTED], + e_shell_folder_selection_dialog_get_selected_path (folder_selection_dialog)); + gtk_widget_destroy (GTK_WIDGET (dialog)); + } + break; + case 1: /* Cancel */ + gtk_signal_emit (GTK_OBJECT (folder_selection_dialog), signals[CANCELLED]); + gtk_widget_destroy (GTK_WIDGET (dialog)); + break; + case 2: /* Add */ storage_set_view = E_STORAGE_SET_VIEW (priv->storage_set_view); default_parent_folder = e_storage_set_view_get_current_folder (storage_set_view); e_shell_show_folder_creation_dialog (priv->shell, GTK_WINDOW (dialog), default_parent_folder); + + break; } } @@ -114,6 +173,25 @@ class_init (EShellFolderSelectionDialogClass *klass) object_class->destroy = impl_destroy; dialog_class->clicked = impl_clicked; + + signals[FOLDER_SELECTED] + = gtk_signal_new ("folder_selected", + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (EShellFolderSelectionDialogClass, folder_selected), + gtk_marshal_NONE__POINTER, + GTK_TYPE_NONE, 1, + GTK_TYPE_STRING); + + signals[CANCELLED] + = gtk_signal_new ("cancelled", + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (EShellFolderSelectionDialogClass, cancelled), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); + + gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); } static void @@ -123,7 +201,9 @@ init (EShellFolderSelectionDialog *shell_folder_selection_dialog) priv = g_new (EShellFolderSelectionDialogPrivate, 1); priv->shell = NULL; + priv->storage_set = NULL; priv->storage_set_view = NULL; + priv->allowed_types = NULL; shell_folder_selection_dialog->priv = priv; } @@ -133,11 +213,12 @@ void e_shell_folder_selection_dialog_construct (EShellFolderSelectionDialog *folder_selection_dialog, EShell *shell, const char *title, - const char *default_path) + const char *default_path, + const char *allowed_types[]) { EShellFolderSelectionDialogPrivate *priv; - EStorageSet *storage_set; GtkWidget *scroll_frame; + int i; g_return_if_fail (folder_selection_dialog != NULL); g_return_if_fail (E_IS_SHELL_FOLDER_SELECTION_DIALOG (folder_selection_dialog)); @@ -164,11 +245,19 @@ e_shell_folder_selection_dialog_construct (EShellFolderSelectionDialog *folder_s GTK_SIGNAL_FUNC (gtk_widget_destroy), GTK_OBJECT (folder_selection_dialog)); - storage_set = e_shell_get_storage_set (shell); + priv->storage_set = e_shell_get_storage_set (shell); + gtk_object_ref (GTK_OBJECT (priv->storage_set)); - priv->storage_set_view = e_storage_set_new_view (storage_set); + priv->storage_set_view = e_storage_set_new_view (priv->storage_set); GTK_WIDGET_SET_FLAGS (priv->storage_set_view, GTK_CAN_FOCUS); + g_assert (priv->allowed_types == NULL); + if (allowed_types != NULL) { + for (i = 0; allowed_types[i] != NULL; i++) + priv->allowed_types = g_list_prepend (priv->allowed_types, + g_strdup (allowed_types[i])); + } + e_storage_set_view_set_current_folder (E_STORAGE_SET_VIEW (priv->storage_set_view), default_path); @@ -188,7 +277,8 @@ e_shell_folder_selection_dialog_construct (EShellFolderSelectionDialog *folder_s GtkWidget * e_shell_folder_selection_dialog_new (EShell *shell, const char *title, - const char *default_path) + const char *default_path, + const char *allowed_types[]) { EShellFolderSelectionDialog *folder_selection_dialog; @@ -197,7 +287,7 @@ e_shell_folder_selection_dialog_new (EShell *shell, folder_selection_dialog = gtk_type_new (e_shell_folder_selection_dialog_get_type ()); e_shell_folder_selection_dialog_construct (folder_selection_dialog, shell, - title, default_path); + title, default_path, allowed_types); return GTK_WIDGET (folder_selection_dialog); } diff --git a/shell/e-shell-folder-selection-dialog.h b/shell/e-shell-folder-selection-dialog.h index 29d96e4c61..2ddb98bafe 100644 --- a/shell/e-shell-folder-selection-dialog.h +++ b/shell/e-shell-folder-selection-dialog.h @@ -52,6 +52,10 @@ struct _EShellFolderSelectionDialog { struct _EShellFolderSelectionDialogClass { GnomeDialogClass parent_class; + + void (* folder_selected) (EShellFolderSelectionDialog *folder_selection_dialog, + const char *path); + void (* cancelled) (EShellFolderSelectionDialog *folder_selection_dialog); }; @@ -59,10 +63,12 @@ GtkType e_shell_folder_selection_dialog_get_type (void); void e_shell_folder_selection_dialog_construct (EShellFolderSelectionDialog *folder_selection_dialog, EShell *shell, const char *title, - const char *default_path); + const char *default_path, + const char *allowed_types[]); GtkWidget *e_shell_folder_selection_dialog_new (EShell *shell, const char *title, - const char *default_path); + const char *default_path, + const char *allowed_types[]); const char *e_shell_folder_selection_dialog_get_selected_path (EShellFolderSelectionDialog *folder_selection_dialog); diff --git a/shell/e-shell-view-menu.c b/shell/e-shell-view-menu.c index 391a216823..d47b15b0aa 100644 --- a/shell/e-shell-view-menu.c +++ b/shell/e-shell-view-menu.c @@ -249,32 +249,31 @@ command_new_folder (BonoboUIHandler *uih, /* Going to a folder. */ static void -folder_selection_dialog_clicked_cb (GnomeDialog *dialog, - int button_number, - void *data) +folder_selection_dialog_cancelled_cb (EShellFolderSelectionDialog *folder_selection_dialog, + void *data) { - EShellFolderSelectionDialog *folder_selection_dialog; EShellView *shell_view; shell_view = E_SHELL_VIEW (data); - folder_selection_dialog = E_SHELL_FOLDER_SELECTION_DIALOG (dialog); - if (button_number != 0 /* OK */ && button_number != 1 /* Cancel */) - return; + gtk_widget_destroy (GTK_WIDGET (folder_selection_dialog)); +} - if (button_number == 0 /* OK */) { - const char *path; +static void +folder_selection_dialog_folder_selected_cb (EShellFolderSelectionDialog *folder_selection_dialog, + const char *path, + void *data) +{ + if (path != NULL) { + EShellView *shell_view; + char *uri; - path = e_shell_folder_selection_dialog_get_selected_path (folder_selection_dialog); - if (path != NULL) { - char *uri; + shell_view = E_SHELL_VIEW (data); - uri = g_strconcat (E_SHELL_URI_PREFIX, path, NULL); - e_shell_view_display_uri (shell_view, uri); - } + uri = g_strconcat (E_SHELL_URI_PREFIX, path, NULL); + e_shell_view_display_uri (shell_view, uri); + g_free (uri); } - - gtk_widget_destroy (GTK_WIDGET (dialog)); } static void @@ -300,10 +299,12 @@ command_goto_folder (BonoboUIHandler *uih, folder_selection_dialog = e_shell_folder_selection_dialog_new (shell, _("Go to folder..."), - default_folder); + default_folder, NULL); - gtk_signal_connect (GTK_OBJECT (folder_selection_dialog), "clicked", - GTK_SIGNAL_FUNC (folder_selection_dialog_clicked_cb), shell_view); + gtk_signal_connect (GTK_OBJECT (folder_selection_dialog), "folder_selected", + GTK_SIGNAL_FUNC (folder_selection_dialog_folder_selected_cb), shell_view); + gtk_signal_connect (GTK_OBJECT (folder_selection_dialog), "cancelled", + GTK_SIGNAL_FUNC (folder_selection_dialog_cancelled_cb), shell_view); gtk_widget_show (folder_selection_dialog); } diff --git a/shell/e-shell.c b/shell/e-shell.c index 64eec8c9a2..f5ba300e3d 100644 --- a/shell/e-shell.c +++ b/shell/e-shell.c @@ -29,6 +29,7 @@ #include "Evolution.h" +#include "e-util/e-gui-utils.h" #include "e-util/e-util.h" #include "e-component-registry.h" @@ -91,51 +92,57 @@ static guint signals[LAST_SIGNAL] = { 0 }; /* Callback for the folder selection dialog. */ static void -folder_selection_dialog_clicked_cb (GnomeDialog *dialog, - int button_number, - void *data) +folder_selection_dialog_cancelled_cb (EShellFolderSelectionDialog *folder_selection_dialog, + void *data) { - EShellFolderSelectionDialog *folder_selection_dialog; Evolution_FolderSelectionListener listener; + CORBA_Environment ev; + + listener = gtk_object_get_data (GTK_OBJECT (folder_selection_dialog), "corba_listener"); + + CORBA_exception_init (&ev); + + Evolution_FolderSelectionListener_cancel (listener, &ev); + + CORBA_exception_free (&ev); + + gtk_widget_destroy (GTK_WIDGET (folder_selection_dialog)); +} + +static void +folder_selection_dialog_folder_selected_cb (EShellFolderSelectionDialog *folder_selection_dialog, + const char *path, + void *data) +{ + CORBA_Environment ev; EShell *shell; + Evolution_FolderSelectionListener listener; EStorageSet *storage_set; EFolder *folder; - CORBA_Environment ev; - const char *path; char *uri; - const char *physical_uri; - - if (button_number == 2) - return; + char *physical_uri; - folder_selection_dialog = E_SHELL_FOLDER_SELECTION_DIALOG (dialog); shell = E_SHELL (data); - listener = gtk_object_get_data (GTK_OBJECT (dialog), "corba_listener"); + listener = gtk_object_get_data (GTK_OBJECT (folder_selection_dialog), "corba_listener"); CORBA_exception_init (&ev); - if (button_number == 0) { - storage_set = e_shell_get_storage_set (shell); - path = e_shell_folder_selection_dialog_get_selected_path (folder_selection_dialog), - folder = e_storage_set_get_folder (storage_set, path); + storage_set = e_shell_get_storage_set (shell); + folder = e_storage_set_get_folder (storage_set, path); - uri = g_strconcat (E_SHELL_URI_PREFIX, path, NULL); + uri = g_strconcat (E_SHELL_URI_PREFIX, path, NULL); - if (folder == NULL || button_number == 1) /* Uh? */ - physical_uri = ""; - else - physical_uri = e_folder_get_physical_uri (folder); + if (folder == NULL) + physical_uri = ""; + else + physical_uri = e_folder_get_physical_uri (folder); - Evolution_FolderSelectionListener_selected (listener, uri, physical_uri, &ev); - g_free (uri); - } else - Evolution_FolderSelectionListener_cancel (listener, &ev); + Evolution_FolderSelectionListener_selected (listener, uri, physical_uri, &ev); + g_free (uri); - CORBA_Object_release (listener, &ev); CORBA_exception_free (&ev); - if (button_number != -1) - gnome_dialog_close(dialog); + gtk_widget_destroy (GTK_WIDGET (folder_selection_dialog)); } @@ -194,28 +201,52 @@ impl_Shell_get_component_for_type (PortableServer_Servant servant, return CORBA_Object_duplicate (corba_component, ev); } +static void +corba_listener_destroy_notify (void *data) +{ + CORBA_Environment ev; + Evolution_FolderSelectionListener listener_interface; + + listener_interface = (Evolution_FolderSelectionListener) data; + + CORBA_exception_init (&ev); + CORBA_Object_release (listener_interface, &ev); + CORBA_exception_free (&ev); +} + static void impl_Shell_user_select_folder (PortableServer_Servant servant, const Evolution_FolderSelectionListener listener, const CORBA_char *title, const CORBA_char *default_folder, + const Evolution_Shell_FolderTypeList *corba_allowed_types, CORBA_Environment *ev) { GtkWidget *folder_selection_dialog; BonoboObject *bonobo_object; Evolution_FolderSelectionListener listener_duplicate; EShell *shell; + const char **allowed_types; + int i; bonobo_object = bonobo_object_from_servant (servant); shell = E_SHELL (bonobo_object); - folder_selection_dialog = e_shell_folder_selection_dialog_new (shell, title, default_folder); + allowed_types = alloca (sizeof (allowed_types[0]) * (corba_allowed_types->_length + 1)); + for (i = 0; i < corba_allowed_types->_length; i++) + allowed_types[i] = corba_allowed_types->_buffer[i]; + allowed_types[corba_allowed_types->_length] = NULL; + + folder_selection_dialog = e_shell_folder_selection_dialog_new (shell, title, default_folder, allowed_types); listener_duplicate = CORBA_Object_duplicate (listener, ev); - gtk_object_set_data (GTK_OBJECT (folder_selection_dialog), "corba_listener", listener_duplicate); + gtk_object_set_data_full (GTK_OBJECT (folder_selection_dialog), "corba_listener", + listener_duplicate, corba_listener_destroy_notify); - gtk_signal_connect (GTK_OBJECT (folder_selection_dialog), "clicked", - GTK_SIGNAL_FUNC (folder_selection_dialog_clicked_cb), shell); + gtk_signal_connect (GTK_OBJECT (folder_selection_dialog), "folder_selected", + GTK_SIGNAL_FUNC (folder_selection_dialog_folder_selected_cb), shell); + gtk_signal_connect (GTK_OBJECT (folder_selection_dialog), "cancelled", + GTK_SIGNAL_FUNC (folder_selection_dialog_cancelled_cb), shell); gtk_widget_show (folder_selection_dialog); } diff --git a/shell/evolution-shell-client.c b/shell/evolution-shell-client.c index 10ba9ced93..5d48111c01 100644 --- a/shell/evolution-shell-client.c +++ b/shell/evolution-shell-client.c @@ -148,10 +148,25 @@ create_folder_selection_listener_interface (char **result, return corba_interface; } +static int +count_string_items (const char *list[]) +{ + int i; + + if (list == NULL) + return 0; + + for (i = 0; list[i] != NULL; i++) + ; + + return i; +} + static void user_select_folder (EvolutionShellClient *shell_client, const char *title, const char *default_folder, + const char *possible_types[], char **uri_return, char **physical_uri_return) { @@ -159,6 +174,8 @@ user_select_folder (EvolutionShellClient *shell_client, Evolution_Shell corba_shell; GMainLoop *main_loop; CORBA_Environment ev; + Evolution_Shell_FolderTypeList corba_type_list; + int num_possible_types; char *result; result = NULL; @@ -175,10 +192,15 @@ user_select_folder (EvolutionShellClient *shell_client, corba_shell = bonobo_object_corba_objref (BONOBO_OBJECT (shell_client)); - g_print ("%s -- %p\n", __FUNCTION__, corba_shell); + num_possible_types = count_string_items (possible_types); + + corba_type_list._length = num_possible_types; + corba_type_list._maximum = num_possible_types; + corba_type_list._buffer = possible_types; Evolution_Shell_user_select_folder (corba_shell, listener_interface, - title, default_folder, &ev); + title, default_folder, &corba_type_list, + &ev); if (ev._major != CORBA_NO_EXCEPTION) { CORBA_exception_free (&ev); @@ -301,6 +323,7 @@ void evolution_shell_client_user_select_folder (EvolutionShellClient *shell_client, const char *title, const char *default_folder, + const char *possible_types[], char **uri_return, char **physical_uri_return) { @@ -309,7 +332,8 @@ evolution_shell_client_user_select_folder (EvolutionShellClient *shell_client, g_return_if_fail (title != NULL); g_return_if_fail (default_folder != NULL); - user_select_folder (shell_client, title, default_folder, uri_return, physical_uri_return); + user_select_folder (shell_client, title, default_folder, possible_types, + uri_return, physical_uri_return); } diff --git a/shell/evolution-shell-client.h b/shell/evolution-shell-client.h index daf0c65e76..c9258574f7 100644 --- a/shell/evolution-shell-client.h +++ b/shell/evolution-shell-client.h @@ -67,6 +67,7 @@ EvolutionShellClient *evolution_shell_client_new (Evolution_Shel void evolution_shell_client_user_select_folder (EvolutionShellClient *shell_client, const char *title, const char *default_folder, + const char *possible_types[], char **uri_return, char **physical_uri_return); -- cgit v1.2.3