diff options
-rw-r--r-- | ChangeLog | 29 | ||||
-rw-r--r-- | lib/ephy-node-common.h | 3 | ||||
-rw-r--r-- | lib/ephy-node.c | 30 | ||||
-rw-r--r-- | lib/ephy-node.h | 6 | ||||
-rw-r--r-- | lib/widgets/ephy-node-view.c | 25 | ||||
-rw-r--r-- | src/bookmarks/ephy-bookmarks-editor.c | 6 | ||||
-rw-r--r-- | src/bookmarks/ephy-bookmarks.c | 213 | ||||
-rw-r--r-- | src/bookmarks/ephy-bookmarks.h | 5 |
8 files changed, 298 insertions, 19 deletions
@@ -1,5 +1,34 @@ 2005-07-10 Christian Persch <chpe@cvs.gnome.org> + * lib/ephy-node-common.h: + * lib/ephy-node.c: (ephy_node_new_with_id), + (ephy_node_signal_disconnect), (ephy_node_set_is_drag_source), + (ephy_node_get_is_drag_source), (ephy_node_set_is_drag_dest), + (ephy_node_get_is_drag_dest): + * lib/ephy-node.h: + * lib/widgets/ephy-node-view.c: (drag_motion_cb), + (drag_data_received_cb): + + Implement a way to disallow dragging from resp. dropping on certain + nodes. + + * src/bookmarks/ephy-bookmarks-editor.c: + (ephy_bookmarks_editor_update_menu): + * src/bookmarks/ephy-bookmarks.c: (save_filter), + (save_filter_local), (ephy_bookmarks_save), + (update_bookmark_keywords), (bookmark_is_categorized), + (resolve_cb), (browse_cb), (ephy_local_bookmarks_init), + (ephy_local_bookmarks_stop), (ephy_bookmarks_init), + (ephy_bookmarks_finalize), (ephy_bookmarks_get_topic_uri), + (ephy_bookmarks_find_keyword), (ephy_bookmarks_get_favorites), + (ephy_bookmarks_get_local): + * src/bookmarks/ephy-bookmarks.h: + + Implement "Local Sites" topic, filled with zeroconf-discovered + bookmarks. Patch by Bastien Nocera, fixes bug #144969. + +2005-07-10 Christian Persch <chpe@cvs.gnome.org> + * embed/ephy-embed-shell.c: (ephy_embed_shell_prepare_close): Fix build with -Werror. diff --git a/lib/ephy-node-common.h b/lib/ephy-node-common.h index a81fafb20..8376a028c 100644 --- a/lib/ephy-node-common.h +++ b/lib/ephy-node-common.h @@ -38,7 +38,8 @@ enum HOSTS_NODE_ID = 5, PAGES_NODE_ID = 6, ICONS_NODE_ID = 9, - SMARTBOOKMARKS_NODE_ID = 10 + SMARTBOOKMARKS_NODE_ID = 10, + BMKS_LOCAL_NODE_ID = 11, }; typedef enum diff --git a/lib/ephy-node.c b/lib/ephy-node.c index 9e98ccd8c..67889893b 100644 --- a/lib/ephy-node.c +++ b/lib/ephy-node.c @@ -69,6 +69,8 @@ struct _EphyNode int signal_id; guint emissions; guint invalidated_signals; + guint is_drag_source : 1; + guint is_drag_dest : 1; EphyNodeDb *db; }; @@ -365,6 +367,8 @@ ephy_node_new_with_id (EphyNodeDb *db, guint reserved_id) node->signal_id = 0; node->emissions = 0; node->invalidated_signals = 0; + node->is_drag_source = TRUE; + node->is_drag_dest = TRUE; _ephy_node_db_add_id (db, reserved_id, node); @@ -1273,6 +1277,32 @@ ephy_node_signal_disconnect (EphyNode *node, } } +void +ephy_node_set_is_drag_source (EphyNode *node, + gboolean allow) +{ + node->is_drag_source = allow != FALSE; +} + +gboolean +ephy_node_get_is_drag_source (EphyNode *node) +{ + return node->is_drag_source; +} + +void +ephy_node_set_is_drag_dest (EphyNode *node, + gboolean allow) +{ + node->is_drag_dest = allow != FALSE; +} + +gboolean +ephy_node_get_is_drag_dest (EphyNode *node) +{ + return node->is_drag_dest; +} + GType ephy_node_get_type (void) { diff --git a/lib/ephy-node.h b/lib/ephy-node.h index ecdb32588..f4e0b0411 100644 --- a/lib/ephy-node.h +++ b/lib/ephy-node.h @@ -129,6 +129,12 @@ EphyNode *ephy_node_get_next_child (EphyNode *node, EphyNode *child); EphyNode *ephy_node_get_previous_child (EphyNode *node, EphyNode *child); +void ephy_node_set_is_drag_source (EphyNode *node, + gboolean allow); +gboolean ephy_node_get_is_drag_source (EphyNode *node); +void ephy_node_set_is_drag_dest (EphyNode *node, + gboolean allow); +gboolean ephy_node_get_is_drag_dest (EphyNode *node); G_END_DECLS diff --git a/lib/widgets/ephy-node-view.c b/lib/widgets/ephy-node-view.c index 668ac4ba6..23cc2fc60 100644 --- a/lib/widgets/ephy-node-view.c +++ b/lib/widgets/ephy-node-view.c @@ -309,7 +309,8 @@ drag_motion_cb (GtkWidget *widget, (node, view->priv->priority_prop_id); if (priority != EPHY_NODE_VIEW_ALL_PRIORITY && - priority != EPHY_NODE_VIEW_SPECIAL_PRIORITY) + priority != EPHY_NODE_VIEW_SPECIAL_PRIORITY && + ephy_node_get_is_drag_source (node)) { action = context->suggested_action; } @@ -374,6 +375,10 @@ drag_data_received_cb (GtkWidget *widget, return; } + /* appease GtkTreeView by preventing its drag_data_receive + * from being called */ + g_signal_stop_emission_by_name (view, "drag_data_received"); + if (!view->priv->have_drag_data) { view->priv->have_drag_data = TRUE; @@ -388,16 +393,18 @@ drag_data_received_cb (GtkWidget *widget, gboolean success = FALSE; GtkTreePath *path; - gtk_tree_view_get_dest_row_at_pos - (GTK_TREE_VIEW (widget), x, y, &path, &pos); - - g_return_if_fail (path != NULL); + if (gtk_tree_view_get_dest_row_at_pos + (GTK_TREE_VIEW (widget), x, y, &path, &pos) == FALSE) + { + return; + } node = get_node_from_path (view, path); + if (node == NULL) return; uris = gtk_selection_data_get_uris (selection_data); - if (uris != NULL) + if (uris != NULL && ephy_node_get_is_drag_dest (node)) { /* FIXME fill success */ g_signal_emit (G_OBJECT (view), @@ -416,12 +423,6 @@ drag_data_received_cb (GtkWidget *widget, gtk_tree_path_free (path); } } - - - /* appease GtkTreeView by preventing its drag_data_receive - * from being called */ - g_signal_stop_emission_by_name (GTK_TREE_VIEW (view), - "drag_data_received"); } static gboolean diff --git a/src/bookmarks/ephy-bookmarks-editor.c b/src/bookmarks/ephy-bookmarks-editor.c index 5ff95844d..2049ad0df 100644 --- a/src/bookmarks/ephy-bookmarks-editor.c +++ b/src/bookmarks/ephy-bookmarks-editor.c @@ -1157,6 +1157,7 @@ ephy_bookmarks_editor_update_menu (EphyBookmarksEditor *editor) gboolean key_normal = FALSE; gboolean cut, copy, paste, select_all; gboolean can_show_in_bookmarks_bar, show_in_bookmarks_bar = FALSE; + gboolean mutable = TRUE; GtkActionGroup *action_group; GtkAction *action; GList *selected; @@ -1229,6 +1230,7 @@ ephy_bookmarks_editor_update_menu (EphyBookmarksEditor *editor) id = ephy_node_get_id (node); show_in_bookmarks_bar = ephy_bookmarksbar_model_has_bookmark (editor->priv->tb_model, id); + mutable = !ephy_node_get_property_boolean (node, EPHY_NODE_BMK_PROP_IMMUTABLE); g_list_free (selected); } @@ -1251,11 +1253,11 @@ ephy_bookmarks_editor_update_menu (EphyBookmarksEditor *editor) open_in_window = (bmk_focus && bmk_selection); open_in_tab = (bmk_focus && bmk_selection); - rename = (bmk_focus && single_bmk_selected) || + rename = (bmk_focus && single_bmk_selected && mutable) || (key_selection && key_focus && key_normal); delete = (bmk_focus && bmk_selection) || (key_selection && key_focus && key_normal); - properties = (bmk_focus && single_bmk_selected); + properties = bmk_focus && single_bmk_selected && mutable; can_show_in_bookmarks_bar = (bmk_focus && single_bmk_selected) || (key_selection && key_focus); diff --git a/src/bookmarks/ephy-bookmarks.c b/src/bookmarks/ephy-bookmarks.c index 25045438d..5ca86de27 100644 --- a/src/bookmarks/ephy-bookmarks.c +++ b/src/bookmarks/ephy-bookmarks.c @@ -41,14 +41,16 @@ #include <string.h> #include <glib/gi18n.h> #include <libgnomevfs/gnome-vfs-utils.h> +#include <libgnomevfs/gnome-vfs-dns-sd.h> #include <gtk/gtkmessagedialog.h> #include <gtk/gtkdialog.h> #define EPHY_BOOKMARKS_XML_ROOT "ephy_bookmarks" #define EPHY_BOOKMARKS_XML_VERSION "1.03" -#define BOOKMARKS_SAVE_DELAY (3 * 1000) +#define BOOKMARKS_SAVE_DELAY (3 * 1000) /* ms */ #define MAX_FAVORITES_NUM 10 #define UPDATE_URI_DATA_KEY "updated-uri" +#define SD_RESOLVE_TIMEOUT (3 * 1000) /* ms */ #define EPHY_BOOKMARKS_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_BOOKMARKS, EphyBookmarksPrivate)) @@ -70,6 +72,11 @@ struct _EphyBookmarksPrivate double lower_score; GHashTable *props_dialogs; guint disable_bookmark_editing_notifier_id; + + /* Local sites */ + EphyNode *local; + GnomeVFSDNSSDBrowseHandle *browse_handle; + GList *resolve_list; }; typedef struct @@ -317,7 +324,17 @@ save_filter (EphyNode *node, return node != priv->bookmarks && node != priv->favorites && - node != priv->notcategorized; + node != priv->notcategorized && + node != priv->local; +} + +static gboolean +save_filter_local (EphyNode *node, + EphyBookmarks *bookmarks) +{ + EphyBookmarksPrivate *priv = bookmarks->priv; + + return !ephy_node_has_child (priv->local, node); } static void @@ -333,7 +350,7 @@ ephy_bookmarks_save (EphyBookmarks *eb) (xmlChar *) EPHY_BOOKMARKS_XML_VERSION, (xmlChar *) "Do not rely on this file, it's only for internal use. Use bookmarks.rdf instead.", eb->priv->keywords, (EphyNodeFilterFunc) save_filter, eb, - eb->priv->bookmarks, NULL, NULL, + eb->priv->bookmarks, (EphyNodeFilterFunc) save_filter_local, eb, NULL); /* Export bookmarks in rdf */ @@ -621,6 +638,7 @@ update_bookmark_keywords (EphyBookmarks *eb, EphyNode *bookmark) if (kid != eb->priv->notcategorized && kid != eb->priv->favorites && kid != eb->priv->bookmarks && + kid != eb->priv->local && ephy_node_has_child (kid, bookmark)) { const char *topic; @@ -689,6 +707,7 @@ bookmark_is_categorized (EphyBookmarks *eb, EphyNode *bookmark) if (kid != eb->priv->notcategorized && kid != eb->priv->favorites && kid != eb->priv->bookmarks && + kid != eb->priv->local && ephy_node_has_child (kid, bookmark)) { return TRUE; @@ -776,6 +795,154 @@ backup_file (const char *original_filename, const char *extension) } static void +resolve_cb (GnomeVFSDNSSDResolveHandle *handle, + GnomeVFSResult result, + const GnomeVFSDNSSDService *service, + const char *host, + int port, + const GHashTable *text, + int text_raw_len, + const char *text_raw, + gpointer callback_data) +{ + EphyBookmarks *bookmarks = (EphyBookmarks *) callback_data; + EphyBookmarksPrivate *priv = bookmarks->priv; + EphyNode *node; + GValue value = { 0, }; + const char *path; + char *url; + + priv->resolve_list = g_list_remove (priv->resolve_list, handle); + + if (result != GNOME_VFS_OK) return; + + if (text != NULL) + { + path = g_hash_table_lookup ((GHashTable *) text, "path"); + } + else + { + path = "/"; + } + + url = g_strdup_printf ("http://%s:%d%s", host, port, path); + + node = ephy_node_new (priv->db); + if (node == NULL) return; + + /* don't allow dragging this node */ + ephy_node_set_is_drag_source (node, FALSE); + + g_value_init (&value, G_TYPE_STRING); + g_value_set_string (&value, service->name); + ephy_node_set_property (node, EPHY_NODE_BMK_PROP_TITLE, &value); + g_value_unset (&value); + + g_value_init (&value, G_TYPE_STRING); + g_value_take_string (&value, url); + ephy_node_set_property (node, EPHY_NODE_BMK_PROP_LOCATION, &value); + g_value_unset (&value); + + g_value_init (&value, G_TYPE_BOOLEAN); + g_value_set_boolean (&value, TRUE); + ephy_node_set_property (node, EPHY_NODE_BMK_PROP_IMMUTABLE, &value); + g_value_unset (&value); + +#if 0 + /* FIXME what was that about ??? */ + g_value_init (&value, G_TYPE_INT); + g_value_set_int (&value, EPHY_NODE_SPECIAL_PRIORITY); + ephy_node_set_property (priv->local, + EPHY_NODE_KEYWORD_PROP_PRIORITY, + &value); + g_value_unset (&value); +#endif + + ephy_node_add_child (priv->bookmarks, node); + ephy_node_add_child (priv->local, node); +} + +static void +browse_cb (GnomeVFSDNSSDBrowseHandle *handle, + GnomeVFSDNSSDServiceStatus status, + const GnomeVFSDNSSDService *service, + EphyBookmarks *bookmarks) +{ + EphyBookmarksPrivate *priv = bookmarks->priv; + GnomeVFSDNSSDResolveHandle *reshandle = NULL; + GPtrArray *children; + EphyNode *kid; + const char *title; + guint i; + + if (status == GNOME_VFS_DNS_SD_SERVICE_REMOVED) + { + /* Find the bookmark to remove */ + children = ephy_node_get_children (priv->local); + for (i = 0; i < children->len; i++) + { + kid = g_ptr_array_index (children, i); + title = ephy_node_get_property_string (kid, EPHY_NODE_BMK_PROP_TITLE); + + if (g_str_equal (title, service->name)) + { + ephy_node_remove_child (priv->local, kid); + break; + } + } + + return; + } + + /* status == GNOME_VFS_DNS_SD_SERVICE_ADDED */ + + if (gnome_vfs_dns_sd_resolve (&reshandle, + service->name, service->type, service->domain, + SD_RESOLVE_TIMEOUT, + resolve_cb, + bookmarks, + NULL) == GNOME_VFS_OK) + { + priv->resolve_list = + g_list_prepend (priv->resolve_list, reshandle); + } +} + +static void +ephy_local_bookmarks_init (EphyBookmarks *bookmarks) +{ + EphyBookmarksPrivate *priv = bookmarks->priv; + + if (gnome_vfs_dns_sd_browse (&priv->browse_handle, + "local", "_http._tcp", + (GnomeVFSDNSSDBrowseCallback) browse_cb, + bookmarks, + NULL) != GNOME_VFS_OK) + { + priv->browse_handle = NULL; + ephy_node_remove_child (priv->keywords, priv->local); + } +} + +static void +ephy_local_bookmarks_stop (EphyBookmarks *bookmarks) +{ + EphyBookmarksPrivate *priv = bookmarks->priv; + + if (priv->browse_handle != NULL) + { + gnome_vfs_dns_sd_stop_browse (priv->browse_handle); + priv->browse_handle = NULL; + ephy_node_remove_child (priv->keywords, priv->local); + } + + g_list_foreach (priv->resolve_list, + (GFunc) gnome_vfs_dns_sd_cancel_resolve, NULL); + g_list_free (priv->resolve_list); + priv->resolve_list = NULL; +} + +static void ephy_bookmarks_init (EphyBookmarks *eb) { GValue value = { 0, }; @@ -870,6 +1037,30 @@ ephy_bookmarks_init (EphyBookmarks *eb) g_value_unset (&value); ephy_node_add_child (eb->priv->keywords, eb->priv->notcategorized); + /* Local Websites */ + eb->priv->local = ephy_node_new_with_id (db, BMKS_LOCAL_NODE_ID); + + /* don't allow drags to this topic */ + ephy_node_set_is_drag_dest (eb->priv->local, FALSE); + + g_value_init (&value, G_TYPE_STRING); + /* Translators: The text before the "|" is context to help you decide on + * the correct translation. You MUST OMIT it in the translated string. */ + /* Translators: this topic contains the local websites bookmarks */ + g_value_set_string (&value, Q_("bookmarks|Local sites")); + ephy_node_set_property (eb->priv->local, + EPHY_NODE_KEYWORD_PROP_NAME, + &value); + g_value_unset (&value); + g_value_init (&value, G_TYPE_INT); + g_value_set_int (&value, EPHY_NODE_SPECIAL_PRIORITY); + ephy_node_set_property (eb->priv->local, + EPHY_NODE_KEYWORD_PROP_PRIORITY, + &value); + g_value_unset (&value); + ephy_node_add_child (eb->priv->keywords, eb->priv->local); + ephy_local_bookmarks_init (eb); + /* Smart bookmarks */ eb->priv->smartbookmarks = ephy_node_new_with_id (db, SMARTBOOKMARKS_NODE_ID); @@ -923,6 +1114,8 @@ ephy_bookmarks_finalize (GObject *object) g_source_remove (eb->priv->save_timeout_id); } + ephy_local_bookmarks_stop (eb); + ephy_bookmarks_save (eb); /* have to do this before unreffing the nodes */ @@ -1360,6 +1553,10 @@ ephy_bookmarks_get_topic_uri (EphyBookmarks *eb, { uri = g_strdup ("topic://Special/Favorites"); } + else if (ephy_bookmarks_get_local (eb) == node) + { + uri = g_strdup ("topic://Special/Local"); + } else { const char *name; @@ -1405,6 +1602,10 @@ ephy_bookmarks_find_keyword (EphyBookmarks *eb, { return ephy_bookmarks_get_favorites (eb); } + else if (strcmp (name, "topic://Special/Local") == 0) + { + return ephy_bookmarks_get_local (eb); + } else if (g_str_has_prefix (name, "topic://")) { topic_name += strlen ("topic://"); @@ -1506,6 +1707,12 @@ ephy_bookmarks_get_favorites (EphyBookmarks *eb) } EphyNode * +ephy_bookmarks_get_local (EphyBookmarks *eb) +{ + return eb->priv->local; +} + +EphyNode * ephy_bookmarks_get_not_categorized (EphyBookmarks *eb) { return eb->priv->notcategorized; diff --git a/src/bookmarks/ephy-bookmarks.h b/src/bookmarks/ephy-bookmarks.h index b9a3ea69c..8acf1ab31 100644 --- a/src/bookmarks/ephy-bookmarks.h +++ b/src/bookmarks/ephy-bookmarks.h @@ -49,7 +49,8 @@ typedef enum EPHY_NODE_BMK_PROP_KEYWORDS = 4, EPHY_NODE_KEYWORD_PROP_NAME = 5, EPHY_NODE_BMK_PROP_ICON = 7, - EPHY_NODE_KEYWORD_PROP_PRIORITY = 8 + EPHY_NODE_KEYWORD_PROP_PRIORITY = 8, + EPHY_NODE_BMK_PROP_IMMUTABLE = 15 } EphyBookmarkProperty; struct _EphyBookmarks @@ -143,6 +144,8 @@ EphyNode *ephy_bookmarks_get_not_categorized (EphyBookmarks *eb); EphyNode *ephy_bookmarks_get_smart_bookmarks (EphyBookmarks *eb); +EphyNode *ephy_bookmarks_get_local (EphyBookmarks *eb); + G_END_DECLS #endif |