diff options
author | Dan Winship <danw@src.gnome.org> | 2002-04-05 04:01:31 +0800 |
---|---|---|
committer | Dan Winship <danw@src.gnome.org> | 2002-04-05 04:01:31 +0800 |
commit | 54ddaa6e4852542cf37cfb32fa6bfcec92a2dd0d (patch) | |
tree | 5db3acedbe64f229af7052db4ec38e7ac5c19a3d /shell | |
parent | 97e99e459e9a32c96ade6b1fbf9bd0da201de591 (diff) | |
download | gsoc2013-evolution-54ddaa6e4852542cf37cfb32fa6bfcec92a2dd0d.tar.gz gsoc2013-evolution-54ddaa6e4852542cf37cfb32fa6bfcec92a2dd0d.tar.zst gsoc2013-evolution-54ddaa6e4852542cf37cfb32fa6bfcec92a2dd0d.zip |
New widget for a button that displays a folder selection in a standard
* evolution-folder-selector-button.c: New widget for a button that
displays a folder selection in a standard form, and when clicked
lets the user select a new folder.
* Evolution-Shell.idl (FolderSelectionListener:notifySelected):
Make this take an Evolution:Folder instead of a pair of uris.
(Shell:getIconByType): New method to get the icon for a type from
the folder type registry.
* Evolution-common.idl (Folder): add "evolutionUri" to the folder
structure.
* Evolution-Storage.idl (StorageRegistry:getFolderByUri): get an
Evolution:Folder for a given uri.
* evolution-shell-client.c
(evolution_shell_client_user_select_folder): Update this to
reflect the IDL change: return a GNOME_Evolution_Folder instead of
a pair of URIs. Make sure it always sets *@folder_return to %NULL
if it fails (even if it's a g_return_if_fail).
(evolution_shell_client_get_storage_registry_interface): New.
(evolution_shell_client_get_pixbuf_for_type): New. Uses
Shell_getIconByType, but caches results.
* e-shell.c (folder_selection_dialog_folder_selected_cb): Update
for API change. (Return a GNOME_Evolution_Folder.)
(impl_Shell_getIconByType): Implement.
* e-corba-storage-registry.c
(impl_StorageRegistry_getFolderByUri): Implement.
* evolution-storage.c (evolution_storage_new_folder): Add a
(dummy) evolutionUri to the folder.
* Makefile.am (libeshell_la_SOURCES): add
evolution-folder-selector-button.c
(eshellinclude_HEADERS): and .h
svn path=/trunk/; revision=16352
Diffstat (limited to 'shell')
-rw-r--r-- | shell/ChangeLog | 40 | ||||
-rw-r--r-- | shell/Evolution-Shell.idl | 16 | ||||
-rw-r--r-- | shell/Evolution-Storage.idl | 3 | ||||
-rw-r--r-- | shell/Evolution-common.idl | 1 | ||||
-rw-r--r-- | shell/Makefile.am | 2 | ||||
-rw-r--r-- | shell/e-corba-storage-registry.c | 66 | ||||
-rw-r--r-- | shell/e-shell.c | 64 | ||||
-rw-r--r-- | shell/evolution-folder-selector-button.c | 308 | ||||
-rw-r--r-- | shell/evolution-folder-selector-button.h | 75 | ||||
-rw-r--r-- | shell/evolution-shell-client.c | 178 | ||||
-rw-r--r-- | shell/evolution-shell-client.h | 23 | ||||
-rw-r--r-- | shell/evolution-storage.c | 11 |
12 files changed, 712 insertions, 75 deletions
diff --git a/shell/ChangeLog b/shell/ChangeLog index 0229f33dc3..89e52dac03 100644 --- a/shell/ChangeLog +++ b/shell/ChangeLog @@ -1,3 +1,43 @@ +2002-04-04 Dan Winship <danw@ximian.com> + + * evolution-folder-selector-button.c: New widget for a button that + displays a folder selection in a standard form, and when clicked + lets the user select a new folder. + + * Evolution-Shell.idl (FolderSelectionListener:notifySelected): + Make this take an Evolution:Folder instead of a pair of uris. + (Shell:getIconByType): New method to get the icon for a type from + the folder type registry. + + * Evolution-common.idl (Folder): add "evolutionUri" to the folder + structure. + + * Evolution-Storage.idl (StorageRegistry:getFolderByUri): get an + Evolution:Folder for a given uri. + + * evolution-shell-client.c + (evolution_shell_client_user_select_folder): Update this to + reflect the IDL change: return a GNOME_Evolution_Folder instead of + a pair of URIs. Make sure it always sets *@folder_return to %NULL + if it fails (even if it's a g_return_if_fail). + (evolution_shell_client_get_storage_registry_interface): New. + (evolution_shell_client_get_pixbuf_for_type): New. Uses + Shell_getIconByType, but caches results. + + * e-shell.c (folder_selection_dialog_folder_selected_cb): Update + for API change. (Return a GNOME_Evolution_Folder.) + (impl_Shell_getIconByType): Implement. + + * e-corba-storage-registry.c + (impl_StorageRegistry_getFolderByUri): Implement. + + * evolution-storage.c (evolution_storage_new_folder): Add a + (dummy) evolutionUri to the folder. + + * Makefile.am (libeshell_la_SOURCES): add + evolution-folder-selector-button.c + (eshellinclude_HEADERS): and .h + 2002-04-04 Ettore Perazzoli <ettore@ximian.com> * evolution-shell-component.c: Change type of parent_class to diff --git a/shell/Evolution-Shell.idl b/shell/Evolution-Shell.idl index aa8ef84296..814133f7fc 100644 --- a/shell/Evolution-Shell.idl +++ b/shell/Evolution-Shell.idl @@ -42,6 +42,20 @@ module Evolution { raises (NotReady, NotFound); /** + * getIconByType: + * @type: name of a valid folder type + * @mini: whether or not to get a mini (16x16) icon + * + * Get an icon associated with a specific folder type. + * + * Return value: an Evolution::Icon interface for the + * component that handles @type. + */ + Icon getIconByType (in string type, + in boolean mini) + raises (NotReady, NotFound); + + /** * createNewView: * @uri: URI for the view to open * @@ -118,7 +132,7 @@ module Evolution { }; interface FolderSelectionListener { - void notifySelected (in string uri, in string physical_uri); + void notifySelected (in Folder folder); void notifyCanceled (); }; }; diff --git a/shell/Evolution-Storage.idl b/shell/Evolution-Storage.idl index f7d9ad1e7b..04999d24a3 100644 --- a/shell/Evolution-Storage.idl +++ b/shell/Evolution-Storage.idl @@ -120,6 +120,9 @@ module Evolution { void removeListener (in Bonobo::Listener listener) raises (NotFound); + + Folder getFolderByUri (in string uri) + raises (NotFound); }; }; }; diff --git a/shell/Evolution-common.idl b/shell/Evolution-common.idl index 86cd774852..85c3bfc4f7 100644 --- a/shell/Evolution-common.idl +++ b/shell/Evolution-common.idl @@ -16,6 +16,7 @@ struct Folder { string description; string displayName; string physicalUri; + string evolutionUri; long unreadCount; }; diff --git a/shell/Makefile.am b/shell/Makefile.am index bb5171d5c7..736e77eeb4 100644 --- a/shell/Makefile.am +++ b/shell/Makefile.am @@ -60,6 +60,7 @@ eshellinclude_HEADERS = \ Evolution.h \ e-folder-tree.h \ evolution-activity-client.h \ + evolution-folder-selector-button.h \ evolution-session.h \ evolution-shell-client.h \ evolution-shell-component-client.h \ @@ -80,6 +81,7 @@ libeshell_la_SOURCES = \ evolution-activity-client.c \ evolution-config-control.c \ evolution-config-control.h \ + evolution-folder-selector-button.c \ evolution-session.c \ evolution-shell-client.c \ evolution-shell-component-client.c \ diff --git a/shell/e-corba-storage-registry.c b/shell/e-corba-storage-registry.c index 6086bda60e..c93ac2caa5 100644 --- a/shell/e-corba-storage-registry.c +++ b/shell/e-corba-storage-registry.c @@ -24,12 +24,12 @@ #include <config.h> #endif -#include <gal/util/e-util.h> - #include "e-corba-storage.h" - #include "e-corba-storage-registry.h" +#include "e-shell-constants.h" + #include <bonobo/bonobo-exception.h> +#include <gal/util/e-util.h> #define PARENT_TYPE BONOBO_OBJECT_TYPE @@ -289,6 +289,63 @@ impl_StorageRegistry_removeListener (PortableServer_Servant servant, g_slist_free (p); } +static GNOME_Evolution_Folder * +impl_StorageRegistry_getFolderByUri (PortableServer_Servant servant, + const CORBA_char *uri, + CORBA_Environment *ev) +{ + BonoboObject *bonobo_object; + ECorbaStorageRegistry *storage_registry; + GNOME_Evolution_Folder *corba_folder; + EStorageSet *storage_set; + EFolder *folder; + char *path; + CORBA_char *corba_evolution_uri; + + bonobo_object = bonobo_object_from_servant (servant); + storage_registry = E_CORBA_STORAGE_REGISTRY (bonobo_object); + storage_set = storage_registry->priv->storage_set; + + if (!strncmp (uri, E_SHELL_URI_PREFIX, E_SHELL_URI_PREFIX_LEN)) { + corba_evolution_uri = CORBA_string_dup (uri); + path = (char *)uri + E_SHELL_URI_PREFIX_LEN; + folder = e_storage_set_get_folder (storage_set, path); + } else { + path = e_storage_set_get_path_for_physical_uri (storage_set, uri); + if (path) { + corba_evolution_uri = CORBA_string_alloc (strlen (path) + E_SHELL_URI_PREFIX_LEN + 1); + strcpy (corba_evolution_uri, E_SHELL_URI_PREFIX); + strcat (corba_evolution_uri, path); + folder = e_storage_set_get_folder (storage_set, path); + g_free (path); + } else + folder = NULL; + } + + if (!folder) { + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_GNOME_Evolution_StorageRegistry_NotFound, + NULL); + return CORBA_OBJECT_NIL; + } + + corba_folder = GNOME_Evolution_Folder__alloc (); + corba_folder->displayName = CORBA_string_dup (e_folder_get_name (folder)); + if (e_folder_get_description (folder)) + corba_folder->description = CORBA_string_dup (e_folder_get_description (folder)); + else + corba_folder->description = CORBA_string_dup (""); + corba_folder->type = CORBA_string_dup (e_folder_get_type_string (folder)); + if (e_folder_get_physical_uri (folder)) + corba_folder->physicalUri = CORBA_string_dup (e_folder_get_physical_uri (folder)); + else + corba_folder->physicalUri = CORBA_string_dup (""); + corba_folder->evolutionUri = corba_evolution_uri; + corba_folder->unreadCount = e_folder_get_unread_count (folder); + + return corba_folder; +} + /* GtkObject methods. */ @@ -329,7 +386,8 @@ corba_class_init (void) epv->removeStorageByName = impl_StorageRegistry_removeStorageByName; epv->addListener = impl_StorageRegistry_addListener; epv->removeListener = impl_StorageRegistry_removeListener; - + epv->getFolderByUri = impl_StorageRegistry_getFolderByUri; + vepv = &storage_registry_vepv; vepv->_base_epv = base_epv; vepv->Bonobo_Unknown_epv = bonobo_object_get_epv (); diff --git a/shell/e-shell.c b/shell/e-shell.c index d16ff306b3..f15348e95f 100644 --- a/shell/e-shell.c +++ b/shell/e-shell.c @@ -58,6 +58,7 @@ #include "e-folder-type-registry.h" #include "e-local-storage.h" #include "e-shell-constants.h" +#include "e-shell-corba-icon-utils.h" #include "e-shell-folder-selection-dialog.h" #include "e-shell-offline-handler.h" #include "e-shell-startup-wizard.h" @@ -239,8 +240,7 @@ folder_selection_dialog_folder_selected_cb (EShellFolderSelectionDialog *folder_ GNOME_Evolution_FolderSelectionListener listener; EStorageSet *storage_set; EFolder *folder; - char *uri; - const char *physical_uri; + GNOME_Evolution_Folder corba_folder; shell = E_SHELL (data); listener = gtk_object_get_data (GTK_OBJECT (folder_selection_dialog), "corba_listener"); @@ -250,15 +250,28 @@ folder_selection_dialog_folder_selected_cb (EShellFolderSelectionDialog *folder_ 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); - - if (folder == NULL) - physical_uri = ""; - else - physical_uri = e_folder_get_physical_uri (folder); + if (folder == NULL) { + corba_folder.type = ""; + corba_folder.description = ""; + corba_folder.displayName = ""; + corba_folder.physicalUri = ""; + corba_folder.evolutionUri = ""; + corba_folder.unreadCount = -1; + } else { + corba_folder.type = (CORBA_char *)e_folder_get_type_string (folder); + corba_folder.description = (CORBA_char *)e_folder_get_description (folder); + if (corba_folder.description == NULL) + corba_folder.description = ""; + corba_folder.displayName = (CORBA_char *)e_folder_get_name (folder); + corba_folder.physicalUri = (CORBA_char *)e_folder_get_physical_uri (folder); + if (corba_folder.physicalUri == NULL) + corba_folder.physicalUri = ""; + corba_folder.evolutionUri = (CORBA_char *)g_strconcat (E_SHELL_URI_PREFIX, path, NULL); + corba_folder.unreadCount = e_folder_get_unread_count (folder); + } - GNOME_Evolution_FolderSelectionListener_notifySelected (listener, uri, physical_uri, &ev); - g_free (uri); + GNOME_Evolution_FolderSelectionListener_notifySelected (listener, &corba_folder, &ev); + g_free (corba_folder.evolutionUri); CORBA_exception_free (&ev); @@ -336,6 +349,36 @@ impl_Shell_getComponentByType (PortableServer_Servant servant, return CORBA_Object_duplicate (corba_component, ev); } +static GNOME_Evolution_Icon * +impl_Shell_getIconByType (PortableServer_Servant servant, + const CORBA_char *type, + const CORBA_boolean mini, + CORBA_Environment *ev) +{ + BonoboObject *bonobo_object; + EFolderTypeRegistry *folder_type_registry; + GdkPixbuf *pixbuf; + GNOME_Evolution_Icon *icon; + EShell *shell; + + if (raise_exception_if_not_ready (servant, ev)) + return CORBA_OBJECT_NIL; + + bonobo_object = bonobo_object_from_servant (servant); + shell = E_SHELL (bonobo_object); + folder_type_registry = shell->priv->folder_type_registry; + + pixbuf = e_folder_type_registry_get_icon_for_type (folder_type_registry, type, mini); + + if (pixbuf == NULL) { + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Shell_NotFound, NULL); + return CORBA_OBJECT_NIL; + } + + icon = e_new_corba_icon_from_pixbuf (pixbuf); + return icon; +} + static GNOME_Evolution_ShellView impl_Shell_createNewView (PortableServer_Servant servant, const CORBA_char *uri, @@ -1050,6 +1093,7 @@ class_init (EShellClass *klass) epv = & klass->epv; epv->_get_displayName = impl_Shell__get_displayName; epv->getComponentByType = impl_Shell_getComponentByType; + epv->getIconByType = impl_Shell_getIconByType; epv->createNewView = impl_Shell_createNewView; epv->handleURI = impl_Shell_handleURI; epv->selectUserFolder = impl_Shell_selectUserFolder; diff --git a/shell/evolution-folder-selector-button.c b/shell/evolution-folder-selector-button.c new file mode 100644 index 0000000000..2ca81da05f --- /dev/null +++ b/shell/evolution-folder-selector-button.c @@ -0,0 +1,308 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* evolution-folder-selector-button.c + * + * Copyright (C) 2002 Ximian, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "evolution-folder-selector-button.h" +#include <bonobo/bonobo-ui-toolbar-icon.h> +#include <gal/util/e-util.h> +#include <gal/widgets/e-unicode.h> +#include <gtk/gtkhbox.h> +#include <gtk/gtklabel.h> +#include <libgnome/gnome-i18n.h> + + +struct _EvolutionFolderSelectorButtonPrivate { + EvolutionShellClient *shell_client; + GNOME_Evolution_StorageRegistry corba_storage_registry; + GtkWidget *icon, *label; + char *title, **possible_types, *uri; +}; + +enum { + SELECTED, + LAST_SIGNAL +}; +static guint signals[LAST_SIGNAL] = { 0 }; + +#define PARENT_TYPE gtk_button_get_type () +static GtkButtonClass *parent_class = NULL; + + +static GNOME_Evolution_Folder * +get_folder_for_uri (EvolutionFolderSelectorButton *folder_selector_button, + const char *uri) +{ + EvolutionFolderSelectorButtonPrivate *priv = folder_selector_button->priv; + CORBA_Environment ev; + GNOME_Evolution_Folder *folder; + + CORBA_exception_init (&ev); + folder = GNOME_Evolution_StorageRegistry_getFolderByUri ( + priv->corba_storage_registry, uri, &ev); + if (ev._major != CORBA_NO_EXCEPTION) + folder = CORBA_OBJECT_NIL; + CORBA_exception_free (&ev); + + return folder; +} + +static void +set_icon_and_label (EvolutionFolderSelectorButton *folder_selector_button, + GNOME_Evolution_Folder *folder) +{ + GtkWidget *w = GTK_WIDGET (folder_selector_button); + EvolutionFolderSelectorButtonPrivate *priv; + GdkPixbuf *pixbuf; + char *folder_lname, *storage_lname, *label_text; + const char *p; + + priv = folder_selector_button->priv; + + if (!folder) { + bonobo_ui_toolbar_icon_clear (BONOBO_UI_TOOLBAR_ICON (priv->icon)); + gtk_label_set_text (GTK_LABEL (priv->label), + _("<click here to select a folder>")); + return; + } + + pixbuf = evolution_shell_client_get_pixbuf_for_type (priv->shell_client, folder->type, TRUE); + bonobo_ui_toolbar_icon_set_pixbuf (BONOBO_UI_TOOLBAR_ICON (priv->icon), pixbuf); + gdk_pixbuf_unref (pixbuf); + + folder_lname = e_utf8_to_gtk_string (w, folder->displayName); + storage_lname = NULL; + p = strchr (folder->evolutionUri, '/'); + if (p) { + p = strchr (p + 1, '/'); + if (p) { + GNOME_Evolution_Folder *storage_folder; + char *storage_uri; + + storage_uri = g_strndup (folder->evolutionUri, + p - folder->evolutionUri); + storage_folder = get_folder_for_uri (folder_selector_button, storage_uri); + storage_lname = e_utf8_to_gtk_string (w, storage_folder->displayName); + CORBA_free (storage_folder); + g_free (storage_uri); + } + } + + if (storage_lname) { + label_text = g_strdup_printf ("\"%s\" in \"%s\"", folder_lname, + storage_lname); + g_free (storage_lname); + } else + label_text = g_strdup_printf ("\"%s\"", folder_lname); + + gtk_label_set_text (GTK_LABEL (priv->label), label_text); + g_free (label_text); + g_free (folder_lname); +} + +static void +clicked (GtkButton *button) +{ + EvolutionFolderSelectorButton *folder_selector_button; + EvolutionFolderSelectorButtonPrivate *priv; + GNOME_Evolution_Folder *return_folder; + GtkWindow *parent_window; + + parent_window = (GtkWindow *) + gtk_widget_get_ancestor (GTK_WIDGET (button), + GTK_TYPE_WINDOW); + + folder_selector_button = EVOLUTION_FOLDER_SELECTOR_BUTTON (button); + priv = folder_selector_button->priv; + + evolution_shell_client_user_select_folder (priv->shell_client, + parent_window, + priv->title, + priv->uri ? priv->uri : "", + (const char **)priv->possible_types, + &return_folder); + if (!return_folder) + return; + + g_free (priv->uri); + priv->uri = g_strdup (return_folder->evolutionUri); + set_icon_and_label (folder_selector_button, return_folder); + + gtk_signal_emit (GTK_OBJECT (folder_selector_button), + signals[SELECTED], return_folder); + CORBA_free (return_folder); +} + + +/* GtkObject methods. */ + +static void +destroy (GtkObject *object) +{ + EvolutionFolderSelectorButton *folder_selector_button; + EvolutionFolderSelectorButtonPrivate *priv; + int i; + + folder_selector_button = EVOLUTION_FOLDER_SELECTOR_BUTTON (object); + priv = folder_selector_button->priv; + + gtk_object_unref (GTK_OBJECT (priv->shell_client)); + g_free (priv->title); + for (i = 0; priv->possible_types[i]; i++) + g_free (priv->possible_types[i]); + g_free (priv->possible_types); + g_free (priv->uri); + + g_free (priv); + + (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); +} + + +static void +class_init (EvolutionFolderSelectorButtonClass *klass) +{ + GtkObjectClass *object_class; + GtkButtonClass *button_class; + + parent_class = gtk_type_class (bonobo_object_get_type ()); + + object_class = GTK_OBJECT_CLASS (klass); + button_class = GTK_BUTTON_CLASS (klass); + + button_class->clicked = clicked; + object_class->destroy = destroy; + + signals[SELECTED] = gtk_signal_new ("selected", + GTK_RUN_FIRST, + object_class->type, + GTK_SIGNAL_OFFSET (EvolutionFolderSelectorButtonClass, selected), + gtk_marshal_NONE__POINTER, + GTK_TYPE_NONE, 1, + GTK_TYPE_POINTER); + gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); +} + +static void +init (EvolutionFolderSelectorButton *folder_selector_button) +{ + EvolutionFolderSelectorButtonPrivate *priv; + GtkWidget *box; + + priv = g_new0 (EvolutionFolderSelectorButtonPrivate, 1); + + priv->icon = bonobo_ui_toolbar_icon_new (); + priv->label = gtk_label_new (""); + gtk_label_set_justify (GTK_LABEL (priv->label), GTK_JUSTIFY_LEFT); + gtk_misc_set_alignment (GTK_MISC (priv->label), 0.0, 0.0); + box = gtk_hbox_new (FALSE, 4); + gtk_box_pack_start (GTK_BOX (box), priv->icon, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (box), priv->label, TRUE, TRUE, 0); + gtk_widget_show_all (GTK_WIDGET (box)); + gtk_container_add (GTK_CONTAINER (folder_selector_button), box); + + folder_selector_button->priv = priv; +} + + +/** + * evolution_folder_selector_button_construct: + * @folder_selector_button: + * @shell_client: the shell client that will be used for folder selection + * @title: the title to use for the selection dialog + * @initial_uri: the URI (evolution: or physical) of the + * initially-selected folder + * @possible_types: a %NULL-terminated array of selectable types. + * + * Construct @folder_selector_button. + **/ +void +evolution_folder_selector_button_construct (EvolutionFolderSelectorButton *folder_selector_button, + EvolutionShellClient *shell_client, + const char *title, + const char *initial_uri, + const char *possible_types[]) +{ + EvolutionFolderSelectorButtonPrivate *priv; + GNOME_Evolution_Folder *folder; + int count; + + g_return_if_fail (EVOLUTION_IS_FOLDER_SELECTOR_BUTTON (folder_selector_button)); + g_return_if_fail (EVOLUTION_IS_SHELL_CLIENT (shell_client)); + g_return_if_fail (possible_types != NULL); + + priv = folder_selector_button->priv; + + priv->shell_client = shell_client; + gtk_object_ref (GTK_OBJECT (shell_client)); + priv->corba_storage_registry = evolution_shell_client_get_storage_registry_interface (shell_client); + + priv->title = g_strdup (title); + priv->uri = g_strdup (initial_uri); + + if (initial_uri) + folder = get_folder_for_uri (folder_selector_button, initial_uri); + else + folder = NULL; + set_icon_and_label (folder_selector_button, folder); + if (folder) + CORBA_free (folder); + + for (count = 0; possible_types[count]; count++) + ; + priv->possible_types = g_new (char *, count + 1); + for (count = 0; possible_types[count]; count++) + priv->possible_types[count] = g_strdup (possible_types[count]); + priv->possible_types[count] = NULL; +} + +/** + * evolution_folder_selector_button_new: + * @shell_client: the shell client that will be used for folder selection + * @title: the title to use for the selection dialog + * @initial_uri: the URI (evolution: or physical) of the + * initially-selected folder + * @possible_types: a %NULL-terminated array of selectable types. + * + * Return value: a new folder selector button. + **/ +GtkWidget * +evolution_folder_selector_button_new (EvolutionShellClient *shell_client, + const char *title, + const char *initial_uri, + const char *possible_types[]) +{ + EvolutionFolderSelectorButton *folder_selector_button; + + folder_selector_button = gtk_type_new (evolution_folder_selector_button_get_type ()); + + evolution_folder_selector_button_construct (folder_selector_button, + shell_client, + title, + initial_uri, + possible_types); + return (GtkWidget *)folder_selector_button; +} + + + +E_MAKE_TYPE (evolution_folder_selector_button, "EvolutionFolderSelectorButton", EvolutionFolderSelectorButton, class_init, init, PARENT_TYPE) diff --git a/shell/evolution-folder-selector-button.h b/shell/evolution-folder-selector-button.h new file mode 100644 index 0000000000..71b0a10165 --- /dev/null +++ b/shell/evolution-folder-selector-button.h @@ -0,0 +1,75 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* evolution-folder-selector-button.h + * + * Copyright (C) 2002 Ximian, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __EVOLUTION_FOLDER_SELECTOR_BUTTON_H__ +#define __EVOLUTION_FOLDER_SELECTOR_BUTTON_H__ + +#include <gtk/gtkbutton.h> +#include "evolution-shell-client.h" + +#include "Evolution.h" + +#ifdef __cplusplus +extern "C" { +#pragma } +#endif /* __cplusplus */ + +#define EVOLUTION_TYPE_FOLDER_SELECTOR_BUTTON (evolution_folder_selector_button_get_type ()) +#define EVOLUTION_FOLDER_SELECTOR_BUTTON(obj) (GTK_CHECK_CAST ((obj), EVOLUTION_TYPE_FOLDER_SELECTOR_BUTTON, EvolutionFolderSelectorButton)) +#define EVOLUTION_FOLDER_SELECTOR_BUTTON_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), EVOLUTION_TYPE_FOLDER_SELECTOR_BUTTON, EvolutionFolderSelectorButtonClass)) +#define EVOLUTION_IS_FOLDER_SELECTOR_BUTTON(obj) (GTK_CHECK_TYPE ((obj), EVOLUTION_TYPE_FOLDER_SELECTOR_BUTTON)) +#define EVOLUTION_IS_FOLDER_SELECTOR_BUTTON_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), EVOLUTION_TYPE_FOLDER_SELECTOR_BUTTON)) + + +typedef struct _EvolutionFolderSelectorButton EvolutionFolderSelectorButton; +typedef struct _EvolutionFolderSelectorButtonPrivate EvolutionFolderSelectorButtonPrivate; +typedef struct _EvolutionFolderSelectorButtonClass EvolutionFolderSelectorButtonClass; + +struct _EvolutionFolderSelectorButton { + GtkButton parent; + + EvolutionFolderSelectorButtonPrivate *priv; +}; + +struct _EvolutionFolderSelectorButtonClass { + GtkButtonClass parent_class; + + /* signals */ + void (*selected) (GNOME_Evolution_Folder *folder); +}; + + +GtkType evolution_folder_selector_button_get_type (void); + +void evolution_folder_selector_button_construct (EvolutionFolderSelectorButton *folder_selector_button, + EvolutionShellClient *shell_client, + const char *title, + const char *initial_uri, + const char *possible_types[]); +GtkWidget *evolution_folder_selector_button_new (EvolutionShellClient *shell_client, + const char *title, + const char *initial_uri, + const char *possible_types[]); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EVOLUTION_FOLDER_SELECTOR_BUTTON_H__ */ diff --git a/shell/evolution-shell-client.c b/shell/evolution-shell-client.c index 5b2502b239..e04d4cf26e 100644 --- a/shell/evolution-shell-client.c +++ b/shell/evolution-shell-client.c @@ -33,11 +33,14 @@ #include <gal/util/e-util.h> #include "evolution-shell-client.h" +#include "e-shell-corba-icon-utils.h" struct _EvolutionShellClientPrivate { GNOME_Evolution_Activity activity_interface; GNOME_Evolution_Shortcuts shortcuts_interface; + GNOME_Evolution_StorageRegistry storage_registry_interface; + GHashTable *icons; }; #define PARENT_TYPE bonobo_object_client_get_type () @@ -53,8 +56,7 @@ static gboolean FolderSelectionListener_vtables_initialized = FALSE; struct _FolderSelectionListenerServant { POA_GNOME_Evolution_FolderSelectionListener servant; - char **uri_return; - char **physical_uri_return; + GNOME_Evolution_Folder **folder_return; }; typedef struct _FolderSelectionListenerServant FolderSelectionListenerServant; @@ -92,19 +94,24 @@ query_shell_interface (EvolutionShellClient *shell_client, static void impl_FolderSelectionListener_selected (PortableServer_Servant servant, - const CORBA_char *uri, - const CORBA_char *physical_uri, + const GNOME_Evolution_Folder *folder, CORBA_Environment *ev) { FolderSelectionListenerServant *listener_servant; listener_servant = (FolderSelectionListenerServant *) servant; - if (listener_servant->uri_return != NULL) - * (listener_servant->uri_return) = g_strdup (uri); - - if (listener_servant->physical_uri_return != NULL) - * (listener_servant->physical_uri_return) = g_strdup (physical_uri); + if (listener_servant->folder_return != NULL) { + GNOME_Evolution_Folder *ret_folder = + GNOME_Evolution_Folder__alloc (); + ret_folder->type = CORBA_string_dup (folder->type); + ret_folder->description = CORBA_string_dup (folder->description); + ret_folder->displayName = CORBA_string_dup (folder->displayName); + ret_folder->physicalUri = CORBA_string_dup (folder->physicalUri); + ret_folder->evolutionUri = CORBA_string_dup (folder->evolutionUri); + ret_folder->unreadCount = folder->unreadCount; + * (listener_servant->folder_return) = ret_folder; + } gtk_main_quit (); } @@ -117,11 +124,8 @@ impl_FolderSelectionListener_cancel (PortableServer_Servant servant, listener_servant = (FolderSelectionListenerServant *) servant; - if (listener_servant->uri_return != NULL) - * (listener_servant->uri_return) = NULL; - - if (listener_servant->physical_uri_return != NULL) - * (listener_servant->physical_uri_return) = NULL; + if (listener_servant->folder_return != NULL) + * (listener_servant->folder_return) = NULL; gtk_main_quit (); } @@ -144,8 +148,7 @@ init_FolderSelectionListener_vtables (void) static GNOME_Evolution_FolderSelectionListener create_folder_selection_listener_interface (char **result, - char **uri_return, - char **physical_uri_return) + GNOME_Evolution_Folder **folder_return) { GNOME_Evolution_FolderSelectionListener corba_interface; CORBA_Environment ev; @@ -156,9 +159,8 @@ create_folder_selection_listener_interface (char **result, init_FolderSelectionListener_vtables (); servant = g_new0 (FolderSelectionListenerServant, 1); - servant->servant.vepv = &FolderSelectionListener_vepv; - servant->uri_return = uri_return; - servant->physical_uri_return = physical_uri_return; + servant->servant.vepv = &FolderSelectionListener_vepv; + servant->folder_return = folder_return; listener_servant = (PortableServer_Servant) servant; @@ -182,7 +184,7 @@ create_folder_selection_listener_interface (char **result, } static int -count_string_items (const char *list[]) +count_string_items (const char **list) { int i; @@ -200,9 +202,8 @@ user_select_folder (EvolutionShellClient *shell_client, GtkWindow *parent, const char *title, const char *default_folder, - const char *possible_types[], - char **uri_return, - char **physical_uri_return) + const char **possible_types, + GNOME_Evolution_Folder **folder_return) { GNOME_Evolution_FolderSelectionListener listener_interface; GNOME_Evolution_Shell corba_shell; @@ -214,13 +215,8 @@ user_select_folder (EvolutionShellClient *shell_client, result = NULL; - if (uri_return != NULL) - *uri_return = NULL; - if (physical_uri_return != NULL) - *physical_uri_return = NULL; - - listener_interface = create_folder_selection_listener_interface (&result, uri_return, - physical_uri_return); + listener_interface = create_folder_selection_listener_interface (&result, + folder_return); if (listener_interface == CORBA_OBJECT_NIL) return; @@ -256,6 +252,13 @@ user_select_folder (EvolutionShellClient *shell_client, /* GtkObject methods. */ static void +unref_pixbuf (gpointer name, gpointer pixbuf, gpointer data) +{ + g_free (name); + gdk_pixbuf_unref (pixbuf); +} + +static void destroy (GtkObject *object) { EvolutionShellClient *shell_client; @@ -285,8 +288,20 @@ destroy (GtkObject *object) CORBA_Object_release (priv->shortcuts_interface, &ev); } + if (priv->storage_registry_interface != CORBA_OBJECT_NIL) { + Bonobo_Unknown_unref (priv->storage_registry_interface, &ev); + if (ev._major != CORBA_NO_EXCEPTION) + g_warning ("EvolutionShellClient::destroy: " + "Error unreffing the ::StorageRegistry interface -- %s\n", + ev._repo_id); + CORBA_Object_release (priv->storage_registry_interface, &ev); + } + CORBA_exception_free (&ev); + g_hash_table_foreach (priv->icons, unref_pixbuf, NULL); + g_hash_table_destroy (priv->icons); + g_free (priv); (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); @@ -311,8 +326,10 @@ init (EvolutionShellClient *shell_client) EvolutionShellClientPrivate *priv; priv = g_new (EvolutionShellClientPrivate, 1); - priv->activity_interface = CORBA_OBJECT_NIL; - priv->shortcuts_interface = CORBA_OBJECT_NIL; + priv->activity_interface = CORBA_OBJECT_NIL; + priv->shortcuts_interface = CORBA_OBJECT_NIL; + priv->storage_registry_interface = CORBA_OBJECT_NIL; + priv->icons = g_hash_table_new (g_str_hash, g_str_equal); shell_client->priv = priv; } @@ -342,6 +359,7 @@ evolution_shell_client_construct (EvolutionShellClient *shell_client, priv->activity_interface = query_shell_interface (shell_client, "IDL:GNOME/Evolution/Activity:1.0"); priv->shortcuts_interface = query_shell_interface (shell_client, "IDL:GNOME/Evolution/Shortcuts:1.0"); + priv->storage_registry_interface = query_shell_interface (shell_client, "IDL:GNOME/Evolution/StorageRegistry:1.0"); } /** @@ -376,31 +394,36 @@ evolution_shell_client_new (GNOME_Evolution_Shell corba_shell) * @parent: Parent window for the dialog (must be realized when invoking) * @title: The title for the folder selection dialog * @default_folder: URI (physical or evolution:) of the folder initially selected on the dialog - * @uri_return: - * @physical_uri_return: + * @folder_return: * - * Pop up the shell's folder selection dialog with the specified @title and - * @default_folder as the initially selected folder. On return, set *@uri and - * *@physical_uri to the evolution: URI and the physical URI of the selected - * folder (or %NULL if the user cancelled the dialog). (The dialog is modal.) + * Pop up the shell's folder selection dialog with the specified + * @title and @default_folder as the initially selected folder. On + * return, set *@folder_return to the folder structure for the + * selected folder (or %NULL if the user cancelled the dialog). (The + * dialog is modal.) **/ void evolution_shell_client_user_select_folder (EvolutionShellClient *shell_client, GtkWindow *parent, const char *title, const char *default_folder, - const char *possible_types[], - char **uri_return, - char **physical_uri_return) + const char **possible_types, + GNOME_Evolution_Folder **folder_return) { + /* Do this first so it can be checked as a return value, even + * if we g_return_if_fail. + */ + if (folder_return) + *folder_return = CORBA_OBJECT_NIL; + g_return_if_fail (shell_client != NULL); g_return_if_fail (EVOLUTION_IS_SHELL_CLIENT (shell_client)); g_return_if_fail (title != NULL); g_return_if_fail (default_folder != NULL); g_return_if_fail (parent == NULL || GTK_WIDGET_REALIZED (parent)); - user_select_folder (shell_client, parent, title, default_folder, possible_types, - uri_return, physical_uri_return); + user_select_folder (shell_client, parent, title, default_folder, + possible_types, folder_return); } @@ -408,7 +431,7 @@ evolution_shell_client_user_select_folder (EvolutionShellClient *shell_client, * evolution_shell_client_get_activity_interface: * @shell_client: An EvolutionShellClient object * - * Get the GNOME::Evolution::Activity for the shell associated to + * Get the GNOME::Evolution::Activity for the shell associated with * @shell_client. * * Return value: A CORBA Object represeting the GNOME::Evolution::Activity @@ -424,10 +447,10 @@ evolution_shell_client_get_activity_interface (EvolutionShellClient *shell_clien } /** - * evolution_shell_client_get_activity_interface: + * evolution_shell_client_get_shortcuts_interface: * @shell_client: An EvolutionShellClient object * - * Get the GNOME::Evolution::Shortcuts for the shell associated to + * Get the GNOME::Evolution::Shortcuts for the shell associated with * @shell_client. * * Return value: A CORBA Object represeting the GNOME::Evolution::Shortcuts @@ -442,6 +465,25 @@ evolution_shell_client_get_shortcuts_interface (EvolutionShellClient *shell_cli return shell_client->priv->shortcuts_interface; } +/** + * evolution_shell_client_get_storage_registry_interface: + * @shell_client: An EvolutionShellClient object + * + * Get the GNOME::Evolution::StorageRegistry for the shell associated + * with @shell_client. + * + * Return value: A CORBA Object represeting the + * GNOME::Evolution::StorageRegistry interface. + **/ +GNOME_Evolution_StorageRegistry +evolution_shell_client_get_storage_registry_interface (EvolutionShellClient *shell_client) +{ + g_return_val_if_fail (shell_client != NULL, CORBA_OBJECT_NIL); + g_return_val_if_fail (EVOLUTION_IS_SHELL_CLIENT (shell_client), CORBA_OBJECT_NIL); + + return shell_client->priv->storage_registry_interface; +} + /** * evolution_shell_client_get_local_storage: @@ -506,4 +548,48 @@ evolution_shell_client_set_line_status (EvolutionShellClient *shell_client, } +GdkPixbuf * +evolution_shell_client_get_pixbuf_for_type (EvolutionShellClient *shell_client, + const char *folder_type, + gboolean mini) +{ + GNOME_Evolution_Shell corba_shell; + CORBA_Environment ev; + GNOME_Evolution_Icon *icon; + GdkPixbuf *pixbuf; + char *hash_name; + + g_return_val_if_fail (EVOLUTION_IS_SHELL_CLIENT (shell_client), NULL); + + hash_name = g_strdup_printf ("%s/%s", folder_type, + mini ? "mini" : "large"); + pixbuf = g_hash_table_lookup (shell_client->priv->icons, hash_name); + if (!pixbuf) { + corba_shell = bonobo_object_corba_objref (BONOBO_OBJECT (shell_client)); + g_return_val_if_fail (corba_shell != CORBA_OBJECT_NIL, NULL); + + CORBA_exception_init (&ev); + icon = GNOME_Evolution_Shell_getIconByType (corba_shell, + folder_type, mini, + &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + g_free (hash_name); + return NULL; + } + CORBA_exception_free (&ev); + + pixbuf = e_new_gdk_pixbuf_from_corba_icon (icon, icon->width, + icon->height); + CORBA_free (icon); + + g_hash_table_insert (shell_client->priv->icons, + hash_name, pixbuf); + } + + g_free (hash_name); + gdk_pixbuf_ref (pixbuf); + return pixbuf; +} + + E_MAKE_TYPE (evolution_shell_client, "EvolutionShellClient", EvolutionShellClient, class_init, init, PARENT_TYPE) diff --git a/shell/evolution-shell-client.h b/shell/evolution-shell-client.h index ee5fd7ced0..ab1b3b5b7d 100644 --- a/shell/evolution-shell-client.h +++ b/shell/evolution-shell-client.h @@ -25,6 +25,7 @@ #include <bonobo/bonobo-object-client.h> #include <gtk/gtkwindow.h> +#include <gdk-pixbuf/gdk-pixbuf.h> #include "Evolution.h" @@ -60,22 +61,26 @@ void evolution_shell_client_construct (EvolutionShe GNOME_Evolution_Shell corba_shell); EvolutionShellClient *evolution_shell_client_new (GNOME_Evolution_Shell shell); -void evolution_shell_client_user_select_folder (EvolutionShellClient *shell_client, - GtkWindow *parent, - const char *title, - const char *default_folder, - const char *possible_types[], - char **uri_return, - char **physical_uri_return); +void evolution_shell_client_user_select_folder (EvolutionShellClient *shell_client, + GtkWindow *parent, + const char *title, + const char *default_folder, + const char **possible_types, + GNOME_Evolution_Folder **folder_return); -GNOME_Evolution_Activity evolution_shell_client_get_activity_interface (EvolutionShellClient *shell_client); -GNOME_Evolution_Shortcuts evolution_shell_client_get_shortcuts_interface (EvolutionShellClient *shell_client); +GNOME_Evolution_Activity evolution_shell_client_get_activity_interface (EvolutionShellClient *shell_client); +GNOME_Evolution_Shortcuts evolution_shell_client_get_shortcuts_interface (EvolutionShellClient *shell_client); +GNOME_Evolution_StorageRegistry evolution_shell_client_get_storage_registry_interface (EvolutionShellClient *shell_client); GNOME_Evolution_Storage evolution_shell_client_get_local_storage (EvolutionShellClient *shell_client); void evolution_shell_client_set_line_status (EvolutionShellClient *shell_client, gboolean online); +GdkPixbuf *evolution_shell_client_get_pixbuf_for_type (EvolutionShellClient *shell_client, + const char *folder_type, + gboolean mini); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/shell/evolution-storage.c b/shell/evolution-storage.c index 382af7f8a2..a48d135203 100644 --- a/shell/evolution-storage.c +++ b/shell/evolution-storage.c @@ -836,11 +836,12 @@ evolution_storage_new_folder (EvolutionStorage *evolution_storage, CORBA_exception_init (&ev); corba_folder = GNOME_Evolution_Folder__alloc (); - corba_folder->displayName = CORBA_string_dup (display_name); - corba_folder->description = CORBA_string_dup (description); - corba_folder->type = CORBA_string_dup (type); - corba_folder->physicalUri = CORBA_string_dup (physical_uri); - corba_folder->unreadCount = unread_count; + corba_folder->displayName = CORBA_string_dup (display_name); + corba_folder->description = CORBA_string_dup (description); + corba_folder->type = CORBA_string_dup (type); + corba_folder->physicalUri = CORBA_string_dup (physical_uri); + corba_folder->evolutionUri = CORBA_string_dup (""); /* FIXME? */ + corba_folder->unreadCount = unread_count; if (! e_folder_tree_add (priv->folder_tree, path, corba_folder)) { CORBA_free (corba_folder); |