static gboolean idle_populate_proposals (GscProviderDevhelp *devhelp) { guint idx = 0; if (devhelp->priv->view == NULL) { devhelp->priv->proposals = g_sequence_new ((GDestroyNotify)g_object_unref); devhelp->priv->scrolled_window = gtk_scrolled_window_new (NULL, NULL); devhelp->priv->view = dh_assistant_view_new (); gtk_widget_show (devhelp->priv->view); gtk_container_add (GTK_CONTAINER (devhelp->priv->scrolled_window), devhelp->priv->view); dh_assistant_view_set_base (DH_ASSISTANT_VIEW (devhelp->priv->view), devhelp->priv->dhbase); gtk_widget_set_size_request (devhelp->priv->scrolled_window, 400, 300); devhelp->priv->populateptr = dh_base_get_keywords (devhelp->priv->dhbase); } while (idx < POPULATE_BATCH && devhelp->priv->populateptr) { DhLink *link = (DhLink *)devhelp->priv->populateptr->data; gchar const *name = dh_link_get_name (link); if (valid_link_type (dh_link_get_link_type (link)) && name != NULL && *name != '\0') { GscDevhelpItem *proposal = g_object_new (gsc_devhelp_item_get_type (), NULL); proposal->link = link; proposal->word = string_for_compare (dh_link_get_name (proposal->link)); g_sequence_insert_sorted (devhelp->priv->proposals, proposal, (GCompareDataFunc)compare_two_items, NULL); } ++idx; devhelp->priv->populateptr = g_list_next (devhelp->priv->populateptr); } return devhelp->priv->populateptr != NULL; }
static void gsc_provider_devhelp_update_info (GtkSourceCompletionProvider *provider, GtkSourceCompletionProposal *proposal, GtkSourceCompletionInfo *info) { GscProviderDevhelp *self = GSC_PROVIDER_DEVHELP (provider); const gchar *uri = dh_link_get_name (((GscDevhelpItem *)proposal)->link); dh_assistant_view_search (DH_ASSISTANT_VIEW (self->priv->view), uri); }
static gchar * gsc_devhelp_item_get_text_impl (GtkSourceCompletionProposal *proposal) { return g_strdup (dh_link_get_name (((GscDevhelpItem *)proposal)->link)); }
gboolean dh_assistant_view_search (DhAssistantView *view, const gchar *str) { DhAssistantViewPriv *priv; const gchar *name; DhLink *link; DhLink *exact_link; DhLink *prefix_link; DhBookManager *book_manager; GList *books; g_return_val_if_fail (DH_IS_ASSISTANT_VIEW (view), FALSE); g_return_val_if_fail (str, FALSE); priv = GET_PRIVATE (view); /* Filter out very short strings. */ if (strlen (str) < 4) { return FALSE; } if (priv->current_search && strcmp (priv->current_search, str) == 0) { return FALSE; } g_free (priv->current_search); priv->current_search = g_strdup (str); book_manager = dh_base_get_book_manager (dh_assistant_view_get_base (view)); prefix_link = NULL; exact_link = NULL; for (books = dh_book_manager_get_books (book_manager); !exact_link && books; books = g_list_next (books)) { GList *l; for (l = dh_book_get_keywords (DH_BOOK (books->data)); l && exact_link == NULL; l = l->next) { DhLinkType type; link = l->data; type = dh_link_get_link_type (link); if (type == DH_LINK_TYPE_BOOK || type == DH_LINK_TYPE_PAGE || type == DH_LINK_TYPE_KEYWORD) { continue; } name = dh_link_get_name (link); if (strcmp (name, str) == 0) { exact_link = link; } else if (g_str_has_prefix (name, str)) { /* Prefer shorter prefix matches. */ if (!prefix_link) { prefix_link = link; } else if (strlen (dh_link_get_name (prefix_link)) > strlen (name)) { prefix_link = link; } } } } if (exact_link) { /*g_print ("exact hit: '%s' '%s'\n", exact_link->name, str);*/ dh_assistant_view_set_link (view, exact_link); } else if (prefix_link) { /*g_print ("prefix hit: '%s' '%s'\n", prefix_link->name, str);*/ dh_assistant_view_set_link (view, prefix_link); } else { /*g_print ("no hit\n");*/ /*assistant_view_set_link (view, NULL);*/ return FALSE; } return TRUE; }
/** * dh_assistant_view_set_link: * @view: an devhelp assistant view * @link: the #DhLink * * Open @link in the assistant view, if %NULL the view will be blanked. * * Return value: %TRUE if the requested link is open, %FALSE otherwise. **/ gboolean dh_assistant_view_set_link (DhAssistantView *view, DhLink *link) { DhAssistantViewPriv *priv; gchar *uri; const gchar *anchor; gchar *filename; GMappedFile *file; const gchar *contents; gsize length; gchar *key; gsize key_length; gsize offset = 0; const gchar *start; const gchar *end; g_return_val_if_fail (DH_IS_ASSISTANT_VIEW (view), FALSE); priv = GET_PRIVATE (view); if (priv->link == link) { return TRUE; } if (priv->link) { dh_link_unref (priv->link); priv->link = NULL; } if (link) { link = dh_link_ref (link); } else { webkit_web_view_load_uri (WEBKIT_WEB_VIEW (view), "about:blank"); return TRUE; } uri = dh_link_get_uri (link); anchor = strrchr (uri, '#'); if (anchor) { filename = g_strndup (uri, anchor - uri); anchor++; g_free (uri); } else { g_free (uri); return FALSE; } if (g_str_has_prefix (filename, "file://")) offset = 7; file = g_mapped_file_new (filename + offset, FALSE, NULL); if (!file) { g_free (filename); return FALSE; } contents = g_mapped_file_get_contents (file); length = g_mapped_file_get_length (file); key = g_strdup_printf ("<a name=\"%s\"", anchor); key_length = strlen (key); start = find_in_buffer (contents, key, length, key_length); g_free (key); end = NULL; if (start) { const gchar *start_key; const gchar *end_key; length -= start - contents; start_key = "<pre class=\"programlisting\">"; start = find_in_buffer (start, start_key, length, strlen (start_key)); end_key = "<div class=\"refsect"; if (start) { end = find_in_buffer (start, end_key, length - strlen (start_key), strlen (end_key)); if (!end) { end_key = "<div class=\"footer"; end = find_in_buffer (start, end_key, length - strlen (start_key), strlen (end_key)); } } } if (start && end) { gchar *buf; gboolean break_line; const gchar *function; gchar *stylesheet; gchar *javascript; gchar *html; buf = g_strndup (start, end-start); /* Try to reformat function signatures so they take less * space and look nicer. Don't reformat things that don't * look like functions. */ switch (dh_link_get_link_type (link)) { case DH_LINK_TYPE_FUNCTION: break_line = TRUE; function = "onload=\"reformatSignature()\""; break; case DH_LINK_TYPE_MACRO: break_line = TRUE; function = "onload=\"cleanupSignature()\""; break; default: break_line = FALSE; function = ""; break; } if (break_line) { gchar *name; name = strstr (buf, dh_link_get_name (link)); if (name && name > buf) { name[-1] = '\n'; } } stylesheet = dh_util_build_data_filename ("devhelp", "assistant", "assistant.css", NULL); javascript = dh_util_build_data_filename ("devhelp", "assistant", "assistant.js", NULL); html = g_strdup_printf ( "<html>" "<head>" "<link rel=\"stylesheet\" type=\"text/css\" href=\"file://%s\"/>" "<script src=\"file://%s\"></script>" "</head>" "<body %s>" "<div class=\"title\">%s: <a href=\"%s\">%s</a></div>" "<div class=\"subtitle\">%s %s</div>" "<div class=\"content\">%s</div>" "</body>" "</html>", stylesheet, javascript, function, dh_link_get_type_as_string (link), dh_link_get_uri (link), dh_link_get_name (link), _("Book:"), dh_link_get_book_name (link), buf); g_free (buf); g_free (stylesheet); g_free (javascript); priv->snippet_loaded = FALSE; webkit_web_view_load_string ( WEBKIT_WEB_VIEW (view), html, "text/html", NULL, filename); g_free (html); } else { webkit_web_view_load_uri (WEBKIT_WEB_VIEW (view), "about:blank"); } #if GLIB_CHECK_VERSION(2,21,3) g_mapped_file_unref (file); #else g_mapped_file_free (file); #endif g_free (filename); return TRUE; }