From f312a007fd4b8aaf36a74aa6f40b30ab5bce5a04 Mon Sep 17 00:00:00 2001 From: Ettore Perazzoli Date: Tue, 6 Aug 2002 16:27:48 +0000 Subject: New callback for the show_folder_properties signal. * evolution-test-component.c (storage_show_folder_properties_callback): New callback for the show_folder_properties signal. (setup_custom_storage): Add two property items, and connect the callback to the signal. * e-storage-set-view.c: Renamed private member container into ui_container; new member ui_component. (init): Initialize ui_component to NULL. (impl_destroy): Unref if not NULL. (e_storage_set_view_construct): If @ui_container is not NULL, weakref it and create a new ui_component that uses it as its container. (ui_container_destroy_notify): New, weakref destroy callback for priv->ui_container. (remove_property_items): New helper function. (setup_folder_properties_items_if_corba_storage_clicked): New helper function. (folder_property_item_verb_callback): New callback for the verbs associated to the folder property items. (popup_folder_menu): Set up the per-storage folder property items using setup_folder_properties_items_if_corba_storage_clicked() and remove them with remove_property_items() after the menu has been popped down. Don't invoke populate_folder_context_menu if there is no handler for this node [this avoids a spurious warning]. * e-corba-storage.c (e_corba_storage_show_folder_properties): New. (e_corba_storage_get_folder_property_items): New. (e_corba_storage_free_property_items_list): New. * evolution-storage.c: New private member folder_property_items. (init): Init to NULL. (destroy): Free. (impl_showFolderProperties): New, implementation for the Storage::showFolderProperties CORBA method. (class_init): Set up the "show_folder_properties" signal here. (impl_Storage__get_propertyItems): New, getter for the Storage::propertyItems property. (corba_class_init): Install the new methods. (evolution_storage_add_property_item): New function to add property items to the storage. * evolution-storage.h: New signal show_folder_properties. * e-storage-set.c (e_storage_set_create_new_view): Renamed from e_storage_set_new_view(). * Evolution-Storage.idl: Added attribute folderPropertyItems and method ::showFolderProperties. svn path=/trunk/; revision=17714 --- shell/ChangeLog | 52 +++++++ shell/Evolution-Storage.idl | 29 +++- shell/e-corba-storage.c | 93 +++++++++++- shell/e-corba-storage.h | 18 ++- shell/e-shell-config-offline.c | 2 +- shell/e-shell-folder-creation-dialog.c | 2 +- shell/e-shell-folder-selection-dialog.c | 2 +- shell/e-shell-view.c | 4 +- shell/e-storage-set-view.c | 225 ++++++++++++++++++++++++++--- shell/e-storage-set-view.h | 10 +- shell/e-storage-set.c | 5 +- shell/e-storage-set.h | 2 +- shell/evolution-storage-set-view-factory.c | 2 +- shell/evolution-storage.c | 129 ++++++++++++++++- shell/evolution-storage.h | 12 ++ shell/evolution-test-component.c | 19 +++ 16 files changed, 554 insertions(+), 52 deletions(-) diff --git a/shell/ChangeLog b/shell/ChangeLog index d7486cd9ca..6fc314a583 100644 --- a/shell/ChangeLog +++ b/shell/ChangeLog @@ -1,3 +1,55 @@ +2002-08-06 Ettore Perazzoli + + * evolution-test-component.c + (storage_show_folder_properties_callback): New callback for the + show_folder_properties signal. + (setup_custom_storage): Add two property items, and connect the + callback to the signal. + + * e-storage-set-view.c: Renamed private member container into + ui_container; new member ui_component. + (init): Initialize ui_component to NULL. + (impl_destroy): Unref if not NULL. + (e_storage_set_view_construct): If @ui_container is not NULL, + weakref it and create a new ui_component that uses it as its + container. + (ui_container_destroy_notify): New, weakref destroy callback for + priv->ui_container. + (remove_property_items): New helper function. + (setup_folder_properties_items_if_corba_storage_clicked): New + helper function. + (folder_property_item_verb_callback): New callback for the verbs + associated to the folder property items. + (popup_folder_menu): Set up the per-storage folder property items + using setup_folder_properties_items_if_corba_storage_clicked() and + remove them with remove_property_items() after the menu has been + popped down. Don't invoke populate_folder_context_menu if there + is no handler for this node [this avoids a spurious warning]. + + * e-corba-storage.c (e_corba_storage_show_folder_properties): New. + (e_corba_storage_get_folder_property_items): New. + (e_corba_storage_free_property_items_list): New. + + * evolution-storage.c: New private member folder_property_items. + (init): Init to NULL. + (destroy): Free. + (impl_showFolderProperties): New, implementation for the + Storage::showFolderProperties CORBA method. + (class_init): Set up the "show_folder_properties" signal here. + (impl_Storage__get_propertyItems): New, getter for the + Storage::propertyItems property. + (corba_class_init): Install the new methods. + (evolution_storage_add_property_item): New function to add + property items to the storage. + + * evolution-storage.h: New signal show_folder_properties. + + * e-storage-set.c (e_storage_set_create_new_view): Renamed from + e_storage_set_new_view(). + + * Evolution-Storage.idl: Added attribute folderPropertyItems and + method ::showFolderProperties. + 2002-08-01 Ettore Perazzoli * e-gray-bar.c (endarken_style): Set the color for diff --git a/shell/Evolution-Storage.idl b/shell/Evolution-Storage.idl index e4ce3f1f1a..844f7255f6 100644 --- a/shell/Evolution-Storage.idl +++ b/shell/Evolution-Storage.idl @@ -43,7 +43,7 @@ module Evolution { /* Whether the storage has folders from other user's. */ readonly attribute boolean hasSharedFolders; - /* Get informatino for a folder. NOTE: evolutionUri in the + /* Get information for a folder. NOTE: evolutionUri in the returned Folder is going to be an empty string if you use this function. */ Folder getFolderAtPath (in string path) @@ -52,6 +52,17 @@ module Evolution { /* Flat list of the folders in the storage. */ readonly attribute FolderList folderList; + /* The folder property items (for right-click menu etc.). */ + + struct FolderPropertyItem { + string label; + string tooltip; + Icon icon; // Currently unused + }; + typedef sequence FolderPropertyItemList; + + readonly attribute FolderPropertyItemList folderPropertyItems; + /* Folder Operations. */ void asyncCreateFolder (in string path, @@ -70,27 +81,29 @@ module Evolution { in Bonobo::Listener listener); /* Open remote nodes. */ - void asyncOpenFolder (in string path); /* Set unread count. */ - void updateFolder (in string path, in long unread_count); /* Shared folders. */ - void asyncDiscoverSharedFolder (in string user, in string folder_name, in Bonobo::Listener listener); /* Listener handling. */ - - void addListener (in StorageListener listener) + void addListener (in StorageListener listener) raises (AlreadyListening); - - void removeListener (in StorageListener listener) + void removeListener (in StorageListener listener) raises (NotFound); + + /* (This should probably be in a separate interface, but + creating a new interface in Bonobo is so painful that I'll + just keep it here for now. */ + void showFolderProperties (in string path, + in short itemNumber, + in long parentWindowId); }; interface StorageListener { diff --git a/shell/e-corba-storage.c b/shell/e-corba-storage.c index 0fe5bdc3f4..95da96ed24 100644 --- a/shell/e-corba-storage.c +++ b/shell/e-corba-storage.c @@ -26,11 +26,17 @@ #include "e-corba-storage.h" +#include "e-shell-constants.h" + +#include "Evolution.h" + #include -#include #include -#include "Evolution.h" +#include +#include + +#include #define PARENT_TYPE E_TYPE_STORAGE @@ -625,5 +631,88 @@ e_corba_storage_get_corba_objref (ECorbaStorage *corba_storage) return corba_storage->priv->storage_interface; } + +GSList * +e_corba_storage_get_folder_property_items (ECorbaStorage *corba_storage) +{ + GNOME_Evolution_Storage_FolderPropertyItemList *corba_items; + CORBA_Environment ev; + GSList *list; + int i; + + g_return_val_if_fail (E_IS_CORBA_STORAGE (corba_storage), NULL); + + CORBA_exception_init (&ev); + + corba_items = GNOME_Evolution_Storage__get_folderPropertyItems (corba_storage->priv->storage_interface, + &ev); + + if (BONOBO_EX (&ev)) { + CORBA_exception_free (&ev); + return NULL; + } + + list = NULL; + for (i = 0; i < corba_items->_length; i ++) { + ECorbaStoragePropertyItem *item; + + item = g_new (ECorbaStoragePropertyItem, 1); + item->label = g_strdup (corba_items->_buffer[i].label); + item->tooltip = g_strdup (corba_items->_buffer[i].tooltip); + item->icon = NULL; /* We don't care for now -- FIXME */ + + list = g_slist_prepend (list, item); + } + list = g_slist_reverse (list); + + CORBA_free (corba_items); + CORBA_exception_free (&ev); + + return list; +} + +void +e_corba_storage_free_property_items_list (GSList *list) +{ + GSList *p; + + for (p = list; p != NULL; p = p->next) { + ECorbaStoragePropertyItem *item; + + item = (ECorbaStoragePropertyItem *) p->data; + + if (item->icon != NULL) + gdk_pixbuf_unref (item->icon); + g_free (item->label); + g_free (item->tooltip); + g_free (item); + } + + g_slist_free (list); +} + +void +e_corba_storage_show_folder_properties (ECorbaStorage *corba_storage, + const char *path, + int property_item_id, + GdkWindow *parent_window) +{ + CORBA_Environment ev; + + g_return_if_fail (E_IS_CORBA_STORAGE (corba_storage)); + g_return_if_fail (path != NULL && path[0] == E_PATH_SEPARATOR); + + CORBA_exception_init (&ev); + + GNOME_Evolution_Storage_showFolderProperties (corba_storage->priv->storage_interface, + path, property_item_id, + GDK_WINDOW_XWINDOW (parent_window), + &ev); + if (BONOBO_EX (&ev)) + g_warning ("Error in Storage::showFolderProperties -- %s", BONOBO_EX_ID (&ev)); + + CORBA_exception_free (&ev); +} + E_MAKE_TYPE (e_corba_storage, "ECorbaStorage", ECorbaStorage, class_init, init, PARENT_TYPE) diff --git a/shell/e-corba-storage.h b/shell/e-corba-storage.h index 432214f170..b144656cfb 100644 --- a/shell/e-corba-storage.h +++ b/shell/e-corba-storage.h @@ -53,6 +53,14 @@ struct _ECorbaStorageClass { EStorageClass parent_class; }; + +struct _ECorbaStoragePropertyItem { + char *label; + char *tooltip; + GdkPixbuf *icon; +}; +typedef struct _ECorbaStoragePropertyItem ECorbaStoragePropertyItem; + GtkType e_corba_storage_get_type (void); void e_corba_storage_construct (ECorbaStorage *corba_storage, @@ -62,9 +70,17 @@ EStorage *e_corba_storage_new (const GNOME_Evolution_Storage storage_int const char *name); GNOME_Evolution_Storage e_corba_storage_get_corba_objref (ECorbaStorage *corba_storage); -/* FIXME: I don't like this call. */ + const GNOME_Evolution_StorageListener e_corba_storage_get_StorageListener (ECorbaStorage *corba_storage); +GSList *e_corba_storage_get_folder_property_items (ECorbaStorage *corba_storage); +void e_corba_storage_free_property_items_list (GSList *list); + +void e_corba_storage_show_folder_properties (ECorbaStorage *corba_storage, + const char *path, + int property_item_id, + GdkWindow *parent_window); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/shell/e-shell-config-offline.c b/shell/e-shell-config-offline.c index d586293742..638f7f7af5 100644 --- a/shell/e-shell-config-offline.c +++ b/shell/e-shell-config-offline.c @@ -182,7 +182,7 @@ e_shell_config_offline_create_widget (EShell *shell, EvolutionConfigControl *con page_data = g_new (PageData, 1); page_data->shell = shell; - page_data->storage_set_view = e_storage_set_new_view (e_shell_get_storage_set (shell), NULL); + page_data->storage_set_view = e_storage_set_create_new_view (e_shell_get_storage_set (shell), NULL); e_storage_set_view_set_show_checkboxes (E_STORAGE_SET_VIEW (page_data->storage_set_view), TRUE, storage_set_view_has_checkbox_func, NULL); gtk_widget_show (page_data->storage_set_view); diff --git a/shell/e-shell-folder-creation-dialog.c b/shell/e-shell-folder-creation-dialog.c index 23940acffa..9d92295342 100644 --- a/shell/e-shell-folder-creation-dialog.c +++ b/shell/e-shell-folder-creation-dialog.c @@ -320,7 +320,7 @@ add_storage_set_view (GtkWidget *dialog, GtkWidget *vbox; storage_set = e_shell_get_storage_set (shell); - storage_set_view = e_storage_set_new_view (storage_set, NULL/*XXX*/); + storage_set_view = e_storage_set_create_new_view (storage_set, NULL); e_storage_set_view_set_allow_dnd (E_STORAGE_SET_VIEW (storage_set_view), FALSE); diff --git a/shell/e-shell-folder-selection-dialog.c b/shell/e-shell-folder-selection-dialog.c index 11d6493d0d..887d9de988 100644 --- a/shell/e-shell-folder-selection-dialog.c +++ b/shell/e-shell-folder-selection-dialog.c @@ -400,7 +400,7 @@ e_shell_folder_selection_dialog_construct (EShellFolderSelectionDialog *folder_s 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 (priv->storage_set, NULL /* No BonoboUIContainer */); + priv->storage_set_view = e_storage_set_create_new_view (priv->storage_set, NULL); e_storage_set_view_set_allow_dnd (E_STORAGE_SET_VIEW (priv->storage_set_view), FALSE); /* Load the expanded state for this StorageSetView */ diff --git a/shell/e-shell-view.c b/shell/e-shell-view.c index ad016da488..97cf88af30 100644 --- a/shell/e-shell-view.c +++ b/shell/e-shell-view.c @@ -1020,8 +1020,8 @@ setup_storage_set_subwindow (EShellView *shell_view) priv = shell_view->priv; - storage_set_view = e_storage_set_new_view (e_shell_get_storage_set (priv->shell), - priv->ui_container); + storage_set_view = e_storage_set_create_new_view (e_shell_get_storage_set (priv->shell), + priv->ui_container); gtk_signal_connect (GTK_OBJECT (storage_set_view), "folder_selected", GTK_SIGNAL_FUNC (folder_selected_cb), shell_view); gtk_signal_connect (GTK_OBJECT (storage_set_view), "folder_context_menu_popping_up", diff --git a/shell/e-storage-set-view.c b/shell/e-storage-set-view.c index 02ac2d2986..a4ac4c62ac 100644 --- a/shell/e-storage-set-view.c +++ b/shell/e-storage-set-view.c @@ -29,14 +29,11 @@ #include "e-util/e-gtk-utils.h" +#include "e-corba-storage.h" #include "e-icon-factory.h" #include "e-folder-dnd-bridge.h" #include "e-shell-constants.h" -#include -#include -#include -#include #include #include #include @@ -45,6 +42,11 @@ #include #include +#include +#include +#include +#include +#include #include #include "check-empty.xpm" @@ -77,7 +79,8 @@ static ETreeClass *parent_class = NULL; struct _EStorageSetViewPrivate { EStorageSet *storage_set; - BonoboUIContainer *container; + BonoboUIComponent *ui_component; + BonoboUIContainer *ui_container; ETreeModel *etree_model; ETreePath root_node; @@ -210,7 +213,6 @@ folder_sort_callback (ETreeMemory *etmm, return +1; } - /* Helper functions. */ @@ -393,6 +395,17 @@ convert_gdk_drag_action_set_to_corba (GdkDragAction action) return retval; } + +/* The weakref callback for priv->ui_component. */ + +static void +ui_container_destroy_notify (void *data) +{ + EStorageSetViewPrivate *priv = (EStorageSetViewPrivate *) data; + + priv->ui_container = NULL; +} + /* Custom marshalling function. */ @@ -592,6 +605,160 @@ set_evolution_path_selection (EStorageSetView *storage_set_view, /* Folder context menu. */ +struct _FolderPropertyItemsData { + EStorageSetView *storage_set_view; + ECorbaStorage *corba_storage; + int num_items; +}; +typedef struct _FolderPropertyItemsData FolderPropertyItemsData; + +static void +folder_property_item_verb_callback (BonoboUIComponent *component, + void *user_data, + const char *cname) +{ + FolderPropertyItemsData *data; + GtkWidget *toplevel_widget; + const char *p; + int item_number; + + data = (FolderPropertyItemsData *) user_data; + + p = strrchr (cname, ':'); + g_assert (p != NULL); + + item_number = atoi (p + 1) - 1; + g_assert (item_number >= 0); + + toplevel_widget = gtk_widget_get_toplevel (GTK_WIDGET (data->storage_set_view)); + + e_corba_storage_show_folder_properties (data->corba_storage, + data->storage_set_view->priv->right_click_row_path, + item_number, toplevel_widget->window); +} + +static FolderPropertyItemsData * +setup_folder_properties_items_if_corba_storage_clicked (EStorageSetView *storage_set_view) +{ + EStorageSetViewPrivate *priv; + EStorage *storage; + GSList *items, *p; + GString *xml; + FolderPropertyItemsData *data; + const char *slash; + char *storage_name; + int num_property_items; + int i; + + priv = storage_set_view->priv; + + slash = strchr (priv->right_click_row_path + 1, E_PATH_SEPARATOR); + if (slash == NULL) + storage_name = g_strdup (priv->right_click_row_path + 1); + + else + storage_name = g_strndup (priv->right_click_row_path + 1, + slash - (priv->right_click_row_path + 1)); + + storage = e_storage_set_get_storage (priv->storage_set, storage_name); + g_free (storage_name); + + if (storage == NULL || ! E_IS_CORBA_STORAGE (storage)) + return 0; + + items = e_corba_storage_get_folder_property_items (E_CORBA_STORAGE (storage)); + if (items == NULL) + return 0; + + xml = g_string_new (""); + g_string_append (xml, ""); + + num_property_items = 0; + for (p = items; p != NULL; p = p->next) { + const ECorbaStoragePropertyItem *item; + char *encoded_label; + char *encoded_tooltip; + + item = (const ECorbaStoragePropertyItem *) p->data; + num_property_items ++; + + g_string_sprintfa (xml, "tooltip); + g_string_sprintfa (xml, " tip=\"%s\"", encoded_tooltip); + + encoded_label = bonobo_ui_util_encode_str (item->label); + g_string_sprintfa (xml, " label=\"%s\"/>", encoded_label); + + g_free (encoded_tooltip); + g_free (encoded_label); + } + + g_string_append (xml, ""); + + data = g_new (FolderPropertyItemsData, 1); + data->storage_set_view = storage_set_view; + data->corba_storage = E_CORBA_STORAGE (storage); + data->num_items = num_property_items; + + gtk_object_ref (GTK_OBJECT (data->storage_set_view)); + gtk_object_ref (GTK_OBJECT (data->corba_storage)); + + for (i = 1; i <= num_property_items; i ++) { + char *verb; + + verb = g_strdup_printf ("EStorageSetView:FolderPropertyItem:%d", i); + bonobo_ui_component_add_verb (priv->ui_component, verb, + folder_property_item_verb_callback, + data); + } + + bonobo_ui_component_set (priv->ui_component, "/popups/FolderPopup", xml->str, NULL); + + g_string_free (xml, TRUE); + e_corba_storage_free_property_items_list (items); + + return data; +} + +static void +remove_property_items (EStorageSetView *storage_set_view, + FolderPropertyItemsData *data) +{ + EStorageSetViewPrivate *priv; + + priv = storage_set_view->priv; + + if (data->num_items > 0) { + int i; + + bonobo_ui_component_rm (priv->ui_component, + "/popups/FolderPopup/StorageFolderPropertiesPlaceholder/EStorageSetViewFolderPropertiesSeparator", + NULL); + + for (i = 1; i <= data->num_items; i ++) { + char *path; + char *verb; + + path = g_strdup_printf ("/popups/FolderPopup/StorageFolderPropertiesPlaceholder/EStorageSetView:FolderPropertyItem:%d", i); + bonobo_ui_component_rm (priv->ui_component, path, NULL); + g_free (path); + + verb = g_strdup_printf ("EStorageSetView:FolderPropertyItem:%d", i); + bonobo_ui_component_remove_verb (priv->ui_component, verb); + g_free (verb); + } + } + + gtk_object_unref (GTK_OBJECT (data->storage_set_view)); + gtk_object_unref (GTK_OBJECT (data->corba_storage)); + + g_free (data); +} + static void popup_folder_menu (EStorageSetView *storage_set_view, GdkEventButton *event) @@ -601,6 +768,7 @@ popup_folder_menu (EStorageSetView *storage_set_view, EFolderTypeRegistry *folder_type_registry; EFolder *folder; GtkWidget *menu; + FolderPropertyItemsData *folder_property_items_data; priv = storage_set_view->priv; @@ -612,18 +780,24 @@ popup_folder_menu (EStorageSetView *storage_set_view, handler = e_folder_type_registry_get_handler_for_type (folder_type_registry, e_folder_get_type_string (folder)); menu = gtk_menu_new (); - bonobo_window_add_popup (bonobo_ui_container_get_win (priv->container), + bonobo_window_add_popup (bonobo_ui_container_get_win (priv->ui_container), GTK_MENU (menu), "/popups/FolderPopup"); - evolution_shell_component_client_populate_folder_context_menu (handler, - priv->container, - e_folder_get_physical_uri (folder), - e_folder_get_type_string (folder)); + if (handler != NULL) + evolution_shell_component_client_populate_folder_context_menu (handler, + priv->ui_container, + e_folder_get_physical_uri (folder), + e_folder_get_type_string (folder)); + + folder_property_items_data = setup_folder_properties_items_if_corba_storage_clicked (storage_set_view); gtk_widget_show (GTK_WIDGET (menu)); gnome_popup_menu_do_popup_modal (GTK_WIDGET (menu), NULL, NULL, event, NULL); + if (folder_property_items_data != NULL) + remove_property_items (storage_set_view, folder_property_items_data); + gtk_widget_destroy (GTK_WIDGET (menu)); e_tree_right_click_up (E_TREE (storage_set_view)); @@ -691,6 +865,11 @@ impl_destroy (GtkObject *object) if (priv->drag_corba_data != NULL) CORBA_free (priv->drag_corba_data); + if (priv->ui_component != NULL) + bonobo_object_unref (BONOBO_OBJECT (priv->ui_component)); + + /* (No unreffing for priv->ui_container since we use a weakref.) */ + g_free (priv->selected_row_path); g_free (priv->right_click_row_path); @@ -1057,7 +1236,7 @@ impl_right_click (ETree *etree, g_free (priv->right_click_row_path); priv->right_click_row_path = g_strdup (e_tree_memory_node_get_data (E_TREE_MEMORY(priv->etree_model), path)); - if (priv->container) { + if (priv->ui_container) { gtk_signal_emit (GTK_OBJECT (storage_set_view), signals[FOLDER_CONTEXT_MENU_POPPING_UP], priv->right_click_row_path); @@ -1676,6 +1855,9 @@ init (EStorageSetView *storage_set_view) priv->path_to_etree_node = g_hash_table_new (g_str_hash, g_str_equal); priv->type_name_to_pixbuf = g_hash_table_new (g_str_hash, g_str_equal); + priv->ui_component = NULL; + priv->ui_container = NULL; + priv->selected_row_path = NULL; priv->right_click_row_path = NULL; @@ -1837,20 +2019,25 @@ insert_storages (EStorageSetView *storage_set_view) void e_storage_set_view_construct (EStorageSetView *storage_set_view, EStorageSet *storage_set, - BonoboUIContainer *container) + BonoboUIContainer *ui_container) { EStorageSetViewPrivate *priv; ETableExtras *extras; ECell *cell; - g_return_if_fail (storage_set_view != NULL); g_return_if_fail (E_IS_STORAGE_SET_VIEW (storage_set_view)); - g_return_if_fail (storage_set != NULL); g_return_if_fail (E_IS_STORAGE_SET (storage_set)); priv = storage_set_view->priv; - priv->container = container; + priv->ui_container = ui_container; + if (ui_container != NULL) { + gtk_object_weakref (GTK_OBJECT (ui_container), ui_container_destroy_notify, priv); + + priv->ui_component = bonobo_ui_component_new_default (); + bonobo_ui_component_set_container (priv->ui_component, + bonobo_object_corba_objref (BONOBO_OBJECT (ui_container))); + } priv->etree_model = e_tree_memory_callbacks_new (etree_icon_at, @@ -1931,15 +2118,15 @@ e_storage_set_view_construct (EStorageSetView *storage_set_view, /* DON'T USE THIS. Use e_storage_set_new_view() instead. */ GtkWidget * e_storage_set_view_new (EStorageSet *storage_set, - BonoboUIContainer *container) + BonoboUIContainer *ui_container) { GtkWidget *new; - g_return_val_if_fail (storage_set != NULL, NULL); g_return_val_if_fail (E_IS_STORAGE_SET (storage_set), NULL); new = gtk_type_new (e_storage_set_view_get_type ()); - e_storage_set_view_construct (E_STORAGE_SET_VIEW (new), storage_set, container); + + e_storage_set_view_construct (E_STORAGE_SET_VIEW (new), storage_set, ui_container); return new; } diff --git a/shell/e-storage-set-view.h b/shell/e-storage-set-view.h index 7d615cecaf..1d884bc00f 100644 --- a/shell/e-storage-set-view.h +++ b/shell/e-storage-set-view.h @@ -79,11 +79,11 @@ struct _EStorageSetViewClass { GtkType e_storage_set_view_get_type (void); /* DON'T USE THIS. Use e_storage_set_new_view() instead. */ -GtkWidget *e_storage_set_view_new (EStorageSet *storage_set, - BonoboUIContainer *container); -void e_storage_set_view_construct (EStorageSetView *storage_set_view, - EStorageSet *storage_set, - BonoboUIContainer *container); +GtkWidget *e_storage_set_view_new (EStorageSet *storage_set, + BonoboUIContainer *ui_container); +void e_storage_set_view_construct (EStorageSetView *storage_set_view, + EStorageSet *storage_set, + BonoboUIContainer *ui_container); EStorageSet *e_storage_set_view_get_storage_set (EStorageSetView *storage_set_view); diff --git a/shell/e-storage-set.c b/shell/e-storage-set.c index f4e91594e7..17c66ce672 100644 --- a/shell/e-storage-set.c +++ b/shell/e-storage-set.c @@ -615,14 +615,15 @@ storage_set_view_folder_opened (EStorageSetView *storage_set_view, } GtkWidget * -e_storage_set_new_view (EStorageSet *storage_set, BonoboUIContainer *container) +e_storage_set_create_new_view (EStorageSet *storage_set, + BonoboUIContainer *ui_container) { GtkWidget *storage_set_view; g_return_val_if_fail (storage_set != NULL, NULL); g_return_val_if_fail (E_IS_STORAGE_SET (storage_set), NULL); - storage_set_view = e_storage_set_view_new (storage_set, container); + storage_set_view = e_storage_set_view_new (storage_set, ui_container); gtk_signal_connect (GTK_OBJECT (storage_set_view), "folder_opened", GTK_SIGNAL_FUNC (storage_set_view_folder_opened), storage_set); diff --git a/shell/e-storage-set.h b/shell/e-storage-set.h index 6bfa1129e5..a8cc285fc7 100644 --- a/shell/e-storage-set.h +++ b/shell/e-storage-set.h @@ -83,7 +83,7 @@ EStorage *e_storage_set_get_storage (EStorageSet *storage const char *storage_name); EFolder *e_storage_set_get_folder (EStorageSet *storage_set, const char *path); -GtkWidget *e_storage_set_new_view (EStorageSet *storage_set, +GtkWidget *e_storage_set_create_new_view (EStorageSet *storage_set, BonoboUIContainer *container); void e_storage_set_async_create_folder (EStorageSet *storage_set, diff --git a/shell/evolution-storage-set-view-factory.c b/shell/evolution-storage-set-view-factory.c index 8712536f70..38f5a72f38 100644 --- a/shell/evolution-storage-set-view-factory.c +++ b/shell/evolution-storage-set-view-factory.c @@ -46,7 +46,7 @@ evolution_storage_set_view_factory_new_view (EShell *shell) g_return_val_if_fail (E_IS_SHELL (shell), NULL); storage_set = e_shell_get_storage_set (shell); - storage_set_view = e_storage_set_new_view (storage_set, NULL /*XXX*/); + storage_set_view = e_storage_set_create_new_view (storage_set, NULL /*XXX*/); e_storage_set_view_set_allow_dnd (E_STORAGE_SET_VIEW (storage_set_view), FALSE); storage_set_view_interface = evolution_storage_set_view_new (E_STORAGE_SET_VIEW (storage_set_view)); diff --git a/shell/evolution-storage.c b/shell/evolution-storage.c index 2ef04cdc2c..2f55fbbae4 100644 --- a/shell/evolution-storage.c +++ b/shell/evolution-storage.c @@ -24,26 +24,34 @@ #include #endif -#include -#include -#include -#include - -#include +#include "evolution-storage.h" #include "Evolution.h" #include "e-folder.h" #include "e-folder-tree.h" +#include "e-shell-constants.h" +#include "e-shell-corba-icon-utils.h" -#include "evolution-storage.h" +#include -#include "e-shell-constants.h" +#include +#include +#include +#include +#include #define PARENT_TYPE BONOBO_OBJECT_TYPE static BonoboObjectClass *parent_class = NULL; +struct _FolderPropertyItem { + char *label; + char *tooltip; + GdkPixbuf *icon; +}; +typedef struct _FolderPropertyItem FolderPropertyItem; + struct _EvolutionStoragePrivate { /* Name of the storage. */ char *name; @@ -62,6 +70,9 @@ struct _EvolutionStoragePrivate { /* The listener registered on this storage. */ GList *corba_storage_listeners; + + /* The property items. */ + GSList *folder_property_items; }; @@ -72,6 +83,7 @@ enum { UPDATE_FOLDER, OPEN_FOLDER, DISCOVER_SHARED_FOLDER, + SHOW_FOLDER_PROPERTIES, LAST_SIGNAL }; @@ -522,6 +534,55 @@ impl_Storage_removeListener (PortableServer_Servant servant, CORBA_exception_set (ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Storage_NotFound, NULL); } +static void +impl_Storage_showFolderProperties (PortableServer_Servant servant, + const CORBA_char *path, + const CORBA_short item_number, + const CORBA_long parent_window_id, + CORBA_Environment *ev) +{ + EvolutionStorage *storage; + + storage = EVOLUTION_STORAGE (bonobo_object_from_servant (servant)); + gtk_signal_emit (GTK_OBJECT (storage), signals[SHOW_FOLDER_PROPERTIES], + path, item_number, parent_window_id); +} + +static GNOME_Evolution_Storage_FolderPropertyItemList * +impl_Storage__get_folderPropertyItems (PortableServer_Servant servant, + CORBA_Environment *ev) +{ + EvolutionStorage *storage; + EvolutionStoragePrivate *priv; + GNOME_Evolution_Storage_FolderPropertyItemList *list; + GSList *p; + int count; + int i; + + storage = EVOLUTION_STORAGE (bonobo_object_from_servant (servant)); + priv = storage->priv; + + count = g_slist_length (priv->folder_property_items); + + list = GNOME_Evolution_Storage_FolderPropertyItemList__alloc (); + list->_length = list->_maximum = count; + list->_buffer = CORBA_sequence_GNOME_Evolution_Storage_FolderPropertyItem_allocbuf (list->_maximum); + + for (i = 0, p = priv->folder_property_items; p != NULL; i ++, p = p->next) { + const FolderPropertyItem *item; + + item = (const FolderPropertyItem *) p->data; + + list->_buffer[i].label = CORBA_string_dup (item->label); + list->_buffer[i].tooltip = CORBA_string_dup (item->tooltip); + e_store_corba_icon_from_pixbuf (item->icon, & list->_buffer[i].icon); + } + + CORBA_sequence_set_release (list, TRUE); + + return list; +} + /* GtkObject methods. */ @@ -539,6 +600,7 @@ destroy (GtkObject *object) EvolutionStoragePrivate *priv; CORBA_Environment ev; GList *p; + GSList *sp; storage = EVOLUTION_STORAGE (object); priv = storage->priv; @@ -568,6 +630,19 @@ destroy (GtkObject *object) CORBA_exception_free (&ev); + for (sp = priv->folder_property_items; p != NULL; p = p->next) { + FolderPropertyItem *item; + + item = (FolderPropertyItem *) p->data; + + g_free (item->label); + g_free (item->tooltip); + if (item->icon != NULL) + gdk_pixbuf_unref (item->icon); + g_free (item); + } + g_slist_free (priv->folder_property_items); + g_free (priv); (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); @@ -711,6 +786,17 @@ class_init (EvolutionStorageClass *klass) GTK_TYPE_STRING, GTK_TYPE_POINTER); + signals[SHOW_FOLDER_PROPERTIES] = gtk_signal_new ("show_folder_properties", + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (EvolutionStorageClass, + show_folder_properties), + gtk_marshal_NONE__POINTER_INT_INT, + GTK_TYPE_NONE, 3, + GTK_TYPE_STRING, + GTK_TYPE_INT, + GTK_TYPE_INT); + gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); corba_class_init (); @@ -727,6 +813,7 @@ init (EvolutionStorage *storage) priv->folder_tree = e_folder_tree_new (folder_destroy_notify, storage); priv->uri_to_path = g_hash_table_new (g_str_hash, g_str_equal); priv->corba_storage_listeners = NULL; + priv->folder_property_items = NULL; storage->priv = priv; } @@ -750,6 +837,8 @@ evolution_storage_get_epv (void) epv->asyncDiscoverSharedFolder = impl_Storage_asyncDiscoverSharedFolder; epv->addListener = impl_Storage_addListener; epv->removeListener = impl_Storage_removeListener; + epv->showFolderProperties = impl_Storage_showFolderProperties; + epv->_get_folderPropertyItems = impl_Storage__get_folderPropertyItems; return epv; } @@ -1267,6 +1356,30 @@ evolution_storage_has_subfolders (EvolutionStorage *evolution_storage, return result; } + +/* Setting up property items. */ + +void +evolution_storage_add_property_item (EvolutionStorage *evolution_storage, + const char *label, + const char *tooltip, + GdkPixbuf *icon) +{ + FolderPropertyItem *item; + + g_return_if_fail (EVOLUTION_IS_STORAGE (evolution_storage)); + g_return_if_fail (label != NULL); + + item = g_new (FolderPropertyItem, 1); + item->label = g_strdup (label); + item->tooltip = g_strdup (tooltip); + item->icon = icon; + if (icon != NULL) + gdk_pixbuf_ref (icon); + + evolution_storage->priv->folder_property_items = g_slist_append (evolution_storage->priv->folder_property_items, + item); +} E_MAKE_TYPE (evolution_storage, "EvolutionStorage", EvolutionStorage, class_init, init, PARENT_TYPE) diff --git a/shell/evolution-storage.h b/shell/evolution-storage.h index 9cd5eabfbd..751e9e55d5 100644 --- a/shell/evolution-storage.h +++ b/shell/evolution-storage.h @@ -28,6 +28,8 @@ #include "Evolution.h" +#include + #ifdef __cplusplus extern "C" { #pragma } @@ -110,6 +112,11 @@ struct _EvolutionStorageClass { const char *user, const char *folder_name, Bonobo_Listener listener); + + void (*show_folder_properties) (EvolutionStorage *storage, + const char *path, + unsigned int itemNumber, + unsigned long parentWindowId); }; @@ -156,6 +163,11 @@ EvolutionStorageResult evolution_storage_has_subfolders (EvolutionStorage const char *path, const char *message); +void evolution_storage_add_property_item (EvolutionStorage *evolution_storage, + const char *label, + const char *tooltip, + GdkPixbuf *icon); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/shell/evolution-test-component.c b/shell/evolution-test-component.c index eb9b670c02..bdc59073b8 100644 --- a/shell/evolution-test-component.c +++ b/shell/evolution-test-component.c @@ -308,6 +308,16 @@ storage_discover_shared_folder_callback (EvolutionStorage *storage, g_timeout_add (1000, shared_folder_discovery_timeout_callback, listener_copy); } +static void +storage_show_folder_properties_callback (EvolutionStorage *storage, + const char *path, + unsigned int itemNumber, + unsigned long parentWindowId, + void *data) +{ + g_print ("Show properties #%d -- %s\n", itemNumber, path); +} + static void setup_custom_storage (EvolutionShellClient *shell_client) { @@ -319,6 +329,15 @@ setup_custom_storage (EvolutionShellClient *shell_client) gtk_signal_connect (GTK_OBJECT (the_storage), "discover_shared_folder", GTK_SIGNAL_FUNC (storage_discover_shared_folder_callback), shell_client); + /* Add some custom "Properties" items. */ + evolution_storage_add_property_item (the_storage, "Sharing...", + "Change sharing properties for this folder", NULL); + evolution_storage_add_property_item (the_storage, "Permissions...", + "Change permissions for this folder", NULL); + + gtk_signal_connect (GTK_OBJECT (the_storage), "show_folder_properties", + GTK_SIGNAL_FUNC (storage_show_folder_properties_callback), NULL); + result = evolution_storage_register_on_shell (the_storage, BONOBO_OBJREF (shell_client)); if (result != EVOLUTION_STORAGE_OK) { g_warning ("Cannot register storage on the shell."); -- cgit v1.2.3