aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEttore Perazzoli <ettore@src.gnome.org>2000-05-16 01:09:44 +0800
committerEttore Perazzoli <ettore@src.gnome.org>2000-05-16 01:09:44 +0800
commite927ce214f28163a2159129e2d4771da274d5611 (patch)
treec37a8adae2aa79b6d5d3d7ebe111ebacc6ad05c5
parent98317c656590737ced646d6fb4bd65e527c7e178 (diff)
downloadgsoc2013-evolution-e927ce214f28163a2159129e2d4771da274d5611.tar.gz
gsoc2013-evolution-e927ce214f28163a2159129e2d4771da274d5611.tar.zst
gsoc2013-evolution-e927ce214f28163a2159129e2d4771da274d5611.zip
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
-rw-r--r--shell/ChangeLog45
-rw-r--r--shell/e-local-folder.c18
-rw-r--r--shell/e-shortcuts-view.c139
-rw-r--r--shell/e-shortcuts.c211
-rw-r--r--shell/e-shortcuts.h6
-rw-r--r--shell/e-storage-set-view.c6
6 files changed, 296 insertions, 129 deletions
diff --git a/shell/ChangeLog b/shell/ChangeLog
index 167f5a3189..64b27438bd 100644
--- a/shell/ChangeLog
+++ b/shell/ChangeLog
@@ -1,5 +1,50 @@
2000-05-15 Ettore Perazzoli <ettore@helixcode.com>
+ * 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 <ettore@helixcode.com>
+
* e-storage-set-view.c: New members `dragged_row_path',
`selected_row_path_before_click' in `EStorageSetViewPrivate'.
(init): Initialize them to NULL.
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 <gnome-xml/parser.h>
+#include <gnome-xml/xmlmemory.h>
#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
@@ -47,6 +47,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);
@@ -219,119 +235,6 @@ save_shortcuts (EShortcuts *shortcuts,
}
-/* 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. */
static void
@@ -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;
}
@@ -436,6 +343,67 @@ e_shortcuts_new (EStorageSet *storage_set,
}
+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);
}