[yelp/yelp-3-0] [yelp-document] Offer list of valid page IDs, used for search completion



commit 4884009ab66ee3da0a2253b01327dafccc972584
Author: Shaun McCance <shaunm gnome org>
Date:   Thu Mar 25 18:25:21 2010 -0500

    [yelp-document] Offer list of valid page IDs, used for search completion

 libyelp/yelp-document.c |   36 +++++++++++++++++++++++++
 libyelp/yelp-document.h |   15 +---------
 libyelp/yelp-view.c     |   17 ++++++++++++
 libyelp/yelp-view.h     |    1 +
 src/yelp-window.c       |   66 ++++++++++++++++++++++++++++++++++++++++++-----
 5 files changed, 115 insertions(+), 20 deletions(-)
---
diff --git a/libyelp/yelp-document.c b/libyelp/yelp-document.c
index 3c79dc9..7914b3b 100644
--- a/libyelp/yelp-document.c
+++ b/libyelp/yelp-document.c
@@ -63,6 +63,7 @@ struct _YelpDocumentPriv {
     /* Real page IDs map to themselves, so this list doubles
      * as a list of all valid page IDs.
      */
+    GHashTable *core_ids;  /* Mapping of real IDs to themselves, for a set */
     Hash   *page_ids;      /* Mapping of fragment IDs to real page IDs */
     Hash   *titles;        /* Mapping of page IDs to titles */
     Hash   *descs;         /* Mapping of page IDs to descs */
@@ -222,6 +223,7 @@ yelp_document_init (YelpDocument *document)
     priv->reqs_all = NULL;
     priv->reqs_pending = NULL;
 
+    priv->core_ids = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
     priv->page_ids = hash_new (g_free );
     priv->titles = hash_new (g_free);
     priv->descs = hash_new (g_free);
@@ -270,6 +272,8 @@ yelp_document_finalize (GObject *object)
     hash_free (document->priv->next_ids);
     hash_free (document->priv->up_ids);
 
+    g_hash_table_destroy (document->priv->core_ids);
+
     g_mutex_free (document->priv->mutex);
 
     G_OBJECT_CLASS (yelp_document_parent_class)->finalize (object);
@@ -277,6 +281,31 @@ yelp_document_finalize (GObject *object)
 
 /******************************************************************************/
 
+gchar **
+yelp_document_list_page_ids (YelpDocument *document)
+{
+    GList *lst, *cur;
+    gint i;
+    gchar **ret = NULL;
+
+    g_assert (document != NULL && YELP_IS_DOCUMENT (document));
+
+    g_mutex_lock (document->priv->mutex);
+
+    lst = g_hash_table_get_keys (document->priv->core_ids);
+    ret = g_new0 (gchar *, g_list_length (lst) + 1);
+    i = 0;
+    for (cur = lst; cur != NULL; cur = cur->next) {
+        ret[i] = g_strdup ((gchar *) cur->data);
+        i++;
+    }
+    g_list_free (lst);
+
+    g_mutex_unlock (document->priv->mutex);
+
+    return ret;
+}
+
 gchar *
 yelp_document_get_page_id (YelpDocument *document,
 			   const gchar  *id)
@@ -321,6 +350,13 @@ yelp_document_set_page_id (YelpDocument *document,
 	    hash_remove (document->priv->reqs_by_page_id, id);
     }
 
+    if (page_id != NULL) {
+        if (g_hash_table_lookup (document->priv->core_ids, page_id) == NULL) {
+            gchar *ins = g_strdup (page_id);
+            g_hash_table_insert (document->priv->core_ids, ins, ins);
+        }
+    }
+
     g_mutex_unlock (document->priv->mutex);
 }
 
diff --git a/libyelp/yelp-document.h b/libyelp/yelp-document.h
index 674da05..4366a48 100644
--- a/libyelp/yelp-document.h
+++ b/libyelp/yelp-document.h
@@ -96,6 +96,8 @@ const gchar *     yelp_document_read_contents  (YelpDocument         *document,
 void              yelp_document_finish_read    (YelpDocument         *document,
                                                 const gchar          *contents);
 
+gchar **          yelp_document_list_page_ids  (YelpDocument         *document);
+
 gchar *           yelp_document_get_page_id    (YelpDocument         *document,
                                                 const gchar          *id);
 void              yelp_document_set_page_id    (YelpDocument         *document,
@@ -150,19 +152,6 @@ void              yelp_document_signal         (YelpDocument         *document,
                                                 const GError         *error);
 void              yelp_document_error_pending  (YelpDocument         *document,
                                                 const GError         *error);
-/* FIXME */
-/*
-void              yelp_document_error_request  (YelpDocument        *document,
-                                                gint                 req_id,
-                                                YelpError           *error);
-void              yelp_document_error_page     (YelpDocument        *document,
-                                                gchar               *page_id,
-                                                YelpError           *error);
-void              yelp_document_error_pending  (YelpDocument        *document,
-                                                YelpError           *error);
-void              yelp_document_final_pending  (YelpDocument        *document,
-                                                YelpError           *error);
-*/
 
 G_END_DECLS
 
diff --git a/libyelp/yelp-view.c b/libyelp/yelp-view.c
index e269e60..365d4b6 100644
--- a/libyelp/yelp-view.c
+++ b/libyelp/yelp-view.c
@@ -91,6 +91,7 @@ enum {
 enum {
     NEW_VIEW_REQUESTED,
     EXTERNAL_URI,
+    LOADED,
     LAST_SIGNAL
 };
 static gint signals[LAST_SIGNAL] = { 0 };
@@ -212,6 +213,14 @@ yelp_view_class_init (YelpViewClass *klass)
 		      g_cclosure_marshal_VOID__OBJECT,
 		      G_TYPE_NONE, 1, YELP_TYPE_URI);
 
+    signals[LOADED] =
+        g_signal_new ("loaded",
+                      G_TYPE_FROM_CLASS (klass),
+                      G_SIGNAL_RUN_LAST,
+                      0, NULL, NULL,
+                      g_cclosure_marshal_VOID__VOID,
+                      G_TYPE_NONE, 0);
+
     g_type_class_add_private (klass, sizeof (YelpViewPrivate));
 
     g_object_class_install_property (object_class,
@@ -386,6 +395,13 @@ yelp_view_load_document (YelpView     *view,
     view_load_page (view);
 }
 
+YelpDocument *
+yelp_view_get_document (YelpView *view)
+{
+    YelpViewPrivate *priv = GET_PRIV (view);
+    return g_object_ref (priv->document);
+}
+
 /******************************************************************************/
 
 static gboolean
@@ -698,6 +714,7 @@ document_callback (YelpDocument       *document,
         g_free (page_id);
         g_free (mime_type);
 	yelp_document_finish_read (document, contents);
+        g_signal_emit (view, signals[LOADED], 0);
     }
     else if (signal == YELP_DOCUMENT_SIGNAL_ERROR) {
         view_show_error_page (view, error);
diff --git a/libyelp/yelp-view.h b/libyelp/yelp-view.h
index 70b4314..ea2238f 100644
--- a/libyelp/yelp-view.h
+++ b/libyelp/yelp-view.h
@@ -69,6 +69,7 @@ void             yelp_view_load_uri        (YelpView     *view,
 void             yelp_view_load_document   (YelpView     *view,
 					    YelpUri      *uri,
 					    YelpDocument *document);
+YelpDocument *   yelp_view_get_document    (YelpView     *view);
 
 G_END_DECLS
 
diff --git a/src/yelp-window.c b/src/yelp-window.c
index b6253bd..1cbc769 100644
--- a/src/yelp-window.c
+++ b/src/yelp-window.c
@@ -69,6 +69,8 @@ static void          back_button_clicked          (GtkWidget          *button,
 static void          view_external_uri            (YelpView           *view,
                                                    YelpUri            *uri,
                                                    YelpWindow         *window);
+static void          view_loaded                  (YelpView           *view,
+                                                   YelpWindow         *window);
 static void          view_uri_selected            (YelpView           *view,
                                                    GParamSpec         *pspec,
                                                    YelpWindow         *window);
@@ -101,8 +103,8 @@ enum {
   COL_TITLE,
   COL_DESC,
   COL_ICON,
-  COL_FLAGS,
   COL_URI,
+  COL_FLAGS,
   COL_TERMS
 };
 
@@ -126,6 +128,7 @@ back_entry_free (YelpBackEntry *back)
 typedef struct _YelpWindowPrivate YelpWindowPrivate;
 struct _YelpWindowPrivate {
     GtkListStore *history;
+    GtkListStore *completion;
     GtkActionGroup *action_group;
     YelpApplication *application;
 
@@ -225,10 +228,16 @@ yelp_window_init (YelpWindow *window)
                                         G_TYPE_STRING,  /* title */
                                         G_TYPE_STRING,  /* desc */
                                         G_TYPE_STRING,  /* icon */
-                                        G_TYPE_INT,     /* flags */
                                         G_TYPE_STRING,  /* uri */
+                                        G_TYPE_INT,     /* flags */
                                         G_TYPE_STRING   /* search terms */
                                         );
+    priv->completion = gtk_list_store_new (4,
+                                           G_TYPE_STRING,  /* title */
+                                           G_TYPE_STRING,  /* desc */
+                                           G_TYPE_STRING,  /* icon */
+                                           G_TYPE_STRING   /* uri */
+                                           );
     priv->entry = (YelpLocationEntry *)
         yelp_location_entry_new_with_model (GTK_TREE_MODEL (priv->history),
                                             COL_TITLE,
@@ -237,7 +246,7 @@ yelp_window_init (YelpWindow *window)
                                             COL_FLAGS);
 
     yelp_location_entry_set_completion_model (YELP_LOCATION_ENTRY (priv->entry),
-                                              GTK_TREE_MODEL (priv->history),
+                                              GTK_TREE_MODEL (priv->completion),
                                               COL_TITLE,
                                               COL_DESC,
                                               COL_ICON);
@@ -271,6 +280,7 @@ yelp_window_init (YelpWindow *window)
 
     priv->view = (YelpView *) yelp_view_new ();
     g_signal_connect (priv->view, "external-uri", G_CALLBACK (view_external_uri), window);
+    g_signal_connect (priv->view, "loaded", G_CALLBACK (view_loaded), window);
     g_signal_connect (priv->view, "notify::yelp-uri", G_CALLBACK (view_uri_selected), window);
     g_signal_connect (priv->view, "notify::root-title", G_CALLBACK (view_root_title), window);
     g_signal_connect (priv->view, "notify::page-title", G_CALLBACK (view_page_title), window);
@@ -488,11 +498,22 @@ entry_completion_selected (YelpLocationEntry  *entry,
                            GtkTreeIter        *iter,
                            YelpWindow         *window)
 {
-    gchar *uri;
+    YelpUri *base, *uri;
+    gchar *page, *xref;
     YelpWindowPrivate *priv = GET_PRIV (window);
-    gtk_tree_model_get (model, iter, COL_URI, &uri, -1);
-    yelp_view_load (priv->view, uri);
-    g_free (uri);
+
+    base = ((YelpBackEntry *) priv->back_list->data)->uri;
+    gtk_tree_model_get (model, iter, COL_URI, &page, -1);
+
+    xref = g_strconcat ("xref:", page, NULL);
+    uri = yelp_uri_new_relative (base, xref);
+
+    yelp_view_load_uri (priv->view, uri);
+
+    g_free (page);
+    g_free (xref);
+    g_object_unref (uri);
+
     gtk_widget_grab_focus (GTK_WIDGET (priv->view));
 }
 
@@ -533,6 +554,37 @@ view_external_uri (YelpView   *view,
 }
 
 static void
+view_loaded (YelpView   *view,
+             YelpWindow *window)
+{
+    gchar **ids;
+    gint i;
+    YelpWindowPrivate *priv = GET_PRIV (window);
+    YelpDocument *document = yelp_view_get_document (view);
+    ids = yelp_document_list_page_ids (document);
+
+    gtk_list_store_clear (priv->completion);
+    for (i = 0; ids[i]; i++) {
+        GtkTreeIter iter;
+        gchar *title, *desc;
+        gtk_list_store_insert (GTK_LIST_STORE (priv->completion), &iter, 0);
+        title = yelp_document_get_page_title (document, ids[i]);
+        desc = yelp_document_get_page_desc (document, ids[i]);
+        gtk_list_store_set (priv->completion, &iter,
+                            COL_TITLE, title,
+                            COL_DESC, desc,
+                            COL_ICON, "help-browser",
+                            COL_URI, ids[i],
+                            -1);
+        g_free (desc);
+        g_free (title);
+    }
+
+    g_strfreev (ids);
+    g_object_unref (document);
+}
+
+static void
 view_uri_selected (YelpView     *view,
                    GParamSpec   *pspec,
                    YelpWindow   *window)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]