From e927ce214f28163a2159129e2d4771da274d5611 Mon Sep 17 00:00:00 2001 From: Ettore Perazzoli Date: Mon, 15 May 2000 17:09:44 +0000 Subject: Fixed drag and drop so that it properly handles pointer grabbing in the widget with `gtk_grab_add' and `gtk_grab_remove'. Removed leaks from Iain's patch. Moved shortcut view initialization from the model into the view. svn path=/trunk/; revision=3047 --- shell/ChangeLog | 45 ++++++++++ shell/e-local-folder.c | 18 +++- shell/e-shortcuts-view.c | 139 ++++++++++++++++++++++++++++- shell/e-shortcuts.c | 211 +++++++++++++++++++-------------------------- shell/e-shortcuts.h | 6 ++ shell/e-storage-set-view.c | 6 ++ 6 files changed, 296 insertions(+), 129 deletions(-) (limited to 'shell') diff --git a/shell/ChangeLog b/shell/ChangeLog index 167f5a3189..64b27438bd 100644 --- a/shell/ChangeLog +++ b/shell/ChangeLog @@ -1,3 +1,48 @@ +2000-05-15 Ettore Perazzoli + + * e-shortcuts.c + (load_shortcuts_into_view): Removed. + (e_shortcuts_new_view): Don't set up the shortcut bar manually + here anymore, and don't set the icon callback either. The + `EShortcutsView' object is now able to do this by itself. + + * e-shortcuts-view.c + (icon_callback): Moved here from `e-shortcuts.c'. + (load_group): New function. + (load_all_shortcuts): New function. + (e_shortcuts_view_construct): Call it to load the shortcuts from + the `EShortcuts' object. Also, set `icon_callback' as the icon + callback. + + * e-storage-set-view.c + (button_press_event): Add/remove grab with `gtk_grab_add' and + `gtk_grab_remove'. + (button_release_event): Call `gtk_grab_remove' when removing the + grab. + + * e-shortcuts.c: New member `title_to_group' in + `EShortcutsPrivate'. + (init): Initialize here. + (destroy): Destroy here. + (unload_shortcuts): Destroy and recreate here. + (load_shortcuts): Avoid inserting multiple groups with the same + title, and insert the groups into the `title_to_group' hash table. + Also, avoid leaking the return value from `xmlNodeListGetString'. + (e_shortcuts_get_group_titles): New function. + (e_shortcuts_get_shortcuts_in_group): New function. + (e_shortcuts_get_storage_set): New function. + + * e-storage-set-view.c + (e_storage_set_view_set_current_folder): Emit the + "folder_selected" signal. + + * e-local-folder.c + (get_string_value): Return a `char *' to be deallocated by the + caller instead of a `const char *' that does not need to be + deallocated. + (construct_loading_metadata): Free values returned from + `get_string_value'. + 2000-05-15 Ettore Perazzoli * e-storage-set-view.c: New members `dragged_row_path', diff --git a/shell/e-local-folder.c b/shell/e-local-folder.c index 406341e793..b164eb1e95 100644 --- a/shell/e-local-folder.c +++ b/shell/e-local-folder.c @@ -39,6 +39,7 @@ #endif #include +#include #include "e-util/e-util.h" #include "e-util/e-xml-utils.h" @@ -56,11 +57,13 @@ static EFolderClass *parent_class = NULL; #define METADATA_FILE_NAME_LEN 19 -static const char * +static char * get_string_value (xmlNode *node, const char *name) { xmlNode *p; + xmlChar *xml_string; + char *retval; p = e_xml_get_child_by_name (node, (xmlChar *) name); if (p == NULL) @@ -70,7 +73,11 @@ get_string_value (xmlNode *node, if (p == NULL) return NULL; - return (const char *) xmlNodeListGetString (node->doc, p, 1); + xml_string = xmlNodeListGetString (node->doc, p, 1); + retval = g_strdup ((char *) xml_string); + xmlFree (xml_string); + + return retval; } static gboolean @@ -80,8 +87,8 @@ construct_loading_metadata (ELocalFolder *local_folder, EFolder *folder; xmlDoc *doc; xmlNode *root; - const char *type; - const char *description; + char *type; + char *description; char *metadata_path; folder = E_FOLDER (local_folder); @@ -106,6 +113,9 @@ construct_loading_metadata (ELocalFolder *local_folder, e_folder_construct (folder, g_basename (path), type, description); + g_free (type); + g_free (description); + xmlFreeDoc (doc); local_folder->physical_uri = g_strconcat (URI_PREFIX, path, NULL); diff --git a/shell/e-shortcuts-view.c b/shell/e-shortcuts-view.c index ca36020c69..86c386bf72 100644 --- a/shell/e-shortcuts-view.c +++ b/shell/e-shortcuts-view.c @@ -46,6 +46,138 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; + +/* View initialization. */ + +static const char * +get_storage_set_path_from_uri (const char *uri) +{ + const char *colon; + + if (g_path_is_absolute (uri)) + return NULL; + + colon = strchr (uri, ':'); + if (colon == NULL || colon == uri || colon[1] == '\0') + return NULL; + + if (! g_path_is_absolute (colon + 1)) + return NULL; + + if (g_strncasecmp (uri, "evolution", colon - uri) != 0) + return NULL; + + return colon + 1; +} + +static void +load_group (EShortcutsView *shortcuts_view, + const char *group_title, + int group_num) +{ + EShortcutsViewPrivate *priv; + EShortcuts *shortcuts; + EStorageSet *storage_set; + GList *shortcut_list; + GList *p; + + priv = shortcuts_view->priv; + shortcuts = priv->shortcuts; + + storage_set = e_shortcuts_get_storage_set (shortcuts); + g_assert (storage_set != NULL); + + shortcut_list = e_shortcuts_get_shortcuts_in_group (shortcuts, group_title); + if (shortcut_list == NULL) + return; + + for (p = shortcut_list; p != NULL; p = p->next) { + EFolder *folder; + const char *path; + const char *uri; + const char *name; + + uri = (const char *) p->data; + path = get_storage_set_path_from_uri (uri); + if (path != NULL) + folder = e_storage_set_get_folder (storage_set, path); + + if (path == NULL || folder == NULL) { + /* FIXME */ + g_warning ("Invalid link while loading shortcut bar view -- %s\n", + uri); + continue; + } + + name = e_folder_get_name (folder); + e_shortcut_bar_add_item (E_SHORTCUT_BAR (shortcuts_view), group_num, uri, name); + } + + e_free_string_list (shortcut_list); +} + +static void +load_all_shortcuts (EShortcutsView *shortcuts_view) +{ + EShortcutsViewPrivate *priv; + EShortcuts *shortcuts; + GList *group_titles; + GList *p; + int group_num; + + priv = shortcuts_view->priv; + shortcuts = priv->shortcuts; + + group_titles = e_shortcuts_get_group_titles (shortcuts); + + for (p = group_titles; p != NULL; p = p->next) { + const char *group_title; + + group_title = (const char *) p->data; + group_num = e_shortcut_bar_add_group (E_SHORTCUT_BAR (shortcuts_view), + group_title); + + load_group (shortcuts_view, group_title, group_num); + } + + e_free_string_list (group_titles); +} + +/* Icon callback for the shortcut bar. */ +static GdkPixbuf * +icon_callback (EShortcutBar *shortcut_bar, + const char *uri, + gpointer data) +{ + EFolderTypeRepository *folder_type_repository; + EShortcuts *shortcuts; + EStorageSet *storage_set; + EFolder *folder; + GdkPixbuf *pixbuf; + const char *type; + + shortcuts = E_SHORTCUTS (data); + + storage_set = e_shortcuts_get_storage_set (shortcuts); + folder_type_repository = e_storage_set_get_folder_type_repository (storage_set); + + folder = e_storage_set_get_folder (storage_set, + get_storage_set_path_from_uri (uri)); + + if (folder == NULL) + return NULL; + + type = e_folder_get_type_string (folder); + if (type == NULL) + return NULL; + + pixbuf = e_folder_type_repository_get_icon_for_type (folder_type_repository, type); + if (pixbuf != NULL) + gdk_pixbuf_ref (pixbuf); + + return pixbuf; +} + static void destroy (GtkObject *object) @@ -133,9 +265,14 @@ e_shortcuts_view_construct (EShortcutsView *shortcuts_view, g_return_if_fail (E_IS_SHORTCUTS (shortcuts)); priv = shortcuts_view->priv; - priv->shortcuts = shortcuts; gtk_object_ref (GTK_OBJECT (shortcuts)); + priv->shortcuts = shortcuts; + + e_shortcut_bar_set_icon_callback (E_SHORTCUT_BAR (shortcuts_view), icon_callback, + shortcuts); + + load_all_shortcuts (shortcuts_view); } GtkWidget * diff --git a/shell/e-shortcuts.c b/shell/e-shortcuts.c index 5b0d2b72ad..34abe467bb 100644 --- a/shell/e-shortcuts.c +++ b/shell/e-shortcuts.c @@ -84,6 +84,9 @@ struct _EShortcutsPrivate { /* A list of ShortcutViews. */ GList *views; + + /* A hash table to get a group given its name. */ + GHashTable *title_to_group; }; @@ -112,6 +115,9 @@ unload_shortcuts (EShortcuts *shortcuts) priv->groups = NULL; + g_hash_table_destroy (priv->title_to_group); + priv->title_to_group = g_hash_table_new (g_str_hash, g_str_equal); + /* FIXME update the views. */ } @@ -149,13 +155,22 @@ load_shortcuts (EShortcuts *shortcuts, if (shortcut_group_title == NULL) continue; + shortcut_group = g_hash_table_lookup (priv->title_to_group, + shortcut_group_title); + if (shortcut_group != NULL) { + g_warning ("Duplicate shortcut title -- %s", + shortcut_group_title); + xmlFree (shortcut_group_title); + continue; + } + shortcut_group = g_new (ShortcutGroup, 1); shortcut_group->title = g_strdup (shortcut_group_title); xmlFree (shortcut_group_title); - shortcut_group->shortcuts = NULL; + shortcut_group->shortcuts = NULL; for (q = p->childs; q != NULL; q = q->next) { - gchar *content; + char *content; if (strcmp ((char *) q->name, "item") != 0) continue; @@ -163,11 +178,12 @@ load_shortcuts (EShortcuts *shortcuts, content = xmlNodeListGetString (doc, q->childs, 1); shortcut_group->shortcuts = g_list_prepend (shortcut_group->shortcuts, g_strdup (content)); + xmlFree (content); } - shortcut_group->shortcuts = g_list_reverse (shortcut_group->shortcuts); priv->groups = g_list_prepend (priv->groups, shortcut_group); + g_hash_table_insert (priv->title_to_group, shortcut_group->title, shortcut_group); } priv->groups = g_list_reverse (priv->groups); @@ -218,119 +234,6 @@ save_shortcuts (EShortcuts *shortcuts, return TRUE; } - -/* View initialization. */ - -static const char * -get_storage_set_path_from_uri (const char *uri) -{ - const char *colon; - - if (g_path_is_absolute (uri)) - return NULL; - - colon = strchr (uri, ':'); - if (colon == NULL || colon == uri || colon[1] == '\0') - return NULL; - - if (! g_path_is_absolute (colon + 1)) - return NULL; - - if (g_strncasecmp (uri, "evolution", colon - uri) != 0) - return NULL; - - return colon + 1; -} - -static void -load_folders_into_view (EShortcuts *shortcuts, - EShortcutBar *view, - ShortcutGroup *group, - int group_num) -{ - EStorageSet *storage_set; - GList *p; - - storage_set = shortcuts->priv->storage_set; - - for (p = group->shortcuts; p != NULL; p = p->next) { - EFolder *folder; - const char *path; - const char *uri; - const char *name; - - uri = (const char *) p->data; - path = get_storage_set_path_from_uri (uri); - if (path != NULL) - folder = e_storage_set_get_folder (storage_set, path); - - if (path == NULL || folder == NULL) { - /* FIXME */ - g_warning ("Invalid link while loading shortcut bar view -- %s\n", - uri); - continue; - } - - name = e_folder_get_name (folder); - e_shortcut_bar_add_item (view, group_num, uri, name); - } -} - -static void -load_shortcuts_into_view (EShortcuts *shortcuts, - EShortcutBar *view) -{ - EShortcutsPrivate *priv; - GList *p; - int group_num; - - priv = shortcuts->priv; - - for (p = priv->groups; p != NULL; p = p->next) { - ShortcutGroup *group; - - group = (ShortcutGroup *) p->data; - group_num = e_shortcut_bar_add_group (view, group->title); - - load_folders_into_view (shortcuts, view, group, group_num); - } -} - -/* Icon callback for the shortcut bar. */ -static GdkPixbuf * -icon_callback (EShortcutBar *shortcut_bar, - const char *uri, - gpointer data) -{ - EFolderTypeRepository *folder_type_repository; - EShortcuts *shortcuts; - EStorageSet *storage_set; - EFolder *folder; - GdkPixbuf *pixbuf; - const char *type; - - shortcuts = E_SHORTCUTS (data); - - storage_set = shortcuts->priv->storage_set; - folder_type_repository = shortcuts->priv->folder_type_repository; - - folder = e_storage_set_get_folder (storage_set, - get_storage_set_path_from_uri (uri)); - - if (folder == NULL) - return NULL; - - type = e_folder_get_type_string (folder); - if (type == NULL) - return NULL; - - pixbuf = e_folder_type_repository_get_icon_for_type (folder_type_repository, type); - if (pixbuf != NULL) - gdk_pixbuf_ref (pixbuf); - - return pixbuf; -} - /* Signal handlers for the views. */ @@ -367,6 +270,8 @@ destroy (GtkObject *object) unload_shortcuts (shortcuts); + g_hash_table_destroy (priv->title_to_group); + (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); } @@ -389,9 +294,11 @@ init (EShortcuts *shortcuts) EShortcutsPrivate *priv; priv = g_new (EShortcutsPrivate, 1); - priv->storage_set = NULL; - priv->groups = NULL; - priv->views = NULL; + + priv->storage_set = NULL; + priv->groups = NULL; + priv->views = NULL; + priv->title_to_group = g_hash_table_new (g_str_hash, g_str_equal); shortcuts->priv = priv; } @@ -435,6 +342,67 @@ e_shortcuts_new (EStorageSet *storage_set, return new; } + +GList * +e_shortcuts_get_group_titles (EShortcuts *shortcuts) +{ + EShortcutsPrivate *priv; + ShortcutGroup *group; + GList *list; + GList *p; + + g_return_val_if_fail (shortcuts != NULL, NULL); + g_return_val_if_fail (E_IS_SHORTCUTS (shortcuts), NULL); + + priv = shortcuts->priv; + + list = NULL; + + for (p = priv->groups; p != NULL; p = p->next) { + group = (ShortcutGroup *) p->data; + list = g_list_prepend (list, g_strdup (group->title)); + } + + return g_list_reverse (list); +} + +GList * +e_shortcuts_get_shortcuts_in_group (EShortcuts *shortcuts, + const char *group_title) +{ + EShortcutsPrivate *priv; + ShortcutGroup *shortcut_group; + GList *list; + GList *p; + + priv = shortcuts->priv; + + g_return_val_if_fail (shortcuts != NULL, NULL); + g_return_val_if_fail (E_IS_SHORTCUTS (shortcuts), NULL); + g_return_val_if_fail (group_title != NULL, NULL); + + shortcut_group = g_hash_table_lookup (priv->title_to_group, group_title); + if (shortcut_group == NULL) + return NULL; + + list = NULL; + + for (p = shortcut_group->shortcuts; p != NULL; p = p->next) + list = g_list_prepend (list, g_strdup ((const char *) p->data)); + + return g_list_reverse (list); +} + + +EStorageSet * +e_shortcuts_get_storage_set (EShortcuts *shortcuts) +{ + g_return_val_if_fail (shortcuts != NULL, NULL); + g_return_val_if_fail (E_IS_SHORTCUTS (shortcuts), NULL); + + return shortcuts->priv->storage_set; +} + GtkWidget * e_shortcuts_new_view (EShortcuts *shortcuts) @@ -450,11 +418,6 @@ e_shortcuts_new_view (EShortcuts *shortcuts) new = e_shortcuts_view_new (shortcuts); priv->views = g_list_prepend (priv->views, new); - e_shortcut_bar_set_icon_callback (E_SHORTCUT_BAR (new), - icon_callback, shortcuts); - - load_shortcuts_into_view (shortcuts, E_SHORTCUT_BAR (new)); - gtk_signal_connect (GTK_OBJECT (new), "destroy", view_destroyed_cb, shortcuts); return new; diff --git a/shell/e-shortcuts.h b/shell/e-shortcuts.h index 569ff9ead5..bdc9126d68 100644 --- a/shell/e-shortcuts.h +++ b/shell/e-shortcuts.h @@ -67,6 +67,12 @@ void e_shortcuts_construct (EShortcuts *shortcuts, EShortcuts *e_shortcuts_new (EStorageSet *storage_set, EFolderTypeRepository *folder_type_repository); +GList *e_shortcuts_get_group_titles (EShortcuts *shortcuts); +GList *e_shortcuts_get_shortcuts_in_group (EShortcuts *shortcuts, + const char *group_title); + +EStorageSet *e_shortcuts_get_storage_set (EShortcuts *shortcuts); + GtkWidget *e_shortcuts_new_view (EShortcuts *shortcuts); gboolean e_shortcuts_load (EShortcuts *shortcuts, diff --git a/shell/e-storage-set-view.c b/shell/e-storage-set-view.c index 0c0761996b..a63ab66e27 100644 --- a/shell/e-storage-set-view.c +++ b/shell/e-storage-set-view.c @@ -154,9 +154,12 @@ button_press_event (GtkWidget *widget, gdk_pointer_ungrab (GDK_CURRENT_TIME); gdk_flush (); + gtk_grab_remove (widget); + gdk_pointer_grab (GTK_CLIST (widget)->clist_window, FALSE, GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, NULL, NULL, event->time); + gtk_grab_add (widget); return TRUE; } @@ -201,6 +204,7 @@ button_release_event (GtkWidget *widget, if (! priv->in_drag && priv->selected_row_path != NULL) { gdk_pointer_ungrab (GDK_CURRENT_TIME); + gtk_grab_remove (widget); gdk_flush (); gtk_signal_emit (GTK_OBJECT (widget), signals[FOLDER_SELECTED], @@ -624,6 +628,8 @@ e_storage_set_view_set_current_folder (EStorageSetView *storage_set_view, } gtk_ctree_select (GTK_CTREE (storage_set_view), node); + + gtk_signal_emit (GTK_OBJECT (storage_set_view), signals[FOLDER_SELECTED], path); } -- cgit