SF.net SVN: geany-plugins:[2082] trunk/geany-plugins/devhelp
codebrainz at users.sourceforge.net
codebrainz at xxxxx
Tue May 24 09:04:07 UTC 2011
Revision: 2082
http://geany-plugins.svn.sourceforge.net/geany-plugins/?rev=2082&view=rev
Author: codebrainz
Date: 2011-05-24 09:04:06 +0000 (Tue, 24 May 2011)
Log Message:
-----------
More massive re-factoring, cleanup, and renaming.
Modified Paths:
--------------
trunk/geany-plugins/devhelp/data/devhelp.conf
trunk/geany-plugins/devhelp/src/Makefile.am
trunk/geany-plugins/devhelp/wscript_build
trunk/geany-plugins/devhelp/wscript_configure
Added Paths:
-----------
trunk/geany-plugins/devhelp/src/dhp-codesearch.c
trunk/geany-plugins/devhelp/src/dhp-manpages.c
trunk/geany-plugins/devhelp/src/dhp-object.c
trunk/geany-plugins/devhelp/src/dhp-plugin.c
trunk/geany-plugins/devhelp/src/dhp-plugin.h
trunk/geany-plugins/devhelp/src/dhp-settings.c
trunk/geany-plugins/devhelp/src/dhp.h
Removed Paths:
-------------
trunk/geany-plugins/devhelp/src/codesearch.c
trunk/geany-plugins/devhelp/src/devhelpplugin.c
trunk/geany-plugins/devhelp/src/devhelpplugin.h
trunk/geany-plugins/devhelp/src/main-notebook.c
trunk/geany-plugins/devhelp/src/main-notebook.h
trunk/geany-plugins/devhelp/src/manpages.c
trunk/geany-plugins/devhelp/src/plugin.c
trunk/geany-plugins/devhelp/src/plugin.h
Modified: trunk/geany-plugins/devhelp/data/devhelp.conf
===================================================================
--- trunk/geany-plugins/devhelp/data/devhelp.conf 2011-05-23 11:30:31 UTC (rev 2081)
+++ trunk/geany-plugins/devhelp/data/devhelp.conf 2011-05-24 09:04:06 UTC (rev 2082)
@@ -1,4 +1,67 @@
-[general]
-move_sidebar_tabs_bottom=true
-show_in_message_window=false
+
+[webview]
+# Which notebook gets the webview
+# 0 - None (hidden)
+# 1 - Sidebar
+# 2 - Message Window
+# 3 - A new "Main Notebook"
+location=3
+
+# When a search is triggered through the UI or keybinding, focus the webview
+# (show it's notebook page).
+focus_webview_on_search=true
+
+# If set, it's a URI to show in the webview when the plugin is loaded
+# If left blank, the last URI that was shown is used
+custom_homepage=
+
+# Tracks the last URI shown in the webview.
+# This is set by the plugin automatically on unload.
+# If not set (initial) custom_homepage will be shown if set or a default
+# page otherwise.
last_uri=
+
+
+[doc_providers]
+# Use the integrated Devhelp widgets/features.
+devhelp=true
+# Use the system's manual pages (if man program is available)
+man_pages=true
+# Search Google Code and put the result page in the webview
+codesearch=true
+
+[devhelp]
+# Use the devhelp sidebar (search and browser UI).
+show_devhelp_sidebar=true
+# When using the devhelp sidebar, move the main sidebar's tabs to the bottom.
+set_sidebar_tabs_bottom=true
+# When searching with Devhelp, show the tab with the Devhelp sidebar in it.
+focus_sidebar_on_search=true
+
+[man_pages]
+# If the manual page program isn't in the path, you can set it's path.
+prog_path=man
+# Value to pass to -P option of man program
+pager_prog=col -b
+# Search manual page sections in this order. This value is directly passed
+# the man program's -S option.
+section_order=3:2:1:8:5:4:7:6
+
+[codesearch]
+base_uri=http://www.google.com/codesearch
+
+# If Geany's filetype can be mapped to a Google code search language, then
+# specify the language to narrow down the search.
+use_lang_for_search=true
+
+# Other parameteres added to the end of the search URI just before loading
+# the URI in the webview.
+uri_params=
+
+[misc]
+# Where to put the tabs in the "main notebook" if it's being used.
+# 0 - Left
+# 1 - Right
+# 2 - Top
+# 3 - Bottom
+main_notebook_tab_pos=3
Modified: trunk/geany-plugins/devhelp/src/Makefile.am
===================================================================
--- trunk/geany-plugins/devhelp/src/Makefile.am 2011-05-23 11:30:31 UTC (rev 2081)
+++ trunk/geany-plugins/devhelp/src/Makefile.am 2011-05-24 09:04:06 UTC (rev 2082)
@@ -10,16 +10,14 @@
endif
devhelp_la_SOURCES = \
- main-notebook.c \
- devhelpplugin.c \
- plugin.c \
- manpages.c \
- codesearch.c
+ dhp-codesearch.c \
+ dhp-manpages.c \
+ dhp-object.c \
+ dhp-plugin.c
noinst_HEADERS = \
- plugin.h \
- devhelpplugin.h \
- main-notebook.h
+ dhp.h \
+ dhp-plugin.h
devhelp_la_CFLAGS = \
$(AM_CFLAGS) \
Deleted: trunk/geany-plugins/devhelp/src/codesearch.c
===================================================================
--- trunk/geany-plugins/devhelp/src/codesearch.c 2011-05-23 11:30:31 UTC (rev 2081)
+++ trunk/geany-plugins/devhelp/src/codesearch.c 2011-05-24 09:04:06 UTC (rev 2082)
@@ -1,96 +0,0 @@
-#include <glib.h>
-#include <webkit/webkitwebview.h>
-
-#include "devhelpplugin.h"
-
-
-struct LangMapEnt
-{
- const gchar *geany_name;
- const gchar *google_name;
-};
-
-
-#define GOOGLE_CODE_SEARCH_URI "http://www.google.com/codesearch"
-
-#define LANG_MAP_MAX 33 /* update this with lang_map[] size below */
-
-/* maps Geany language names to Google Code language names */
-static const struct LangMapEnt lang_map[LANG_MAP_MAX] = {
- { "ActionScript", "actionscript" },
- { "Ada", "ada" },
- { "ASM", "assembly" },
- { "FreeBasic", "basic" },
- { "C", "c" },
- { "C++", "c++" },
- { "C#", "c#" },
- { "COBOL", "cobol" },
- { "CSS", "css" },
- { "D", "d" },
- { "Erlang", "erlang" },
- { "Fortran", "fortran" },
- { "Haskell", "haskell" },
- { "Java", "java" },
- { "Javascript", "javascript" },
- { "Lisp", "lisp" },
- { "Lua", "lua" },
- { "Make", "makefile" },
- { "Matlab/Octave", "matlab" },
- { "CAML", "ocaml" },
- { "Pascal", "pascal" },
- { "Perl", "perl" },
- { "PHP", "php" },
- { "Python", "python" },
- { "R", "r" },
- { "Ruby", "ruby" },
- { "Sh", "shell" },
- { "SQL", "sql" },
- { "Tcl", "tcl" },
- { "LaTeX", "tex" },
- { "Verilog", "verilog" },
- { "VHDL", "vhdl" },
- { "None", NULL }
-};
-
-
-void devhelp_plugin_search_code(DevhelpPlugin *self, const gchar *term, const gchar *lang)
-{
- gint i;
- gchar *uri, *term_enc, *lang_enc;
- const gchar *google_lang = NULL;
-
- g_return_if_fail(self != NULL);
- g_return_if_fail(term != NULL);
-
- if (lang != NULL)
- {
- for (i = 0; i < LANG_MAP_MAX; i++)
- {
- if (g_strcmp0(lang, lang_map[i].geany_name) == 0)
- {
- google_lang = lang_map[i].google_name;
- break;
- }
- }
- }
-
- if (google_lang != NULL)
- {
- lang_enc = g_uri_escape_string(google_lang, NULL, TRUE);
- term_enc = g_uri_escape_string(term, NULL, TRUE);
- uri = g_strdup_printf("%s?as_q=%s&as_lang=%s", GOOGLE_CODE_SEARCH_URI, term_enc, lang_enc);
- g_free(lang_enc);
- g_free(term_enc);
- }
- else
- {
- term_enc = g_uri_escape_string(term, NULL, TRUE);
- uri = g_strdup_printf("%s?as_q=%s", GOOGLE_CODE_SEARCH_URI, term_enc);
- g_free(term_enc);
- }
-
- webkit_web_view_open(devhelp_plugin_get_webview(self), uri);
- g_free(uri);
-
- devhelp_plugin_activate_webview_tab(self);
-}
Deleted: trunk/geany-plugins/devhelp/src/devhelpplugin.c
===================================================================
--- trunk/geany-plugins/devhelp/src/devhelpplugin.c 2011-05-23 11:30:31 UTC (rev 2081)
+++ trunk/geany-plugins/devhelp/src/devhelpplugin.c 2011-05-24 09:04:06 UTC (rev 2082)
@@ -1,1019 +0,0 @@
-/*
- * devhelpplugin.c
- *
- * Copyright 2011 Matthew Brush <mbrush at leftclick.ca>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#include <stdlib.h>
-#include <gtk/gtk.h>
-#include <geanyplugin.h>
-
-#include <devhelp/dh-base.h>
-#include <devhelp/dh-book-tree.h>
-#include <devhelp/dh-search.h>
-#include <devhelp/dh-link.h>
-
-#ifdef HAVE_BOOK_MANAGER /* for newer api */
-#include <devhelp/dh-book-manager.h>
-#endif
-
-#include <webkit/webkitwebview.h>
-
-#include "main-notebook.h"
-#include "devhelpplugin.h"
-#include "plugin.h"
-
-
-struct _DevhelpPluginPrivate
-{
- DhBase* dhbase;
- GtkWidget* book_tree; /* "Contents" in the sidebar */
- GtkWidget* search; /* "Search" in the sidebar */
- GtkWidget* sb_notebook; /* Notebook that holds contents/search */
- gint sb_notebook_tab; /* Index of tab where devhelp sidebar is */
- GtkWidget* webview; /* Webkit that shows documentation */
- gint webview_tab; /* Index of tab that contains the webview */
- GtkWidget* main_notebook; /* Notebook that holds Geany doc notebook and
- * and webkit view */
- GtkWidget* doc_notebook; /* Geany's document notebook */
- GtkWidget* editor_menu_item; /* Item in the editor's context menu */
- GtkWidget* editor_menu_sep; /* Separator item above menu item */
- gboolean webview_active; /* Tracks whether webview stuff is shown */
- gboolean last_main_tab_id; /* These track the last id of the tabs */
- gboolean last_sb_tab_id; /* before toggling */
- gboolean tabs_toggled; /* Tracks state of whether to toggle to
- * Devhelp or back to code */
- gboolean created_main_nb; /* Track whether we created the main notebook */
-
- GtkPositionType orig_sb_tab_pos; /* The tab idx of the initial sidebar tab */
- gboolean sidebar_tab_bottom; /* whether the sidebar tabs are at the bottom */
- gboolean in_message_window; /* whether the webkit stuff is in the msgwin */
-
- gchar* last_uri; /* the last URI loaded before the current */
- gfloat zoom_level; /* the webkit zoom level */
-
- GtkToolItem* btn_back; /* the webkit browser back button in the toolbar */
- GtkToolItem* btn_forward; /* the webkit browser forward button in the toolbar */
-
- gboolean have_man; /* whether or not the 'man' program is available on load */
-
-};
-
-
-G_DEFINE_TYPE(DevhelpPlugin, devhelp_plugin, G_TYPE_OBJECT)
-
-
-static DhBase *dhbase = NULL;
-
-
-/* Internal callbacks */
-static void on_search_help_activate(GtkMenuItem * menuitem, DevhelpPlugin *self);
-static void on_search_help_man_activate(GtkMenuItem * menuitem, DevhelpPlugin *self);
-static void on_search_help_code_activate(GtkMenuItem *menuitem, DevhelpPlugin *self);
-static void on_editor_menu_popup(GtkWidget * widget, DevhelpPlugin *self);
-static void on_link_clicked(GObject * ignored, DhLink * dhlink, DevhelpPlugin *self);
-static void on_back_button_clicked(GtkToolButton * btn, DevhelpPlugin *self);
-static void on_forward_button_clicked(GtkToolButton * btn, DevhelpPlugin *self);
-static void on_zoom_in_button_clicked(GtkToolButton * btn, DevhelpPlugin *self);
-static void on_zoom_out_button_clicked(GtkToolButton *btn, DevhelpPlugin *self);
-static void on_document_load_finished(WebKitWebView *view, WebKitWebFrame *frame, DevhelpPlugin *self);
-static void on_uri_changed_notify(GObject *object, GParamSpec *pspec, DevhelpPlugin *self);
-static void on_load_status_changed_notify(GObject *object, GParamSpec *pspec, DevhelpPlugin *self);
-
-/* Misc internal functions */
-static inline void update_history_buttons(DevhelpPlugin *self);
-
-
-/* Put cleanup code in here */
-static void devhelp_plugin_finalize(GObject * object)
-{
- DevhelpPlugin *self;
-
- g_return_if_fail(object != NULL);
- g_return_if_fail(DEVHELP_IS_PLUGIN(object));
-
- self = DEVHELP_PLUGIN(object);
-
- gtk_widget_destroy(self->priv->sb_notebook);
-
- gtk_notebook_remove_page(GTK_NOTEBOOK(self->priv->main_notebook), self->priv->webview_tab);
-
- if (!self->priv->in_message_window)
- {
- g_debug("Destroying main notebook");
- main_notebook_destroy();
- }
- gtk_widget_destroy(self->priv->editor_menu_sep);
- gtk_widget_destroy(self->priv->editor_menu_item);
-
- gtk_notebook_set_tab_pos(GTK_NOTEBOOK(geany->main_widgets->sidebar_notebook),
- self->priv->orig_sb_tab_pos);
-
- if (self->priv->last_uri != NULL)
- g_free(self->priv->last_uri);
-
- devhelp_plugin_remove_manpages_temp_files();
-
- G_OBJECT_CLASS(devhelp_plugin_parent_class)->finalize(object);
-}
-
-
-static void devhelp_plugin_class_init(DevhelpPluginClass * klass)
-{
- GObjectClass *g_object_class;
-
- g_object_class = G_OBJECT_CLASS(klass);
- g_object_class->finalize = devhelp_plugin_finalize;
- g_type_class_add_private((gpointer) klass, sizeof(DevhelpPluginPrivate));
-}
-
-
-/*
- * Initialize the Devhelp library/widgets.
- * The Devhelp API isn't exactly stable, so handle quirks in here.
- */
-static void devhelp_plugin_init_dh(DevhelpPlugin *self)
-{
-#ifdef HAVE_BOOK_MANAGER /* for newer api */
- DhBookManager *book_manager;
-#else
- GNode *books;
- GList *keywords;
-#endif
-
- if (dhbase == NULL)
- dhbase = dh_base_new();
- self->priv->dhbase = dhbase;
-
-#ifdef HAVE_BOOK_MANAGER /* for newer api */
- book_manager = dh_base_get_book_manager(self->priv->dhbase);
- self->priv->book_tree = dh_book_tree_new(book_manager);
- self->priv->search = dh_search_new(book_manager);
-#else
- books = dh_base_get_book_tree(self->priv->dhbase);
- keywords = dh_base_get_keywords(self->priv->dhbase);
- self->priv->book_tree = dh_book_tree_new(books);
- self->priv->search = dh_search_new(keywords);
-#endif
-
- gtk_widget_show(self->priv->search);
-
- g_signal_connect(self->priv->book_tree, "link-selected", G_CALLBACK(on_link_clicked), self);
- g_signal_connect(self->priv->search, "link-selected", G_CALLBACK(on_link_clicked), self);
-}
-
-
-/* Initialize the stuff in the editor's context menu */
-static void devhelp_plugin_init_edit_menu(DevhelpPlugin *self)
-{
- GtkWidget *doc_menu, *devhelp_item, *code_item, *man_item;
- DevhelpPluginPrivate *p;
-
- g_return_if_fail(self != NULL);
-
- p = self->priv;
-
- p->editor_menu_sep = gtk_separator_menu_item_new();
- p->editor_menu_item = gtk_menu_item_new_with_label(_("Search for 'Tag' Documentation in"));
- doc_menu = gtk_menu_new();
-
- devhelp_item = gtk_menu_item_new_with_label(_("Devhelp"));
- gtk_menu_shell_append(GTK_MENU_SHELL(doc_menu), devhelp_item);
- g_signal_connect(devhelp_item, "activate", G_CALLBACK(on_search_help_activate), self);
- gtk_widget_show(devhelp_item);
-
- if (p->have_man)
- {
- man_item = gtk_menu_item_new_with_label(_("Manual Pages"));
- gtk_menu_shell_append(GTK_MENU_SHELL(doc_menu), man_item);
- g_signal_connect(man_item, "activate", G_CALLBACK(on_search_help_man_activate), self);
- gtk_widget_show(man_item);
- }
-
- code_item = gtk_menu_item_new_with_label(_("Google Code"));
- gtk_menu_shell_append(GTK_MENU_SHELL(doc_menu), code_item);
- g_signal_connect(code_item, "activate", G_CALLBACK(on_search_help_code_activate), self);
- gtk_widget_show(code_item);
-
- g_signal_connect(geany->main_widgets->editor_menu, "show", G_CALLBACK(on_editor_menu_popup), self);
- gtk_menu_item_set_submenu(GTK_MENU_ITEM(p->editor_menu_item), doc_menu);
- gtk_menu_shell_append(GTK_MENU_SHELL(geany->main_widgets->editor_menu), p->editor_menu_sep);
- gtk_menu_shell_append(GTK_MENU_SHELL(geany->main_widgets->editor_menu), p->editor_menu_item);
- gtk_widget_show(p->editor_menu_sep);
- gtk_widget_show_all(p->editor_menu_item);
-}
-
-
-/* Initialize the WebKit browser and associated widgets */
-static void devhelp_plugin_init_webkit(DevhelpPlugin *self)
-{
- GtkWidget *vbox, *label, *toolbar;
- GtkToolItem *btn_zoom_in, *btn_zoom_out, *tb_sep;
- GtkScrolledWindow *webview_sw;
- DevhelpPluginPrivate *p;
-
- g_return_if_fail(self != NULL);
-
- p = self->priv;
-
- p->webview = webkit_web_view_new();
-
- webview_sw = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(NULL, NULL));
- gtk_scrolled_window_set_policy(webview_sw, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type(webview_sw, GTK_SHADOW_ETCHED_IN);
- gtk_container_add(GTK_CONTAINER(webview_sw), p->webview);
-
- gtk_widget_show_all(GTK_WIDGET(webview_sw));
-
- vbox = gtk_vbox_new(FALSE, 0);
- toolbar = gtk_toolbar_new();
-
- p->btn_back = gtk_tool_button_new_from_stock(GTK_STOCK_GO_BACK);
- p->btn_forward = gtk_tool_button_new_from_stock(GTK_STOCK_GO_FORWARD);
- btn_zoom_in = gtk_tool_button_new_from_stock(GTK_STOCK_ZOOM_IN);
- btn_zoom_out = gtk_tool_button_new_from_stock(GTK_STOCK_ZOOM_OUT);
- tb_sep = gtk_separator_tool_item_new();
-
- gtk_widget_set_tooltip_text(GTK_WIDGET(p->btn_back), _("Go back one page"));
- gtk_widget_set_tooltip_text(GTK_WIDGET(p->btn_forward), _("Go forward one page"));
- gtk_widget_set_tooltip_text(GTK_WIDGET(btn_zoom_in), _("Zoom in"));
- gtk_widget_set_tooltip_text(GTK_WIDGET(btn_zoom_out), _("Zoom out"));
-
- gtk_toolbar_insert(GTK_TOOLBAR(toolbar), p->btn_back, -1);
- gtk_toolbar_insert(GTK_TOOLBAR(toolbar), p->btn_forward, -1);
- gtk_toolbar_insert(GTK_TOOLBAR(toolbar), tb_sep, -1);
- gtk_toolbar_insert(GTK_TOOLBAR(toolbar), btn_zoom_in, -1);
- gtk_toolbar_insert(GTK_TOOLBAR(toolbar), btn_zoom_out, -1);
-
- gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, TRUE, 0);
- gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(webview_sw), TRUE, TRUE, 0);
-
- label = gtk_label_new(_("Documentation"));
- gtk_notebook_append_page(GTK_NOTEBOOK(p->main_notebook), vbox, label);
-
- p->webview_tab = gtk_notebook_page_num(GTK_NOTEBOOK(p->main_notebook), vbox);
-
- gtk_widget_show_all(vbox);
-
- g_signal_connect(p->btn_back, "clicked", G_CALLBACK(on_back_button_clicked), self);
- g_signal_connect(p->btn_forward, "clicked", G_CALLBACK(on_forward_button_clicked), self);
- g_signal_connect(btn_zoom_in, "clicked", G_CALLBACK(on_zoom_in_button_clicked), self);
- g_signal_connect(btn_zoom_out, "clicked", G_CALLBACK(on_zoom_out_button_clicked), self);
-
- g_signal_connect(WEBKIT_WEB_VIEW(p->webview), "document-load-finished", G_CALLBACK(on_document_load_finished), self);
- g_signal_connect(WEBKIT_WEB_VIEW(p->webview), "notify::uri", G_CALLBACK(on_uri_changed_notify), self);
- g_signal_connect(WEBKIT_WEB_VIEW(p->webview), "notify::load-status", G_CALLBACK(on_load_status_changed_notify), self);
-
- p->last_uri = g_filename_to_uri(DHPLUG_WEBVIEW_HOME_FILE, NULL, NULL);
- if (p->last_uri != NULL)
- webkit_web_view_load_uri(WEBKIT_WEB_VIEW(p->webview), p->last_uri);
-}
-
-
-/* Initialize the stuff added to the sidebar. */
-static void devhelp_plugin_init_sidebar(DevhelpPlugin *self)
-{
- GtkWidget *label;
- GtkWidget *book_tree_sw;
- DevhelpPluginPrivate *p;
-
- g_return_if_fail(self != NULL);
-
- p = self->priv;
-
- p->sb_notebook = gtk_notebook_new();
- p->orig_sb_tab_pos = gtk_notebook_get_tab_pos(GTK_NOTEBOOK(geany->main_widgets->sidebar_notebook));
-
- book_tree_sw = gtk_scrolled_window_new(NULL, NULL);
- gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(book_tree_sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
- gtk_container_set_border_width(GTK_CONTAINER(book_tree_sw), 6);
- gtk_container_add(GTK_CONTAINER(book_tree_sw), p->book_tree);
- gtk_widget_show(p->book_tree);
-
- label = gtk_label_new(_("Contents"));
- gtk_notebook_append_page(GTK_NOTEBOOK(p->sb_notebook), book_tree_sw, label);
-
- label = gtk_label_new(_("Search"));
- gtk_notebook_append_page(GTK_NOTEBOOK(p->sb_notebook), p->search, label);
-
- gtk_notebook_set_current_page(GTK_NOTEBOOK(p->sb_notebook), 0);
- gtk_widget_show_all(p->sb_notebook);
-
- label = gtk_label_new(_("Devhelp"));
- gtk_notebook_append_page(GTK_NOTEBOOK(geany->main_widgets->sidebar_notebook), p->sb_notebook, label);
-
- p->sb_notebook_tab = gtk_notebook_page_num(GTK_NOTEBOOK(geany->main_widgets->sidebar_notebook), p->sb_notebook);
-}
-
-
-/* Called when a new plugin is being initialized */
-static void devhelp_plugin_init(DevhelpPlugin * self)
-{
- DevhelpPluginPrivate *p;
-
- g_return_if_fail(self != NULL);
-
- self->priv = p = G_TYPE_INSTANCE_GET_PRIVATE(self, DEVHELP_TYPE_PLUGIN, DevhelpPluginPrivate);
- devhelp_plugin_init_dh(self);
-
- p->in_message_window = FALSE;
- p->tabs_toggled = FALSE;
-
- p->doc_notebook = geany->main_widgets->notebook;
- p->main_notebook = main_notebook_get(); /* see main-notebook.c */
- p->have_man = system("man --version") == 0;
-
- devhelp_plugin_init_edit_menu(self);
- devhelp_plugin_init_sidebar(self);
- devhelp_plugin_init_webkit(self);
-
- p->last_main_tab_id = gtk_notebook_get_current_page(GTK_NOTEBOOK(p->main_notebook));
- p->last_sb_tab_id = gtk_notebook_get_current_page(GTK_NOTEBOOK(geany->main_widgets->sidebar_notebook));
-}
-
-
-DevhelpPlugin *devhelp_plugin_new(void)
-{
- return g_object_new(DEVHELP_TYPE_PLUGIN, NULL);
-}
-
-
-void devhelp_plugin_search(DevhelpPlugin *self, const gchar *term)
-{
- /* todo: fallback on manpages */
- devhelp_plugin_search_books(self, term);
-}
-
-
-/**
- * Search for a term in Devhelp and activate/show the plugin's UI stuff.
- *
- * @param dhplug Devhelp plugin
- * @param term The string to search for
- */
-void devhelp_plugin_search_books(DevhelpPlugin *self, const gchar *term)
-{
-
- g_return_if_fail(self != NULL);
- g_return_if_fail(term != NULL);
-
- dh_search_set_search_string(DH_SEARCH(self->priv->search), term, NULL);
-
- devhelp_plugin_activate_all_tabs(self);
-}
-
-
-/**
- * Search for a term in Manual Pages and activate/show the plugin's UI stuff.
- *
- * @param dhplug Devhelp plugin
- * @param term The string to search for
- */
-void devhelp_plugin_search_manpages(DevhelpPlugin *self, const gchar *term)
-{
- gchar *man_fn;
-
- g_return_if_fail(self != NULL);
- g_return_if_fail(term != NULL);
-
- man_fn = devhelp_plugin_manpages_search(term, NULL);
-
- if (man_fn == NULL)
- return;
-
- webkit_web_view_open(WEBKIT_WEB_VIEW(self->priv->webview), man_fn);
-
- g_free(man_fn);
-
- devhelp_plugin_activate_webview_tab(self);
-}
-
-
-/**
- * Cleans up a word/tag before searching.
- *
- * Replaces non @c GEANY_WORDCHARS in str with spaces and then trims whitespace.
- * This function does not allocate a new string, it modifies @a str in place
- * and returns a pointer to @a str.
- * TODO: make this only remove stuff from the start or end of string.
- *
- * @param str String to clean
- *
- * @return Pointer to (cleaned) @a str.
- */
-gchar *devhelp_plugin_clean_word(gchar* str)
-{
- return g_strstrip(g_strcanon(str, GEANY_WORDCHARS, ' '));
-}
-
-/**
- * Gets either the current selection or the word at the current selection.
- *
- * @return Newly allocated string with current tag or NULL no tag.
- */
-gchar *devhelp_plugin_get_current_tag(void)
-{
- gint pos;
- gchar *tag = NULL;
- GeanyDocument *doc = document_get_current();
-
- if (sci_has_selection(doc->editor->sci))
- return
- devhelp_plugin_clean_word(sci_get_selection_contents(doc->editor->sci));
-
- pos = sci_get_current_position(doc->editor->sci);
- tag = editor_get_word_at_pos(doc->editor, pos, GEANY_WORDCHARS);
-
- if (tag == NULL)
- return NULL;
-
- if (tag[0] == '\0') {
- g_free(tag);
- return NULL;
- }
-
- return devhelp_plugin_clean_word(tag);
-}
-
-
-/**
- * Activate the plugin's tabs in the UI.
- *
- * @param dhplug Devhelp plugin
- * @param search_tabs_shown If TRUE, show the sidebar search tab, otherwise
- * show the contents tab.
- */
-void devhelp_plugin_activate_ui(DevhelpPlugin *self, gboolean show_search_tab)
-{
- g_return_if_fail(self != NULL);
- devhelp_plugin_set_active(self, TRUE);
- gtk_notebook_set_current_page(GTK_NOTEBOOK(self->priv->sb_notebook), (show_search_tab) ? 1 : 0);
-}
-
-
-/**
- * Get whether or not the plugin's tabs are shown/active in the UI.
- *
- * @param dhplug Devhelp plugin
- */
-gboolean devhelp_plugin_get_active(DevhelpPlugin *dhplug)
-{
- return dhplug->priv->tabs_toggled;
-}
-
-
-/**
- * Set whether or not the plugin's tabs are shown/active in the UI.
- *
- * @param dhplug Devhelp plugin
- * @param active Whether to show the plugin's tabs or the previous tabs.
- */
-void devhelp_plugin_set_active(DevhelpPlugin *dhplug, gboolean active)
-{
- DevhelpPluginPrivate *p;
- GtkNotebook *main_nb, *sbar_nb;
-
- g_return_if_fail(dhplug != NULL);
-
- p = dhplug->priv;
- main_nb = GTK_NOTEBOOK(p->main_notebook);
- sbar_nb = GTK_NOTEBOOK(geany->main_widgets->sidebar_notebook);
-
- /* just return if the active state is already correct */
- if ((active && p->tabs_toggled) || (!active && !p->tabs_toggled))
- return;
-
- if (active)
- {
- p->last_main_tab_id = gtk_notebook_get_current_page(main_nb);
- p->last_sb_tab_id = gtk_notebook_get_current_page(sbar_nb);
- gtk_notebook_set_current_page(main_nb, p->webview_tab);
- gtk_notebook_set_current_page(sbar_nb, p->sb_notebook_tab);
- p->tabs_toggled = TRUE;
- }
- else
- {
- gtk_notebook_set_current_page(main_nb, p->last_main_tab_id);
- gtk_notebook_set_current_page(sbar_nb, p->last_sb_tab_id);
- p->tabs_toggled = FALSE;
- }
-}
-
-
-/**
- * Gets whether the Geany sidebar tabs are in the bottom or their original position.
- *
- * @param self Devhelp plugin.
- */
-gboolean devhelp_plugin_get_sidebar_tabs_bottom(DevhelpPlugin *self)
-{
- GtkNotebook *nb;
- g_return_val_if_fail(self != NULL, FALSE);
- nb = GTK_NOTEBOOK(geany->main_widgets->sidebar_notebook);
- return gtk_notebook_get_tab_pos(nb) == GTK_POS_BOTTOM;
-}
-
-
-/**
- * Sets whether the Geany sidebar tabs are at the bottom or in their original position.
- *
- * @param self Devhelp plugin.
- * @param bottom If TRUE, set the sidebar tab position to @c GTK_POS_BOTTOM
- * otherwise set back to original position.
- */
-void devhelp_plugin_set_sidebar_tabs_bottom(DevhelpPlugin *self, gboolean bottom)
-{
- GtkNotebook *nb;
- g_return_if_fail(self != NULL);
- nb = GTK_NOTEBOOK(geany->main_widgets->sidebar_notebook);
- gtk_notebook_set_tab_pos(nb, bottom ? GTK_POS_BOTTOM : self->priv->orig_sb_tab_pos);
-}
-
-
-/**
- * Gets the last URI loaded in the webview.
- *
- * @param self Devhelp plugin.
- *
- * @return The last URI loaded in the webview. This is an internal pointer,
- * do not modify or free.
- */
-const gchar *devhelp_plugin_get_last_uri(DevhelpPlugin *self)
-{
- g_return_val_if_fail(self != NULL, NULL);
- /* return webkit_web_view_get_uri(WEBKIT_WEB_VIEW(self->priv->webview)); */
- return (const gchar *)self->priv->last_uri;
-}
-
-
-/**
- * Gets whether the Documentation tab is in a main_notebook or in the
- * message window.
- *
- * @param self Devhelp plugin.
- *
- * @return TRUE if the Documentation tab is in a main_notebok or FALSE if it's
- * in the message window notebook.
- */
-gboolean devhelp_plugin_get_is_in_msgwin(DevhelpPlugin *self)
-{
- g_return_val_if_fail(self != NULL, FALSE);
- return self->priv->in_message_window;
-}
-
-
-/**
- * Sets whether the Documentation tab is in the message window notebook or is
- * in a main_notebook.
- *
- * @param self Devhelp plugin.
- * @param in_msgwin TRUE to move the Documentation tab to the message window
- * notebook or FALSE to create a main_notebook and put it there.
- */
-void devhelp_plugin_set_is_in_msgwin(DevhelpPlugin *self, gboolean in_msgwin)
-{
- GtkWidget *docs_notebook, *parent;
-
- g_return_if_fail(self != NULL);
-
- if (self->priv->in_message_window && !in_msgwin)
- {
- /* move from message win to main notebook */
- self->priv->main_notebook = main_notebook_get();
-
- //gtk_notebook_append_page(GTK_NOTEBOOK(self->priv->main_notebook),
- // self
- }
- else if (!self->priv->in_message_window && in_msgwin)
- {
- /* move from main notebook to message win */
- gtk_widget_reparent(
- gtk_notebook_get_nth_page(GTK_NOTEBOOK(self->priv->main_notebook), self->priv->webview_tab),
- geany->main_widgets->message_window_notebook);
-
- /* remove the main notebook and put the documents notebook back */
- parent = gtk_widget_get_parent(self->priv->main_notebook);
- docs_notebook = gtk_widget_ref(geany->main_widgets->notebook);
- gtk_container_remove(GTK_CONTAINER(parent), self->priv->main_notebook);
- main_notebook_destroy();
- gtk_container_add(GTK_CONTAINER(parent), docs_notebook);
- gtk_widget_unref(docs_notebook);
-
- self->priv->main_notebook = geany->main_widgets->message_window_notebook;
- }
-
- self->priv->in_message_window = in_msgwin;
-}
-
-
-/**
- * Gets the zoom level of the WebKit WebView.
- *
- * @param self Devhelp plugin.
- *
- * @return The zoom level.
- */
-gfloat devhelp_plugin_get_zoom_level(DevhelpPlugin *self)
-{
- g_return_val_if_fail(self != NULL, 0.0F);
- self->priv->zoom_level = webkit_web_view_get_zoom_level(WEBKIT_WEB_VIEW(self->priv->webview));
- return self->priv->zoom_level;
-}
-
-
-/**
- * Sets the zoom level of the WebKit WebView.
- *
- * @param self Devhelp plugin.
- * @param zoom_level The zoom level to set.
- */
-void devhelp_plugin_set_zoom_level(DevhelpPlugin *self, gfloat zoom_level)
-{
- g_return_if_fail(self != NULL);
- self->priv->zoom_level = zoom_level;
- webkit_web_view_set_zoom_level(WEBKIT_WEB_VIEW(self->priv->webview), zoom_level);
-}
-
-
-/**
- * Get the current URI from the WebKit WebView.
- *
- * @param self Devhelp plugin.
- *
- * @return The URI in the webview. This is an internal value, do not free or
- * modify it.
- */
-const gchar* devhelp_plugin_get_webview_uri(DevhelpPlugin *self)
-{
- g_return_val_if_fail(self != NULL, NULL);
-
- return webkit_web_view_get_uri(WEBKIT_WEB_VIEW(self->priv->webview));
-}
-
-
-/**
- * Loads the specified @a uri in the WebKit WebView.
- *
- * @param self Devhelp plugin.
- * @param uri The URI to load in the webview.
- */
-void devhelp_plugin_set_webview_uri(DevhelpPlugin *self, const gchar *uri)
-{
- g_return_if_fail(self != NULL);
- g_return_if_fail(uri != NULL);
-
- webkit_web_view_open(WEBKIT_WEB_VIEW(self->priv->webview), uri);
-}
-
-
-WebKitWebView* devhelp_plugin_get_webview(DevhelpPlugin *self)
-{
- g_return_val_if_fail(self != NULL, NULL);
- return WEBKIT_WEB_VIEW(self->priv->webview);
-}
-
-
-gboolean devhelp_plugin_get_have_man(DevhelpPlugin *self)
-{
- g_return_val_if_fail(self != NULL, FALSE);
- return self->priv->have_man;
-}
-
-
-/* Activates (brings to top/makes visible) the Devhelp plugin's sidebar tab. */
-static inline void devhelp_plugin_activate_sidebar_tab(DevhelpPlugin *self)
-{
- gint current_tab_id;
-
- g_return_if_fail(self != NULL);
-
- current_tab_id = gtk_notebook_get_current_page(GTK_NOTEBOOK(geany->main_widgets->sidebar_notebook));
- if (current_tab_id != self->priv->sb_notebook_tab)
- self->priv->last_sb_tab_id = current_tab_id;
-
- gtk_widget_set_visible(self->priv->sb_notebook, TRUE);
- gtk_notebook_set_current_page(GTK_NOTEBOOK(geany->main_widgets->sidebar_notebook),
- self->priv->sb_notebook_tab);
-}
-
-
-/**
- * Activates the Devhelp plugin's sidebar tab, and then the internal notebook's
- * Search tab.
- *
- * @param self Devhelp plugin.
- */
-void devhelp_plugin_activate_search_tab(DevhelpPlugin *self)
-{
- g_return_if_fail(self != NULL);
- devhelp_plugin_activate_sidebar_tab(self);
- gtk_notebook_set_current_page(GTK_NOTEBOOK(self->priv->sb_notebook), 1);
-}
-
-
-/**
- * Activates the Devhelp plugin's sidebar tab, and then the internal notebook's
- * Contents tab.
- *
- * @param self Devhelp plugin.
- */
-void devhelp_plugin_activate_contents_tab(DevhelpPlugin *self)
-{
- g_return_if_fail(self != NULL);
- devhelp_plugin_activate_sidebar_tab(self);
- gtk_notebook_set_current_page(GTK_NOTEBOOK(self->priv->sb_notebook), 0);
-}
-
-
-/**
- * Activates the Devhelp plugin's main notebook's Documentation tab.
- *
- * @param self Devhelp plugin.
- */
-void devhelp_plugin_activate_webview_tab(DevhelpPlugin *self)
-{
- gint current_tab_id;
-
- g_return_if_fail(self != NULL);
-
- current_tab_id = gtk_notebook_get_current_page(GTK_NOTEBOOK(self->priv->main_notebook));
- if (current_tab_id != self->priv->webview_tab)
- self->priv->last_main_tab_id = current_tab_id;
-
- gtk_notebook_set_current_page(GTK_NOTEBOOK(self->priv->main_notebook),
- self->priv->webview_tab);
-}
-
-
-/* Toggles the Devhelp tab in the Geany sidebar notebook. */
-static inline void devhelp_plugin_toggle_sidebar_tab(DevhelpPlugin *self, gint tab)
-{
- GtkNotebook *sbar_nb;
- gint current_tab_id;
-
- g_return_if_fail(self != NULL);
-
- sbar_nb = GTK_NOTEBOOK(geany->main_widgets->sidebar_notebook);
- current_tab_id = gtk_notebook_get_current_page(sbar_nb);
-
- if (current_tab_id == self->priv->sb_notebook_tab)
- gtk_notebook_set_current_page(sbar_nb, self->priv->last_sb_tab_id);
- else
- {
- if (tab == 0)
- devhelp_plugin_activate_contents_tab(self);
- else if (tab == 1)
- devhelp_plugin_activate_search_tab(self);
- else
- g_warning("Can't toggle to unknown tab ID: %d", tab);
- }
-}
-
-
-/**
- * Toggle's between the Devhelp plugin's search tab and the previous Geany
- * sidebar tab.
- *
- * @param self Devhelp plugin.
- */
-void devhelp_plugin_toggle_search_tab(DevhelpPlugin *self)
-{
- devhelp_plugin_toggle_sidebar_tab(self, 1);
-}
-
-
-/**
- * Toggle's between the Devhelp plugin's contents tab and the previous Geany
- * sidebar tab.
- *
- * @param self Devhelp plugin.
- */
-void devhelp_plugin_toggle_contents_tab(DevhelpPlugin *self)
-{
- devhelp_plugin_toggle_sidebar_tab(self, 0);
-}
-
-
-/**
- * Toggle's between the Devhelp plugin's main notebook tab and the previous
- * main notebook tab.
- *
- * @param self Devhelp plugin.
- */
-void devhelp_plugin_toggle_webview_tab(DevhelpPlugin *self)
-{
- gint current_tab_id;
-
- g_return_if_fail(self != NULL);
-
- current_tab_id = gtk_notebook_get_current_page(GTK_NOTEBOOK(self->priv->main_notebook));
- if (current_tab_id == self->priv->last_main_tab_id)
- {
- gtk_notebook_set_current_page(GTK_NOTEBOOK(self->priv->main_notebook),
- self->priv->last_main_tab_id);
- }
- else
- devhelp_plugin_activate_webview_tab(self);
-}
-
-
-/**
- * Activates/shows all the Devhelp plugins tabs.
- *
- * @param self Devhelp plugin.
- */
-void devhelp_plugin_activate_all_tabs(DevhelpPlugin *self)
-{
- devhelp_plugin_activate_sidebar_tab(self);
- devhelp_plugin_activate_webview_tab(self);
-}
-
-
-/* Called when the editor menu item is selected */
-static void on_search_help_activate(GtkMenuItem * menuitem, DevhelpPlugin *self)
-{
- gchar *current_tag;
-
- g_return_if_fail(self != NULL);
-
- if ((current_tag = devhelp_plugin_get_current_tag()) == NULL)
- return;
-
- devhelp_plugin_search_books(self, current_tag);
-
- g_free(current_tag);
-}
-
-
-/* Called when the editor menu item is selected */
-static void on_search_help_man_activate(GtkMenuItem * menuitem, DevhelpPlugin *self)
-{
- gchar *current_tag;
-
- g_return_if_fail(self != NULL);
-
- if ((current_tag = devhelp_plugin_get_current_tag()) == NULL)
- return;
-
- devhelp_plugin_search_manpages(self, current_tag);
-
- g_free(current_tag);
-}
-
-
-static void on_search_help_code_activate(GtkMenuItem *menuitem, DevhelpPlugin *self)
-{
- gchar *current_tag;
- const gchar *lang = NULL;
- GeanyDocument *doc;
-
- g_return_if_fail(self != NULL);
-
- if ((current_tag = devhelp_plugin_get_current_tag()) == NULL)
- return;
-
- doc = document_get_current();
- if (doc != NULL && doc->file_type != NULL && doc->file_type->name != NULL)
- lang = doc->file_type->name;
-
- devhelp_plugin_search_code(self, current_tag, lang);
-
- g_free(current_tag);
-}
-
-
-/*
- * Called when the editor context menu is shown so that the devhelp
- * search item can be disabled if there isn't a selected tag.
- */
-static void on_editor_menu_popup(GtkWidget * widget, DevhelpPlugin *self)
-{
- gchar *label_tag, *curword, *new_label;
-
- g_return_if_fail(self != NULL);
-
- curword = devhelp_plugin_get_current_tag();
-
- if (curword == NULL)
- {
- gtk_widget_set_sensitive(self->priv->editor_menu_item, FALSE);
- return;
- }
-
- label_tag = g_strstrip(g_strndup(curword, DHPLUG_MAX_LABEL_TAG));
- new_label = g_strdup_printf(_("Search for '%s' Documentation in"), label_tag);
-
- gtk_menu_item_set_label(GTK_MENU_ITEM(self->priv->editor_menu_item), new_label);
-
- g_free(new_label);
- g_free(label_tag);
-
- gtk_widget_set_sensitive(self->priv->editor_menu_item, TRUE);
-
- g_free(curword);
-}
-
-
-/*
- * Called when a link in either the contents or search areas on the sidebar
- * have a link clicked on, meaning to load that file into the webview.
- */
-static void on_link_clicked(GObject * ignored, DhLink * dhlink, DevhelpPlugin *self)
-{
- g_return_if_fail(self != NULL);
-
- if (self->priv->last_uri != NULL)
- g_free(self->priv->last_uri);
-
- self->priv->last_uri = dh_link_get_uri(dhlink);
- webkit_web_view_open(WEBKIT_WEB_VIEW(self->priv->webview), self->priv->last_uri);
- gtk_notebook_set_current_page(GTK_NOTEBOOK(self->priv->main_notebook), self->priv->webview_tab);
-}
-
-
-static void on_back_button_clicked(GtkToolButton * btn, DevhelpPlugin *self)
-{
- g_return_if_fail(self != NULL);
- webkit_web_view_go_back(WEBKIT_WEB_VIEW(self->priv->webview));
-}
-
-
-static void on_forward_button_clicked(GtkToolButton * btn, DevhelpPlugin *self)
-{
- g_return_if_fail(self != NULL);
- webkit_web_view_go_forward(WEBKIT_WEB_VIEW(self->priv->webview));
-}
-
-
-static void on_zoom_in_button_clicked(GtkToolButton * btn, DevhelpPlugin *self)
-{
- WebKitWebView *view;
-
- g_return_if_fail(self != NULL);
-
- view = WEBKIT_WEB_VIEW(self->priv->webview);
- webkit_web_view_zoom_in(view);
- self->priv->zoom_level = webkit_web_view_get_zoom_level(view);
-}
-
-
-static void on_zoom_out_button_clicked(GtkToolButton *btn, DevhelpPlugin *self)
-{
- WebKitWebView *view;
-
- g_return_if_fail(self != NULL);
-
- view = WEBKIT_WEB_VIEW(self->priv->webview);
- webkit_web_view_zoom_out(view);
- self->priv->zoom_level = webkit_web_view_get_zoom_level(view);
-}
-
-
-/* Controls the sensitivity of the back/forward buttons when webkit page changes. */
-static inline void update_history_buttons(DevhelpPlugin *self)
-{
- WebKitWebView *view;
-
- g_return_if_fail(self != NULL);
-
- view = WEBKIT_WEB_VIEW(self->priv->webview);
-
- gtk_widget_set_sensitive(GTK_WIDGET(self->priv->btn_back),
- webkit_web_view_can_go_back(view));
- gtk_widget_set_sensitive(GTK_WIDGET(self->priv->btn_forward),
- webkit_web_view_can_go_forward(view));
-}
-
-
-static void on_document_load_finished(WebKitWebView *view, WebKitWebFrame *frame, DevhelpPlugin *self)
-{
- update_history_buttons(self);
-}
-
-
-static void on_uri_changed_notify(GObject *object, GParamSpec *pspec, DevhelpPlugin *self)
-{
- update_history_buttons(self);
-}
-
-
-static void on_load_status_changed_notify(GObject *object, GParamSpec *pspec, DevhelpPlugin *self)
-{
- update_history_buttons(self);
-}
-
Deleted: trunk/geany-plugins/devhelp/src/devhelpplugin.h
===================================================================
--- trunk/geany-plugins/devhelp/src/devhelpplugin.h 2011-05-23 11:30:31 UTC (rev 2081)
+++ trunk/geany-plugins/devhelp/src/devhelpplugin.h 2011-05-24 09:04:06 UTC (rev 2082)
@@ -1,116 +0,0 @@
-/*
- * devhelpplugin.h
- *
- * Copyright 2011 Matthew Brush <mbrush at leftclick.ca>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#ifndef DEVHELP_PLUGIN_COMMON_H
-#define DEVHELP_PLUGIN_COMMON_H
-
-#include <gtk/gtk.h>
-#include <webkit/webkitwebview.h>
-
-G_BEGIN_DECLS
-
-
-#ifndef DHPLUG_DATA_DIR
-#define DHPLUG_DATA_DIR "/usr/local/share/geany-devhelp"
-#endif
-
-#define DHPLUG_WEBVIEW_HOME_FILE DHPLUG_DATA_DIR "/home.html"
-#define DHPLUG_MAX_LABEL_TAG 30 /* never search for more than this many chars */
-
-#define DEVHELP_TYPE_PLUGIN (devhelp_plugin_get_type())
-#define DEVHELP_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), DEVHELP_TYPE_PLUGIN, DevhelpPlugin))
-#define DEVHELP_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), DEVHELP_TYPE_PLUGIN, DevhelpPluginClass))
-#define DEVHELP_IS_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), DEVHELP_TYPE_PLUGIN))
-#define DEVHELP_IS_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), DEVHELP_TYPE_PLUGIN))
-#define DEVHELP_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), DEVHELP_TYPE_PLUGIN, DevhelpPluginClass))
-
-
-typedef struct _DevhelpPlugin DevhelpPlugin;
-typedef struct _DevhelpPluginClass DevhelpPluginClass;
-typedef struct _DevhelpPluginPrivate DevhelpPluginPrivate;
-
-
-struct _DevhelpPlugin
-{
- GObject parent;
- DevhelpPluginPrivate *priv;
-};
-
-
-struct _DevhelpPluginClass
-{
- GObjectClass parent_class;
-};
-
-
-GType devhelp_plugin_get_type (void);
-DevhelpPlugin* devhelp_plugin_new (void);
-
-gchar* devhelp_plugin_clean_word (gchar *str);
-gchar* devhelp_plugin_get_current_tag (void);
-
-const gchar* devhelp_plugin_get_webview_uri (DevhelpPlugin *self);
-void devhelp_plugin_set_webview_uri (DevhelpPlugin *self, const gchar *uri);
-
-gboolean devhelp_plugin_get_sidebar_tabs_bottom (DevhelpPlugin *self);
-void devhelp_plugin_set_sidebar_tabs_bottom (DevhelpPlugin *self, gboolean bottom);
-
-gboolean devhelp_plugin_get_active (DevhelpPlugin *self);
-void devhelp_plugin_set_active (DevhelpPlugin *self, gboolean active);
-
-gboolean devhelp_plugin_get_is_in_msgwin (DevhelpPlugin *self);
-void devhelp_plugin_set_is_in_msgwin (DevhelpPlugin *self, gboolean in_msgwin);
-
-void devhelp_plugin_activate_ui (DevhelpPlugin *self, gboolean show_search_tab);
-void devhelp_plugin_search (DevhelpPlugin *self, const gchar *term);
-void devhelp_plugin_search_books (DevhelpPlugin *self, const gchar *term);
-void devhelp_plugin_search_manpages (DevhelpPlugin *self, const gchar *term);
-void devhelp_plugin_search_code (DevhelpPlugin *self, const gchar *term, const gchar *lang);
-
-const gchar* devhelp_plugin_get_last_uri (DevhelpPlugin *self);
-void devhelp_plugin_set_last_uri (DevhelpPlugin *self, const gchar *uri);
-
-gfloat devhelp_plugin_get_zoom_level (DevhelpPlugin *self);
-void devhelp_plugin_set_zoom_level (DevhelpPlugin *self, gfloat zoom_level);
-
-void devhelp_plugin_activate_search_tab (DevhelpPlugin *self);
-void devhelp_plugin_activate_contents_tab (DevhelpPlugin *self);
-void devhelp_plugin_activate_webview_tab (DevhelpPlugin *self);
-void devhelp_plugin_activate_all_tabs (DevhelpPlugin *self);
-
-void devhelp_plugin_toggle_search_tab (DevhelpPlugin *self);
-void devhelp_plugin_toggle_contents_tab (DevhelpPlugin *self);
-void devhelp_plugin_toggle_webview_tab (DevhelpPlugin *self);
-
-WebKitWebView* devhelp_plugin_get_webview (DevhelpPlugin *self);
-
-gboolean devhelp_plugin_get_have_man (DevhelpPlugin *self);
-
-
-gchar *devhelp_plugin_manpages_search(const gchar *term, const gchar *section);
-void devhelp_plugin_remove_manpages_temp_files(void);
-
-
-void devhelp_plugin_search_code(DevhelpPlugin *self, const gchar *term, const gchar *lang);
-
-
-G_END_DECLS
-#endif /* DEVHELP_PLUGIN_H */
Copied: trunk/geany-plugins/devhelp/src/dhp-codesearch.c (from rev 2081, trunk/geany-plugins/devhelp/src/codesearch.c)
===================================================================
--- trunk/geany-plugins/devhelp/src/dhp-codesearch.c (rev 0)
+++ trunk/geany-plugins/devhelp/src/dhp-codesearch.c 2011-05-24 09:04:06 UTC (rev 2082)
@@ -0,0 +1,96 @@
+#include <glib.h>
+#include <webkit/webkitwebview.h>
+
+#include "dhp.h"
+
+
+struct LangMapEnt
+{
+ const gchar *geany_name;
+ const gchar *google_name;
+};
+
+
+#define GOOGLE_CODE_SEARCH_URI "http://www.google.com/codesearch"
+
+#define LANG_MAP_MAX 33 /* update this with lang_map[] size below */
+
+/* maps Geany language names to Google Code language names */
+static const struct LangMapEnt lang_map[LANG_MAP_MAX] = {
+ { "ActionScript", "actionscript" },
+ { "Ada", "ada" },
+ { "ASM", "assembly" },
+ { "FreeBasic", "basic" },
+ { "C", "c" },
+ { "C++", "c++" },
+ { "C#", "c#" },
+ { "COBOL", "cobol" },
+ { "CSS", "css" },
+ { "D", "d" },
+ { "Erlang", "erlang" },
+ { "Fortran", "fortran" },
+ { "Haskell", "haskell" },
+ { "Java", "java" },
+ { "Javascript", "javascript" },
+ { "Lisp", "lisp" },
+ { "Lua", "lua" },
+ { "Make", "makefile" },
+ { "Matlab/Octave", "matlab" },
+ { "CAML", "ocaml" },
+ { "Pascal", "pascal" },
+ { "Perl", "perl" },
+ { "PHP", "php" },
+ { "Python", "python" },
+ { "R", "r" },
+ { "Ruby", "ruby" },
+ { "Sh", "shell" },
+ { "SQL", "sql" },
+ { "Tcl", "tcl" },
+ { "LaTeX", "tex" },
+ { "Verilog", "verilog" },
+ { "VHDL", "vhdl" },
+ { "None", NULL }
+};
+
+
+void devhelp_plugin_search_code(DevhelpPlugin *self, const gchar *term, const gchar *lang)
+{
+ gint i;
+ gchar *uri, *term_enc, *lang_enc;
+ const gchar *google_lang = NULL;
+
+ g_return_if_fail(self != NULL);
+ g_return_if_fail(term != NULL);
+
+ if (lang != NULL)
+ {
+ for (i = 0; i < LANG_MAP_MAX; i++)
+ {
+ if (g_strcmp0(lang, lang_map[i].geany_name) == 0)
+ {
+ google_lang = lang_map[i].google_name;
+ break;
+ }
+ }
+ }
+
+ if (google_lang != NULL)
+ {
+ lang_enc = g_uri_escape_string(google_lang, NULL, TRUE);
+ term_enc = g_uri_escape_string(term, NULL, TRUE);
+ uri = g_strdup_printf("%s?as_q=%s&as_lang=%s", GOOGLE_CODE_SEARCH_URI, term_enc, lang_enc);
+ g_free(lang_enc);
+ g_free(term_enc);
+ }
+ else
+ {
+ term_enc = g_uri_escape_string(term, NULL, TRUE);
+ uri = g_strdup_printf("%s?as_q=%s", GOOGLE_CODE_SEARCH_URI, term_enc);
+ g_free(term_enc);
+ }
+
+ webkit_web_view_open(devhelp_plugin_get_webview(self), uri);
+ g_free(uri);
+
+ devhelp_plugin_activate_webview_tab(self);
+}
Added: trunk/geany-plugins/devhelp/src/dhp-manpages.c
===================================================================
--- trunk/geany-plugins/devhelp/src/dhp-manpages.c (rev 0)
+++ trunk/geany-plugins/devhelp/src/dhp-manpages.c 2011-05-24 09:04:06 UTC (rev 2082)
@@ -0,0 +1,234 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <glib.h>
+
+#include "dhp.h"
+
+
+#define DEVHELP_PLUGIN_MANPAGE_SECTIONS "3:2:1:8:5:4:7:6"
+#define DEVHELP_PLUGIN_MANPAGE_PAGER "col -b"
+
+#define DEVHELP_PLUGIN_MANPAGE_HTML_TEMPLATE \
+ "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd\">\n" \
+ "<html>\n" \
+ " <head>\n" \
+ " <title>%s</title>\n" \
+ " <style type=\"text/css\">\n" \
+ " .man_text {\n" \
+ " /*font-family: sans;*/\n" \
+ " }\n" \
+ " </style>\n" \
+ " </head>\n" \
+ " <body>\n" \
+ " <pre class=\"man_text\">%s</pre>\n" \
+ " </body>\n" \
+ "</html>\n"
+
+
+/* Locates the path to the manpage found for the term and section. */
+static gchar *devhelp_plugin_find_manpage_path(DevhelpPlugin *self, const gchar *term, const gchar *section)
+{
+ gint retcode=0;
+ gchar *cmd, *path=NULL;
+ const gchar *man_path;
+
+ g_return_val_if_fail(self != NULL, NULL);
+ g_return_val_if_fail(term != NULL, NULL);
+
+ if ((man_path = devhelp_plugin_get_man_prog_path(self)) == NULL)
+ man_path = "man";
+
+ if (section == NULL)
+ {
+ cmd = g_strdup_printf("%s -S %s --where '%s'", man_path,
+ DEVHELP_PLUGIN_MANPAGE_SECTIONS, term);
+ }
+ else
+ cmd = g_strdup_printf("%s --where %s '%s'", man_path, section, term);
+
+ if (!g_spawn_command_line_sync(cmd, &path, NULL, &retcode, NULL))
+ {
+ g_free(cmd);
+ return NULL;
+ }
+
+ g_free(cmd);
+
+ if (retcode != 0)
+ {
+ g_free(path);
+ return NULL;
+ }
+
+ return g_strstrip(path);
+}
+
+
+/* Read the text output from man or NULL. */
+static gchar *devhelp_plugin_read_man_text(DevhelpPlugin *self, const gchar *filename)
+{
+ gint retcode=0;
+ gchar *cmd, *text=NULL;
+ const gchar *man_path;
+
+ g_return_val_if_fail(self != NULL, NULL);
+ g_return_val_if_fail(filename != NULL, NULL);
+
+ if ((man_path = devhelp_plugin_get_man_prog_path(self)) == NULL)
+ man_path = "man";
+
+ cmd = g_strdup_printf("%s -P\"%s\" \'%s\'", man_path,
+ DEVHELP_PLUGIN_MANPAGE_PAGER, filename);
+
+ if (!g_spawn_command_line_sync(cmd, &text, NULL, &retcode, NULL))
+ {
+ g_free(cmd);
+ return NULL;
+ }
+
+ g_free(cmd);
+
+ if (retcode != 0)
+ {
+ g_free(text);
+ return NULL;
+ }
+
+ return text;
+}
+
+
+/**
+ * Searches for a manual page, and if it finds one, writes its text into a
+ * <pre> section in an HTML file, and returns the URI of the HTML file which
+ * can be loaded into the webview.
+ *
+ * @param self Devhelp plugin.
+ * @param term The search term to look for.
+ * @param section The manual page section to look in or NULL.
+ *
+ * @return The URI to a temporary HTML file containing the man page text or
+ * NULL on error.
+ */
+gchar *devhelp_plugin_manpages_search(DevhelpPlugin *self, const gchar *term, const gchar *section)
+{
+ FILE *fp = NULL;
+ gint fd = -1, len;
+ gchar *man_fn = NULL, *tmp_fn = NULL, *uri = NULL;
+ gchar *text = NULL, *html_text = NULL;
+ const gchar *tmpl = "devhelp_manpage_XXXXXX.html";
+
+ g_return_val_if_fail(self != NULL, NULL);
+ g_return_val_if_fail(term != NULL, NULL);
+
+ if ((man_fn = devhelp_plugin_find_manpage_path(self, term, section)) == NULL)
+ goto error;
+
+ if ((fd = g_file_open_tmp(tmpl, &tmp_fn, NULL)) == -1)
+ goto error;
+
+ if ((fp = fdopen(fd, "w")) == NULL)
+ goto error;
+
+ if ((text = devhelp_plugin_read_man_text(self, man_fn)) == NULL)
+ goto error;
+
+ html_text = g_strdup_printf(DEVHELP_PLUGIN_MANPAGE_HTML_TEMPLATE, term, text);
+
+ len = strlen(html_text);
+ if (fwrite(html_text, sizeof(gchar), len, fp) != len)
+ goto error;
+
+ devhelp_plugin_add_temp_file(self, tmp_fn);
+
+ uri = g_filename_to_uri(tmp_fn, NULL, NULL);
+
+ g_free(man_fn);
+ g_free(tmp_fn);
+ g_free(text);
+ g_free(html_text);
+
+ fclose(fp);
+
+ return uri;
+
+error:
+ g_free(man_fn);
+ g_free(tmp_fn);
+ g_free(text);
+ g_free(html_text);
+ g_free(uri);
+ if (fp != NULL)
+ fclose(fp);
+ return NULL;
+}
+
+
+/**
+ * Removes temporary files made by the plugin and frees the stored filenames
+ * and the list used to hold them.
+ *
+ * @param self Devhelp plugin.
+ */
+void devhelp_plugin_remove_manpages_temp_files(DevhelpPlugin *self)
+{
+ GList *temp_files, *iter;
+
+ g_return_if_fail(self != NULL);
+
+ temp_files = devhelp_plugin_get_temp_files(self);
+
+ if (temp_files == NULL)
+ return;
+
+ for (iter = temp_files; iter != NULL; iter = iter->next)
+ {
+ if (remove(iter->data) == -1)
+ g_warning("Unable to delete temp file: %s", strerror(errno));
+ g_free(iter->data);
+ }
+
+ g_list_free(temp_files);
+}
+
+
+/**
+ * Adds a filename to the list of temp files to be deleted later.
+ *
+ * @param self Devhelp plugin.
+ * @param filename The filename to track for future removal.
+ */
+void devhelp_plugin_add_temp_file(DevhelpPlugin *self, const gchar *filename)
+{
+ GList *temp_files;
+
+ g_return_if_fail(self != NULL);
+
+ temp_files = devhelp_plugin_get_temp_files(self);
+ temp_files = g_list_append(temp_files, g_strdup(filename));
+}
+
+/**
+ * Search for a term in Manual Pages and activate/show the plugin's UI stuff.
+ *
+ * @param dhplug Devhelp plugin
+ * @param term The string to search for
+ */
+void devhelp_plugin_search_manpages(DevhelpPlugin *self, const gchar *term)
+{
+ gchar *man_fn;
+
+ g_return_if_fail(self != NULL);
+ g_return_if_fail(term != NULL);
+
+ if ((man_fn = devhelp_plugin_manpages_search(self, term, NULL)) == NULL)
+ return;
+
+ devhelp_plugin_set_webview_uri(self, man_fn);
+
+ g_free(man_fn);
+
+ devhelp_plugin_activate_webview_tab(self);
+}
Copied: trunk/geany-plugins/devhelp/src/dhp-object.c (from rev 2081, trunk/geany-plugins/devhelp/src/devhelpplugin.c)
===================================================================
--- trunk/geany-plugins/devhelp/src/dhp-object.c (rev 0)
+++ trunk/geany-plugins/devhelp/src/dhp-object.c 2011-05-24 09:04:06 UTC (rev 2082)
@@ -0,0 +1,1401 @@
+/*
+ * devhelpplugin.c
+ *
+ * Copyright 2011 Matthew Brush <mbrush at leftclick.ca>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <stdlib.h>
+#include <gtk/gtk.h>
+#include <geanyplugin.h>
+
+#include <devhelp/dh-base.h>
+#include <devhelp/dh-book-tree.h>
+#include <devhelp/dh-search.h>
+#include <devhelp/dh-link.h>
+
+#ifdef HAVE_BOOK_MANAGER /* for newer api */
+#include <devhelp/dh-book-manager.h>
+#endif
+
+#include <webkit/webkitwebview.h>
+
+#include "dhp.h"
+#include "dhp-plugin.h"
+
+
+struct _DevhelpPluginPrivate
+{
+ /* Devhelp stuff */
+ DhBase* dhbase;
+ GtkWidget* book_tree; /* "Contents" in the sidebar */
+ GtkWidget* search; /* "Search" in the sidebar */
+ GtkWidget* sb_notebook; /* Notebook that holds contents/search */
+
+ /* Webview stuff */
+ GtkWidget* webview; /* Webkit that shows documentation */
+ GtkWidget* webview_tab; /* The widget that has webview related stuff */
+ GtkToolItem* btn_back; /* the webkit browser back button in the toolbar */
+ GtkToolItem* btn_forward; /* the webkit browser forward button in the toolbar */
+ DevhelpPluginWebViewLocation location; /* where to pack the webview */
+
+ /* Other widgets */
+ GtkWidget* main_notebook; /* Notebook that holds Geany doc notebook and and webkit view */
+ GtkWidget* editor_menu_item; /* Item in the editor's context menu */
+ GtkWidget* editor_menu_sep; /* Separator item above menu item */
+
+ /* Position/tab number tracking */
+ gboolean last_main_tab_id; /* These track the last id of the tabs */
+ gboolean last_sb_tab_id; /* before toggling */
+ gboolean tabs_toggled; /* Tracks state of whether to toggle to Devhelp or back to code */
+ GtkPositionType orig_sb_tab_pos; /* The tab idx of the initial sidebar tab */
+ gboolean in_message_window; /* whether the webkit stuff is in the msgwin */
+
+ GList* temp_files; /* Tracks temp files made by the plugin to delete later. */
+
+ GKeyFile* kf;
+ gboolean focus_webview_on_search;
+ gboolean focus_sidebar_on_search;
+ gchar* custom_homepage;
+ gboolean use_devhelp;
+ gboolean use_man;
+ gboolean use_codesearch;
+
+ gchar* man_prog_path;
+ gchar* man_pager_prog;
+ gchar* man_section_order;
+
+ gchar* codesearch_base_uri;
+ gchar* codesearch_params;
+ gboolean codesearch_use_lang;
+
+ GtkPositionType main_nb_tab_pos;
+};
+
+
+G_DEFINE_TYPE(DevhelpPlugin, devhelp_plugin, G_TYPE_OBJECT)
+
+
+enum
+{
+ PROP_0,
+ PROP_CURRENT_WORD,
+ PROP_WEBVIEW_URI,
+ PROP_SIDEBAR_TABS_BOTTOM,
+ PROP_UI_ACTIVE,
+ PROP_IN_MESSAGE_WINDOW,
+ PROP_ZOOM_LEVEL,
+ PROP_WEBVIEW,
+ PROP_TEMP_FILES,
+ PROP_MAN_PROG_PATH,
+ PROP_HAVE_MAN_PROG,
+ PROP_LAST
+};
+
+
+/* Causes problems if it gets re-initialized so leave global for now */
+static DhBase *dhbase = NULL;
+
+
+/* Internal callbacks */
+static void on_search_help_activate(GtkMenuItem * menuitem, DevhelpPlugin *self);
+static void on_search_help_man_activate(GtkMenuItem * menuitem, DevhelpPlugin *self);
+static void on_search_help_code_activate(GtkMenuItem *menuitem, DevhelpPlugin *self);
+static void on_editor_menu_popup(GtkWidget * widget, DevhelpPlugin *self);
+static void on_link_clicked(GObject * ignored, DhLink * dhlink, DevhelpPlugin *self);
+static void on_back_button_clicked(GtkToolButton * btn, DevhelpPlugin *self);
+static void on_forward_button_clicked(GtkToolButton * btn, DevhelpPlugin *self);
+static void on_zoom_in_button_clicked(GtkToolButton * btn, DevhelpPlugin *self);
+static void on_zoom_out_button_clicked(GtkToolButton *btn, DevhelpPlugin *self);
+static void on_document_load_finished(WebKitWebView *view, WebKitWebFrame *frame, DevhelpPlugin *self);
+static void on_uri_changed_notify(GObject *object, GParamSpec *pspec, DevhelpPlugin *self);
+static void on_load_status_changed_notify(GObject *object, GParamSpec *pspec, DevhelpPlugin *self);
+
+/* Misc internal functions */
+static inline void update_history_buttons(DevhelpPlugin *self);
+static inline gchar* clean_word(gchar *str);
+static GtkWidget* devhelp_plugin_ref_unpack_webview_tab(DevhelpPlugin *self);
+static void devhelp_plugin_set_webview_location(DevhelpPlugin *self, DevhelpPluginWebViewLocation location);
+
+
+/* include long boring code from dhp-settings.c */
+#include "dhp-settings.c"
+
+
+static void devhelp_plugin_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+ DevhelpPlugin *self = DEVHELP_PLUGIN(object);
+
+ switch(property_id)
+ {
+ case PROP_WEBVIEW_URI:
+ devhelp_plugin_set_webview_uri(self, g_value_get_string(value));
+ break;
+ case PROP_SIDEBAR_TABS_BOTTOM:
+ devhelp_plugin_set_sidebar_tabs_bottom(self, g_value_get_boolean(value));
+ break;
+ case PROP_UI_ACTIVE:
+ devhelp_plugin_set_ui_active(self, g_value_get_boolean(value));
+ break;
+ case PROP_IN_MESSAGE_WINDOW:
+ devhelp_plugin_set_in_message_window(self, g_value_get_boolean(value));
+ break;
+ case PROP_ZOOM_LEVEL:
+ devhelp_plugin_set_zoom_level(self, g_value_get_float(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
+}
+
+
+static void devhelp_plugin_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+ DevhelpPlugin *self = DEVHELP_PLUGIN(object);
+
+ switch(property_id)
+ {
+ case PROP_CURRENT_WORD:
+ g_value_set_string(value, devhelp_plugin_get_current_word(self));
+ break;
+ case PROP_WEBVIEW_URI:
+ g_value_set_string(value, devhelp_plugin_get_webview_uri(self));
+ break;
+ case PROP_SIDEBAR_TABS_BOTTOM:
+ g_value_set_boolean(value, devhelp_plugin_get_sidebar_tabs_bottom(self));
+ break;
+ case PROP_UI_ACTIVE:
+ g_value_set_boolean(value, devhelp_plugin_get_ui_active(self));
+ break;
+ case PROP_IN_MESSAGE_WINDOW:
+ g_value_set_boolean(value, devhelp_plugin_get_in_message_window(self));
+ break;
+ case PROP_ZOOM_LEVEL:
+ g_value_set_float(value, devhelp_plugin_get_zoom_level(self));
+ break;
+ case PROP_WEBVIEW:
+ g_value_set_object(value, devhelp_plugin_get_webview(self));
+ break;
+ case PROP_TEMP_FILES:
+ g_value_set_pointer(value, devhelp_plugin_get_temp_files(self));
+ break;
+ case PROP_MAN_PROG_PATH:
+ g_value_set_string(value, devhelp_plugin_get_man_prog_path(self));
+ break;
+ case PROP_HAVE_MAN_PROG:
+ g_value_set_boolean(value, devhelp_plugin_get_have_man_prog(self));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
+}
+
+
+/* Put cleanup code in here */
+static void devhelp_plugin_finalize(GObject * object)
+{
+ DevhelpPlugin *self;
+
+ g_return_if_fail(object != NULL);
+ g_return_if_fail(DEVHELP_IS_PLUGIN(object));
+
+ self = DEVHELP_PLUGIN(object);
+
+ devhelp_plugin_set_sidebar_tabs_bottom(self, FALSE);
+ devhelp_plugin_remove_manpages_temp_files(self);
+
+ gtk_widget_destroy(self->priv->sb_notebook);
+
+ gtk_widget_unref(devhelp_plugin_ref_unpack_webview_tab(self));
+
+ gtk_widget_destroy(self->priv->editor_menu_sep);
+ gtk_widget_destroy(self->priv->editor_menu_item);
+
+ g_free(self->priv->man_prog_path);
+ g_free(self->priv->man_pager_prog);
+ g_free(self->priv->man_section_order);
+ g_free(self->priv->codesearch_base_uri);
+ g_free(self->priv->codesearch_params);
+ g_free(self->priv->custom_homepage);
+
+ G_OBJECT_CLASS(devhelp_plugin_parent_class)->finalize(object);
+}
+
+
+static void devhelp_plugin_class_init(DevhelpPluginClass * klass)
+{
+ GObjectClass *g_object_class;
+ GParamSpec *pspec;
+
+ g_object_class = G_OBJECT_CLASS(klass);
+
+ g_object_class->set_property = devhelp_plugin_set_property;
+ g_object_class->get_property = devhelp_plugin_get_property;
+ g_object_class->finalize = devhelp_plugin_finalize;
+
+ pspec = g_param_spec_string(
+ "current-word",
+ "Current word in editor",
+ "Gets the currently selected word, or the word where the cursor is.",
+ NULL,
+ G_PARAM_READABLE);
+ g_object_class_install_property(g_object_class, PROP_CURRENT_WORD, pspec);
+
+ pspec = g_param_spec_string(
+ "webview-uri",
+ "WebKit WebView URI",
+ "Gets or sets the URI loaded in the WebView widget.",
+ DHPLUG_WEBVIEW_HOME_FILE,
+ G_PARAM_READWRITE);
+ g_object_class_install_property(g_object_class, PROP_WEBVIEW_URI, pspec);
+
+ pspec = g_param_spec_boolean(
+ "sidebar-tabs-bottom",
+ "Sidebar tabs on bottom",
+ "Gets or sets whether Geany's sidebar tabs are positioned on the bottom or not.",
+ FALSE,
+ G_PARAM_READWRITE);
+ g_object_class_install_property(g_object_class, PROP_SIDEBAR_TABS_BOTTOM, pspec);
+
+ pspec = g_param_spec_boolean(
+ "ui-active",
+ "UI widgets are active",
+ "Gets or sets whether the plugin's UI widgets are active/selected/visible.",
+ FALSE,
+ G_PARAM_READWRITE);
+ g_object_class_install_property(g_object_class, PROP_UI_ACTIVE, pspec);
+
+ pspec = g_param_spec_boolean(
+ "in-message-window",
+ "Documentation in the message window notebook",
+ "Gets or sets whether the notebook page with the WebKit WebView is located "
+ "in the main documents notebook area or in the message window notebook.",
+ FALSE,
+ G_PARAM_READWRITE);
+ g_object_class_install_property(g_object_class, PROP_IN_MESSAGE_WINDOW, pspec);
+
+ pspec = g_param_spec_float(
+ "zoom-level",
+ "Zoom level of the WebKit WebView",
+ "Gets or sets the zoom level (font size, etc) of the contents of the "
+ "WebKit WebView.",
+ G_MINFLOAT, G_MAXFLOAT/* FIXME */, 1.0F,
+ G_PARAM_READWRITE);
+ g_object_class_install_property(g_object_class, PROP_ZOOM_LEVEL, pspec);
+
+ pspec = g_param_spec_object(
+ "webview",
+ "WebKit WebView",
+ "Gets the WebKit WebView used to display documentation.",
+ WEBKIT_TYPE_WEB_VIEW,
+ G_PARAM_READABLE);
+ g_object_class_install_property(g_object_class, PROP_WEBVIEW, pspec);
+
+ pspec = g_param_spec_pointer(
+ "temp-files",
+ "Temporary files",
+ "Gets the GList used to track temporary files so they can be deleted later.",
+ G_PARAM_READABLE);
+ g_object_class_install_property(g_object_class, PROP_TEMP_FILES, pspec);
+
+ pspec = g_param_spec_string(
+ "man-prog-path",
+ "Manual page program path",
+ "Gets the path to the system's 'man' program if present.",
+ NULL,
+ G_PARAM_READABLE);
+ g_object_class_install_property(g_object_class, PROP_MAN_PROG_PATH, pspec);
+
+ pspec = g_param_spec_boolean(
+ "have-man-prog",
+ "Have manual page program",
+ "Gets whether a manual page program was found on the system.",
+ FALSE,
+ G_PARAM_READABLE);
+ g_object_class_install_property(g_object_class, PROP_HAVE_MAN_PROG, pspec);
+
+ g_type_class_add_private((gpointer) klass, sizeof(DevhelpPluginPrivate));
+}
+
+
+/*
+ * Initialize the Devhelp library/widgets.
+ * The Devhelp API isn't exactly stable, so handle quirks in here.
+ */
+static void devhelp_plugin_init_dh(DevhelpPlugin *self)
+{
+#ifdef HAVE_BOOK_MANAGER /* for newer api */
+ DhBookManager *book_manager;
+#else
+ GNode *books;
+ GList *keywords;
+#endif
+
+ if (dhbase == NULL)
+ dhbase = dh_base_new();
+ self->priv->dhbase = dhbase;
+
+#ifdef HAVE_BOOK_MANAGER /* for newer api */
+ book_manager = dh_base_get_book_manager(self->priv->dhbase);
+ self->priv->book_tree = dh_book_tree_new(book_manager);
+ self->priv->search = dh_search_new(book_manager);
+#else
+ books = dh_base_get_book_tree(self->priv->dhbase);
+ keywords = dh_base_get_keywords(self->priv->dhbase);
+ self->priv->book_tree = dh_book_tree_new(books);
+ self->priv->search = dh_search_new(keywords);
+#endif
+
+ gtk_widget_show(self->priv->search);
+
+ g_signal_connect(self->priv->book_tree, "link-selected", G_CALLBACK(on_link_clicked), self);
+ g_signal_connect(self->priv->search, "link-selected", G_CALLBACK(on_link_clicked), self);
+}
+
+
+/* Initialize the stuff in the editor's context menu */
+static void devhelp_plugin_init_edit_menu(DevhelpPlugin *self)
+{
+ GtkWidget *doc_menu, *devhelp_item, *code_item, *man_item;
+ DevhelpPluginPrivate *p;
+
+ g_return_if_fail(self != NULL);
+
+ p = self->priv;
+
+ p->editor_menu_sep = gtk_separator_menu_item_new();
+ p->editor_menu_item = gtk_menu_item_new_with_label(_("Search for 'Tag' Documentation in"));
+ doc_menu = gtk_menu_new();
+
+ devhelp_item = gtk_menu_item_new_with_label(_("Devhelp"));
+ gtk_menu_shell_append(GTK_MENU_SHELL(doc_menu), devhelp_item);
+ g_signal_connect(devhelp_item, "activate", G_CALLBACK(on_search_help_activate), self);
+ gtk_widget_show(devhelp_item);
+
+ if (devhelp_plugin_get_have_man_prog(self))
+ {
+ man_item = gtk_menu_item_new_with_label(_("Manual Pages"));
+ gtk_menu_shell_append(GTK_MENU_SHELL(doc_menu), man_item);
+ g_signal_connect(man_item, "activate", G_CALLBACK(on_search_help_man_activate), self);
+ gtk_widget_show(man_item);
+ }
+
+ code_item = gtk_menu_item_new_with_label(_("Google Code"));
+ gtk_menu_shell_append(GTK_MENU_SHELL(doc_menu), code_item);
+ g_signal_connect(code_item, "activate", G_CALLBACK(on_search_help_code_activate), self);
+ gtk_widget_show(code_item);
+
+ g_signal_connect(geany->main_widgets->editor_menu, "show", G_CALLBACK(on_editor_menu_popup), self);
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(p->editor_menu_item), doc_menu);
+ gtk_menu_shell_append(GTK_MENU_SHELL(geany->main_widgets->editor_menu), p->editor_menu_sep);
+ gtk_menu_shell_append(GTK_MENU_SHELL(geany->main_widgets->editor_menu), p->editor_menu_item);
+ gtk_widget_show(p->editor_menu_sep);
+ gtk_widget_show_all(p->editor_menu_item);
+}
+
+
+/* Initialize the WebKit browser and associated widgets */
+static void devhelp_plugin_init_webkit(DevhelpPlugin *self)
+{
+ GtkWidget *vbox, *toolbar;
+ GtkToolItem *btn_zoom_in, *btn_zoom_out, *tb_sep;
+ GtkScrolledWindow *webview_sw;
+ DevhelpPluginPrivate *p;
+
+ g_return_if_fail(self != NULL);
+
+ p = self->priv;
+
+ p->webview = webkit_web_view_new();
+
+ webview_sw = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(NULL, NULL));
+ gtk_scrolled_window_set_policy(webview_sw, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type(webview_sw, GTK_SHADOW_ETCHED_IN);
+ gtk_container_add(GTK_CONTAINER(webview_sw), p->webview);
+
+ gtk_widget_show_all(GTK_WIDGET(webview_sw));
+
+ vbox = gtk_vbox_new(FALSE, 0);
+ toolbar = gtk_toolbar_new();
+
+ p->btn_back = gtk_tool_button_new_from_stock(GTK_STOCK_GO_BACK);
+ p->btn_forward = gtk_tool_button_new_from_stock(GTK_STOCK_GO_FORWARD);
+ btn_zoom_in = gtk_tool_button_new_from_stock(GTK_STOCK_ZOOM_IN);
+ btn_zoom_out = gtk_tool_button_new_from_stock(GTK_STOCK_ZOOM_OUT);
+ tb_sep = gtk_separator_tool_item_new();
+
+ gtk_widget_set_tooltip_text(GTK_WIDGET(p->btn_back), _("Go back one page"));
+ gtk_widget_set_tooltip_text(GTK_WIDGET(p->btn_forward), _("Go forward one page"));
+ gtk_widget_set_tooltip_text(GTK_WIDGET(btn_zoom_in), _("Zoom in"));
+ gtk_widget_set_tooltip_text(GTK_WIDGET(btn_zoom_out), _("Zoom out"));
+
+ gtk_toolbar_insert(GTK_TOOLBAR(toolbar), p->btn_back, -1);
+ gtk_toolbar_insert(GTK_TOOLBAR(toolbar), p->btn_forward, -1);
+ gtk_toolbar_insert(GTK_TOOLBAR(toolbar), tb_sep, -1);
+ gtk_toolbar_insert(GTK_TOOLBAR(toolbar), btn_zoom_in, -1);
+ gtk_toolbar_insert(GTK_TOOLBAR(toolbar), btn_zoom_out, -1);
+
+ gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(webview_sw), TRUE, TRUE, 0);
+
+ gtk_widget_show_all(vbox);
+ p->webview_tab = vbox;
+ devhelp_plugin_set_webview_location(self, DEVHELP_PLUGIN_WEBVIEW_LOCATION_MAIN_NOTEBOOK);
+
+ g_signal_connect(p->btn_back, "clicked", G_CALLBACK(on_back_button_clicked), self);
+ g_signal_connect(p->btn_forward, "clicked", G_CALLBACK(on_forward_button_clicked), self);
+ g_signal_connect(btn_zoom_in, "clicked", G_CALLBACK(on_zoom_in_button_clicked), self);
+ g_signal_connect(btn_zoom_out, "clicked", G_CALLBACK(on_zoom_out_button_clicked), self);
+
+ g_signal_connect(WEBKIT_WEB_VIEW(p->webview), "document-load-finished", G_CALLBACK(on_document_load_finished), self);
+ g_signal_connect(WEBKIT_WEB_VIEW(p->webview), "notify::uri", G_CALLBACK(on_uri_changed_notify), self);
+ g_signal_connect(WEBKIT_WEB_VIEW(p->webview), "notify::load-status", G_CALLBACK(on_load_status_changed_notify), self);
+
+ devhelp_plugin_set_webview_uri(self, NULL);
+}
+
+
+/* Initialize the stuff added to the sidebar. */
+static void devhelp_plugin_init_sidebar(DevhelpPlugin *self)
+{
+ GtkWidget *label;
+ GtkWidget *book_tree_sw;
+ DevhelpPluginPrivate *p;
+
+ g_return_if_fail(self != NULL);
+
+ p = self->priv;
+
+ p->sb_notebook = gtk_notebook_new();
+ p->orig_sb_tab_pos = gtk_notebook_get_tab_pos(GTK_NOTEBOOK(geany->main_widgets->sidebar_notebook));
+
+ book_tree_sw = gtk_scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(book_tree_sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+ gtk_container_set_border_width(GTK_CONTAINER(book_tree_sw), 6);
+ gtk_container_add(GTK_CONTAINER(book_tree_sw), p->book_tree);
+ gtk_widget_show(p->book_tree);
+
+ label = gtk_label_new(_("Contents"));
+ gtk_notebook_append_page(GTK_NOTEBOOK(p->sb_notebook), book_tree_sw, label);
+
+ label = gtk_label_new(_("Search"));
+ gtk_notebook_append_page(GTK_NOTEBOOK(p->sb_notebook), p->search, label);
+
+ gtk_notebook_set_current_page(GTK_NOTEBOOK(p->sb_notebook), 0);
+ gtk_widget_show_all(p->sb_notebook);
+
+ label = gtk_label_new(_("Devhelp"));
+ gtk_notebook_append_page(GTK_NOTEBOOK(geany->main_widgets->sidebar_notebook), p->sb_notebook, label);
+}
+
+
+/* Called when a new plugin is being initialized */
+static void devhelp_plugin_init(DevhelpPlugin * self)
+{
+ DevhelpPluginPrivate *p;
+
+ g_return_if_fail(self != NULL);
+
+ self->priv = p = G_TYPE_INSTANCE_GET_PRIVATE(self, DEVHELP_TYPE_PLUGIN, DevhelpPluginPrivate);
+ devhelp_plugin_init_dh(self);
+
+ p->in_message_window = FALSE;
+ p->tabs_toggled = FALSE;
+ p->location = DEVHELP_PLUGIN_WEBVIEW_LOCATION_NONE;
+ p->main_notebook = NULL;
+
+ p->kf = NULL;
+ p->focus_webview_on_search = TRUE;
+ p->focus_sidebar_on_search = TRUE;
+ p->custom_homepage = NULL;
+ p->use_devhelp = TRUE;
+ p->use_man = TRUE;
+ p->use_codesearch = TRUE;
+
+ p->man_prog_path = g_find_program_in_path("man");
+ p->man_pager_prog = g_strdup("col -b");
+ p->man_section_order = g_strdup("3:2:1:8:5:4:7:6");
+
+ p->codesearch_base_uri = g_strdup("http://www.google.com/codesearch");
+ p->codesearch_params = NULL;
+ p->codesearch_use_lang = TRUE;
+
+ p->main_nb_tab_pos = GTK_POS_BOTTOM;
+
+ devhelp_plugin_init_edit_menu(self);
+ devhelp_plugin_init_sidebar(self);
+ devhelp_plugin_init_webkit(self);
+
+ p->last_main_tab_id = gtk_notebook_get_current_page(GTK_NOTEBOOK(p->main_notebook));
+ p->last_sb_tab_id = gtk_notebook_get_current_page(GTK_NOTEBOOK(geany->main_widgets->sidebar_notebook));
+}
+
+
+/** Create a new Devhelp plugin instance. */
+DevhelpPlugin *devhelp_plugin_new(void)
+{
+ return g_object_new(DEVHELP_TYPE_PLUGIN, NULL);
+}
+
+
+/**
+ * Gets the WebKit WebView object used by the plugin.
+ *
+ * @param self Devhelp plugin.
+ *
+ * @return The webview used by the plugin.
+ */
+const gchar *devhelp_plugin_get_webview_uri(DevhelpPlugin *self)
+{
+ g_return_val_if_fail(DEVHELP_IS_PLUGIN(self), NULL);
+ return webkit_web_view_get_uri(WEBKIT_WEB_VIEW(self->priv->webview));
+}
+
+
+/**
+ * Loads the specified @a uri in the WebKit WebView.
+ *
+ * @param self Devhelp plugin.
+ * @param uri The URI to load in the webview or NULL for default homepage.
+ */
+void devhelp_plugin_set_webview_uri(DevhelpPlugin *self, const gchar *uri)
+{
+ /* stolen from Webhelper plugin */
+ gchar *real_uri;
+ gchar *scheme;
+
+ g_return_if_fail(DEVHELP_IS_PLUGIN(self));
+
+ if (uri == NULL)
+ real_uri = g_filename_to_uri(DHPLUG_WEBVIEW_HOME_FILE, NULL, NULL);
+ else
+ real_uri = g_strdup(uri);
+
+ scheme = g_uri_parse_scheme(real_uri);
+ if (!scheme)
+ {
+ gchar *tmp = g_strconcat("http://", uri, NULL);
+ g_free(real_uri);
+ real_uri = tmp;
+ }
+ g_free(scheme);
+
+ if (g_strcmp0(real_uri, devhelp_plugin_get_webview_uri(self)) != 0)
+ {
+ webkit_web_view_open(WEBKIT_WEB_VIEW(self->priv->webview), real_uri);
+ g_object_notify(G_OBJECT(self), "webview-uri");
+ }
+ g_free(real_uri);
+}
+
+
+/**
+ * Same as devhelp_plugin_search_books().
+ *
+ * @param self Devhelp plugin.
+ * @param term The search term to look up.
+ */
+void devhelp_plugin_search(DevhelpPlugin *self, const gchar *term)
+{
+ devhelp_plugin_search_books(self, term);
+}
+
+
+/**
+ * Search for a term in Devhelp and activate/show the plugin's UI stuff.
+ *
+ * @param dhplug Devhelp plugin
+ * @param term The string to search for
+ */
+void devhelp_plugin_search_books(DevhelpPlugin *self, const gchar *term)
+{
+
+ g_return_if_fail(self != NULL);
+ g_return_if_fail(term != NULL);
+
+ dh_search_set_search_string(DH_SEARCH(self->priv->search), term, NULL);
+
+ devhelp_plugin_activate_all_tabs(self);
+}
+
+
+/*
+ * Cleans up a word/tag before searching.
+ *
+ * Replaces non @c GEANY_WORDCHARS in str with spaces and then trims whitespace.
+ * This function does not allocate a new string, it modifies @a str in place
+ * and returns a pointer to @a str.
+ * TODO: make this only remove stuff from the start or end of string.
+ *
+ * @param str String to clean
+ *
+ * @return Pointer to (cleaned) @a str.
+ */
+static inline gchar *clean_word(gchar* str)
+{
+ return g_strstrip(g_strcanon(str, GEANY_WORDCHARS, ' '));
+}
+
+
+/**
+ * Gets either the current selection or the word at the current selection.
+ *
+ * @return Newly allocated string with current tag or NULL no tag.
+ */
+gchar *devhelp_plugin_get_current_word(DevhelpPlugin *self)
+{
+ gint pos;
+ gchar *tag = NULL;
+ GeanyDocument *doc = document_get_current();
+
+ g_return_val_if_fail(DEVHELP_IS_PLUGIN(self), NULL);
+
+ if (doc == NULL || doc->editor == NULL || doc->editor->sci == NULL)
+ return NULL;
+
+ if (sci_has_selection(doc->editor->sci))
+ return clean_word(sci_get_selection_contents(doc->editor->sci));
+
+ pos = sci_get_current_position(doc->editor->sci);
+ tag = editor_get_word_at_pos(doc->editor, pos, GEANY_WORDCHARS);
+
+ if (tag == NULL || strlen(tag) == 0)
+ {
+ g_free(tag /* might be null, ok */);
+ return NULL;
+ }
+
+ return clean_word(tag);
+}
+
+
+/**
+ * Activate the plugin's tabs in the UI.
+ *
+ * @param dhplug Devhelp plugin
+ * @param search_tabs_shown If TRUE, show the sidebar search tab, otherwise
+ * show the contents tab.
+ */
+void devhelp_plugin_activate_ui(DevhelpPlugin *self, gboolean show_search_tab)
+{
+ g_return_if_fail(self != NULL);
+ devhelp_plugin_set_ui_active(self, TRUE);
+ gtk_notebook_set_current_page(GTK_NOTEBOOK(self->priv->sb_notebook), (show_search_tab) ? 1 : 0);
+}
+
+
+/**
+ * Get whether or not the plugin's tabs are shown/active in the UI.
+ *
+ * @param self Devhelp plugin.
+ *
+ * @return TRUE if the UI elements are active FALSE if not.
+ */
+gboolean devhelp_plugin_get_ui_active(DevhelpPlugin *self)
+{
+ g_return_val_if_fail(DEVHELP_IS_PLUGIN(self), FALSE);
+ return self->priv->tabs_toggled;
+}
+
+
+/**
+ * Set whether or not the plugin's tabs are shown/active in the UI.
+ *
+ * @param self Devhelp plugin
+ * @param active Whether to show the plugin's tabs or the previous tabs.
+ */
+void devhelp_plugin_set_ui_active(DevhelpPlugin *self, gboolean active)
+{
+ GtkNotebook *main_nb, *sbar_nb;
+
+ g_return_if_fail(DEVHELP_IS_PLUGIN(self));
+
+ main_nb = GTK_NOTEBOOK(self->priv->main_notebook);
+ sbar_nb = GTK_NOTEBOOK(geany->main_widgets->sidebar_notebook);
+
+ if (active && !devhelp_plugin_get_ui_active(self))
+ {
+ self->priv->last_main_tab_id = gtk_notebook_get_current_page(main_nb);
+ self->priv->last_sb_tab_id = gtk_notebook_get_current_page(sbar_nb);
+ gtk_notebook_set_current_page(main_nb, gtk_notebook_page_num(main_nb, self->priv->webview_tab));
+ gtk_notebook_set_current_page(sbar_nb, gtk_notebook_page_num(sbar_nb, self->priv->sb_notebook));
+ self->priv->tabs_toggled = TRUE;
+ g_object_notify(G_OBJECT(self), "ui-active");
+ }
+ else if (!active && devhelp_plugin_get_ui_active(self))
+ {
+ gtk_notebook_set_current_page(main_nb, self->priv->last_main_tab_id);
+ gtk_notebook_set_current_page(sbar_nb, self->priv->last_sb_tab_id);
+ self->priv->tabs_toggled = FALSE;
+ g_object_notify(G_OBJECT(self), "ui-active");
+ }
+}
+
+
+/**
+ * Gets whether the Geany sidebar tabs are in the bottom or their original position.
+ *
+ * @param self Devhelp plugin.
+ */
+gboolean devhelp_plugin_get_sidebar_tabs_bottom(DevhelpPlugin *self)
+{
+ GtkPositionType pos;
+ g_return_val_if_fail(DEVHELP_IS_PLUGIN(self), FALSE);
+ pos = gtk_notebook_get_tab_pos(GTK_NOTEBOOK(geany->main_widgets->sidebar_notebook));
+ return pos == GTK_POS_BOTTOM;
+}
+
+
+/**
+ * Sets whether the Geany sidebar tabs are at the bottom or in their original position.
+ *
+ * @param self Devhelp plugin.
+ * @param bottom If TRUE, set the sidebar tab position to @c GTK_POS_BOTTOM
+ * otherwise set back to original position.
+ */
+void devhelp_plugin_set_sidebar_tabs_bottom(DevhelpPlugin *self, gboolean bottom)
+{
+ GtkNotebook *nb;
+
+ g_return_if_fail(DEVHELP_IS_PLUGIN(self));
+
+ nb = GTK_NOTEBOOK(geany->main_widgets->sidebar_notebook);
+
+ if (!devhelp_plugin_get_sidebar_tabs_bottom(self) && bottom)
+ {
+ self->priv->orig_sb_tab_pos = gtk_notebook_get_tab_pos(nb);
+ gtk_notebook_set_tab_pos(nb, GTK_POS_BOTTOM);
+ g_object_notify(G_OBJECT(self), "sidebar-tabs-bottom");
+ }
+ else if (devhelp_plugin_get_sidebar_tabs_bottom(self) && !bottom)
+ {
+ gtk_notebook_set_tab_pos(nb, self->priv->orig_sb_tab_pos);
+ g_object_notify(G_OBJECT(self), "sidebar-tabs-bottom");
+ }
+}
+
+
+/**
+ * Gets whether the Documentation tab is in a main_notebook or in the
+ * message window.
+ *
+ * @param self Devhelp plugin.
+ *
+ * @return TRUE if the Documentation tab is in a main_notebok or FALSE if it's
+ * in the message window notebook.
+ */
+gboolean devhelp_plugin_get_in_message_window(DevhelpPlugin *self)
+{
+ g_return_val_if_fail(DEVHELP_IS_PLUGIN(self), FALSE);
+ return self->priv->in_message_window;
+}
+
+
+/* Refs the webkit tab stuff and removes it from parents, returns pointer to
+ * widget that was ref'd. */
+static GtkWidget* devhelp_plugin_ref_unpack_webview_tab(DevhelpPlugin *self)
+{
+ GtkWidget *parent, *doc_nb;
+
+ g_return_val_if_fail(DEVHELP_IS_PLUGIN(self), NULL);
+
+ /* Prevents a segfault bug from popping up when messing with doc notebook */
+ gtk_widget_set_sensitive(geany->main_widgets->notebook, FALSE);
+
+ gtk_widget_ref(self->priv->webview_tab);
+
+ if (self->priv->location != DEVHELP_PLUGIN_WEBVIEW_LOCATION_NONE)
+ {
+ parent = gtk_widget_get_parent(self->priv->webview_tab);
+ gtk_container_remove(GTK_CONTAINER(parent), self->priv->webview_tab);
+ }
+
+ /* If we were using the "main notebook", put the UI back to normal */
+ if (self->priv->location == DEVHELP_PLUGIN_WEBVIEW_LOCATION_MAIN_NOTEBOOK)
+ {
+ parent = gtk_widget_get_parent(self->priv->main_notebook);
+ doc_nb = gtk_widget_ref(geany->main_widgets->notebook);
+ gtk_container_remove(GTK_CONTAINER(self->priv->main_notebook), doc_nb);
+ gtk_container_remove(GTK_CONTAINER(parent), self->priv->main_notebook);
+ gtk_container_add(GTK_CONTAINER(parent), doc_nb);
+ gtk_widget_unref(doc_nb);
+ self->priv->main_notebook = NULL;
+ }
+
+ self->priv->location = DEVHELP_PLUGIN_WEBVIEW_LOCATION_NONE;
+
+ gtk_widget_set_sensitive(geany->main_widgets->notebook, TRUE);
+
+ return self->priv->webview_tab;
+}
+
+
+static void devhelp_plugin_set_webview_location(DevhelpPlugin *self, DevhelpPluginWebViewLocation location)
+{
+ g_return_if_fail(DEVHELP_IS_PLUGIN(self));
+
+ if (location == self->priv->location) /* no change, so do nothing */
+ return;
+
+ switch(location)
+ {
+ case DEVHELP_PLUGIN_WEBVIEW_LOCATION_SIDEBAR:
+ gtk_notebook_append_page(
+ GTK_NOTEBOOK(geany->main_widgets->sidebar_notebook),
+ devhelp_plugin_ref_unpack_webview_tab(self),
+ gtk_label_new(DEVHELP_PLUGIN_WEBVIEW_TAB_LABEL));
+ gtk_widget_unref(self->priv->webview_tab);
+ self->priv->location = DEVHELP_PLUGIN_WEBVIEW_LOCATION_SIDEBAR;
+ break;
+ case DEVHELP_PLUGIN_WEBVIEW_LOCATION_MESSAGE_WINDOW:
+ gtk_notebook_append_page(
+ GTK_NOTEBOOK(geany->main_widgets->message_window_notebook),
+ devhelp_plugin_ref_unpack_webview_tab(self),
+ gtk_label_new(DEVHELP_PLUGIN_WEBVIEW_TAB_LABEL));
+ gtk_widget_unref(self->priv->webview_tab);
+ self->priv->location = DEVHELP_PLUGIN_WEBVIEW_LOCATION_MESSAGE_WINDOW;
+ break;
+ case DEVHELP_PLUGIN_WEBVIEW_LOCATION_MAIN_NOTEBOOK:
+ {
+ GtkWidget *parent, *doc_nb, *main_notebook, *webview_tab;
+
+ webview_tab = devhelp_plugin_ref_unpack_webview_tab(self);
+ doc_nb = geany->main_widgets->notebook;
+ parent = gtk_widget_get_parent(doc_nb);
+
+ gtk_widget_ref(doc_nb);
+
+ gtk_container_remove(GTK_CONTAINER(parent), doc_nb);
+ main_notebook = gtk_notebook_new();
+ self->priv->main_notebook = main_notebook;
+
+ gtk_notebook_append_page(GTK_NOTEBOOK(main_notebook),
+ doc_nb, gtk_label_new(DEVHELP_PLUGIN_DOCUMENTS_TAB_LABEL));
+ gtk_notebook_append_page(GTK_NOTEBOOK(main_notebook),
+ webview_tab, gtk_label_new(DEVHELP_PLUGIN_WEBVIEW_TAB_LABEL));
+
+ gtk_container_add(GTK_CONTAINER(parent), main_notebook);
+
+ gtk_widget_show_all(doc_nb);
+ gtk_widget_show_all(webview_tab);
+ gtk_widget_show_all(main_notebook);
+
+ gtk_widget_unref(doc_nb);
+ gtk_widget_unref(webview_tab);
+
+ self->priv->location = DEVHELP_PLUGIN_WEBVIEW_LOCATION_MAIN_NOTEBOOK;
+ break;
+ }
+ default:
+ g_warning("Unable to set location of webview.");
+ break;
+ }
+}
+
+
+/**
+ * Sets whether the Documentation tab is in the message window notebook or is
+ * in a main_notebook.
+ *
+ * @param self Devhelp plugin.
+ * @param in_msgwin TRUE to move the Documentation tab to the message window
+ * notebook or FALSE to create a main_notebook and put it there.
+ */
+void devhelp_plugin_set_in_message_window(DevhelpPlugin *self, gboolean in_msgwin)
+{
+ g_return_if_fail(DEVHELP_IS_PLUGIN(self));
+
+ if (in_msgwin && !self->priv->in_message_window)
+ {
+ devhelp_plugin_set_webview_location(self,
+ DEVHELP_PLUGIN_WEBVIEW_LOCATION_MESSAGE_WINDOW);
+ self->priv->in_message_window = TRUE;
+ g_object_notify(G_OBJECT(self), "in-message-window");
+ }
+ else if (!in_msgwin && self->priv->in_message_window)
+ {
+ devhelp_plugin_set_webview_location(self,
+ DEVHELP_PLUGIN_WEBVIEW_LOCATION_MAIN_NOTEBOOK);
+ self->priv->in_message_window = FALSE;
+ g_object_notify(G_OBJECT(self), "in-message-window");
+ }
+}
+
+
+/**
+ * Gets the zoom level of the WebKit WebView.
+ *
+ * @param self Devhelp plugin.
+ *
+ * @return The zoom level.
+ */
+gfloat devhelp_plugin_get_zoom_level(DevhelpPlugin *self)
+{
+ g_return_val_if_fail(DEVHELP_IS_PLUGIN(self), 0.0F);
+ return webkit_web_view_get_zoom_level(WEBKIT_WEB_VIEW(self->priv->webview));
+}
+
+
+/**
+ * Sets the zoom level of the WebKit WebView.
+ *
+ * @param self Devhelp plugin.
+ * @param zoom_level The zoom level to set.
+ */
+void devhelp_plugin_set_zoom_level(DevhelpPlugin *self, gfloat zoom_level)
+{
+ g_return_if_fail(DEVHELP_IS_PLUGIN(self));
+
+ if (devhelp_plugin_get_zoom_level(self) != zoom_level)
+ {
+ webkit_web_view_set_zoom_level(WEBKIT_WEB_VIEW(self->priv->webview), zoom_level);
+ g_object_notify(G_OBJECT(self), "zoom-level");
+ }
+}
+
+
+WebKitWebView* devhelp_plugin_get_webview(DevhelpPlugin *self)
+{
+ g_return_val_if_fail(DEVHELP_IS_PLUGIN(self), NULL);
+ return WEBKIT_WEB_VIEW(self->priv->webview);
+}
+
+
+/**
+ * Returns a pointer to the list used to track temp files.
+ *
+ * @param self Devhelp plugin.
+ *
+ * @return Pointer to the internal list used to track temp files.
+ */
+GList* devhelp_plugin_get_temp_files(DevhelpPlugin *self)
+{
+ g_return_val_if_fail(DEVHELP_IS_PLUGIN(self), NULL);
+ return self->priv->temp_files;
+}
+
+
+/**
+ * Returns the path to the 'man' program on the system or NULL if one was not
+ * found.
+ *
+ * @param self Devhelp plugin.
+ *
+ * @return The path to the 'man' program or NULL if not found. Free the
+ * returned value when no longer needed.
+ */
+const gchar* devhelp_plugin_get_man_prog_path(DevhelpPlugin *self)
+{
+ g_return_val_if_fail(DEVHELP_IS_PLUGIN(self), NULL);
+ return (const gchar *)self->priv->man_prog_path;
+}
+
+
+/**
+ * Finds whether or not a 'man' program is available (in the path) on the
+ * current system.
+ *
+ * @param self Devhelp plugin.
+ *
+ * @return TRUE if a 'man' program was found or FALSE if not.
+ */
+gboolean devhelp_plugin_get_have_man_prog(DevhelpPlugin *self)
+{
+ g_return_val_if_fail(DEVHELP_IS_PLUGIN(self), FALSE);
+ return devhelp_plugin_get_man_prog_path(self) != NULL;
+}
+
+
+/* TODO: make properties for the following accessor functions */
+
+gboolean devhelp_plugin_get_devhelp_sidebar_visible(DevhelpPlugin *self)
+{
+ g_return_val_if_fail(DEVHELP_IS_PLUGIN(self), FALSE);
+ return gtk_widget_get_visible(self->priv->sb_notebook);
+}
+
+
+void devhelp_plugin_set_devhelp_sidebar_visible(DevhelpPlugin *self, gboolean visible)
+{
+ g_return_if_fail(DEVHELP_IS_PLUGIN(self));
+ gtk_widget_set_visible(self->priv->sb_notebook, visible);
+}
+
+
+gboolean devhelp_plugin_get_use_devhelp(DevhelpPlugin *self)
+{
+ g_return_val_if_fail(DEVHELP_IS_PLUGIN(self), FALSE);
+ return self->priv->use_devhelp;
+}
+
+
+void devhelp_plugin_set_use_devhelp(DevhelpPlugin *self, gboolean use)
+{
+ g_return_if_fail(DEVHELP_IS_PLUGIN(self));
+ self->priv->use_devhelp = use;
+ gtk_widget_set_visible(self->priv->sb_notebook, use);
+ /* TODO: hide edit menu items and keybindings */
+ /* TODO: if no providers, hide webview */
+}
+
+
+gboolean devhelp_plugin_get_use_man(DevhelpPlugin *self)
+{
+ g_return_val_if_fail(DEVHELP_IS_PLUGIN(self), FALSE);
+ return self->priv->use_man;
+}
+
+
+void devhelp_plugin_set_use_man(DevhelpPlugin *self, gboolean use)
+{
+ g_return_if_fail(DEVHELP_IS_PLUGIN(self));
+ self->priv->use_man = use;
+ /* TODO: hide edit menu items and keybindings */
+ /* TODO: if no providers, hide webview */
+}
+
+
+gboolean devhelp_plugin_get_use_codesearch(DevhelpPlugin *self)
+{
+ g_return_val_if_fail(DEVHELP_IS_PLUGIN(self), FALSE);
+ return self->priv->use_codesearch;
+}
+
+
+void devhelp_plugin_set_use_codesearch(DevhelpPlugin *self, gboolean use)
+{
+ g_return_if_fail(DEVHELP_IS_PLUGIN(self));
+ self->priv->use_codesearch = use;
+ /* TODO: hide edit menu items and keybindings */
+ /* TODO: if no providers, hide webview */
+}
+
+
+/* Activates (brings to top/makes visible) the Devhelp plugin's sidebar tab. */
+static inline void devhelp_plugin_activate_sidebar_tab(DevhelpPlugin *self)
+{
+ GtkNotebook *nb;
+ gint current_tab_id;
+
+ g_return_if_fail(self != NULL);
+
+ nb = GTK_NOTEBOOK(geany->main_widgets->sidebar_notebook);
+
+ current_tab_id = gtk_notebook_get_current_page(nb);
+ if (current_tab_id != gtk_notebook_page_num(nb, self->priv->sb_notebook))
+ self->priv->last_sb_tab_id = current_tab_id;
+
+ gtk_widget_set_visible(self->priv->sb_notebook, TRUE);
+ gtk_notebook_set_current_page(nb, gtk_notebook_page_num(nb, self->priv->sb_notebook));
+}
+
+
+/**
+ * Activates the Devhelp plugin's sidebar tab, and then the internal notebook's
+ * Search tab.
+ *
+ * @param self Devhelp plugin.
+ */
+void devhelp_plugin_activate_search_tab(DevhelpPlugin *self)
+{
+ g_return_if_fail(self != NULL);
+ devhelp_plugin_activate_sidebar_tab(self);
+ gtk_notebook_set_current_page(GTK_NOTEBOOK(self->priv->sb_notebook), 1);
+}
+
+
+/**
+ * Activates the Devhelp plugin's sidebar tab, and then the internal notebook's
+ * Contents tab.
+ *
+ * @param self Devhelp plugin.
+ */
+void devhelp_plugin_activate_contents_tab(DevhelpPlugin *self)
+{
+ g_return_if_fail(self != NULL);
+ devhelp_plugin_activate_sidebar_tab(self);
+ gtk_notebook_set_current_page(GTK_NOTEBOOK(self->priv->sb_notebook), 0);
+}
+
+
+/**
+ * Activates the Devhelp plugin's main notebook's Documentation tab.
+ *
+ * @param self Devhelp plugin.
+ */
+void devhelp_plugin_activate_webview_tab(DevhelpPlugin *self)
+{
+ GtkNotebook *nb;
+ gint current_tab_id;
+
+ g_return_if_fail(self != NULL);
+
+ nb = GTK_NOTEBOOK(self->priv->main_notebook);
+
+ current_tab_id = gtk_notebook_get_current_page(nb);
+ if (current_tab_id != gtk_notebook_page_num(nb, self->priv->webview_tab))
+ self->priv->last_main_tab_id = current_tab_id;
+
+ gtk_notebook_set_current_page(nb, gtk_notebook_page_num(nb, self->priv->webview_tab));
+}
+
+
+/* Toggles the Devhelp tab in the Geany sidebar notebook. */
+static inline void devhelp_plugin_toggle_sidebar_tab(DevhelpPlugin *self, gint tab)
+{
+ GtkNotebook *sbar_nb;
+ gint current_tab_id;
+
+ g_return_if_fail(self != NULL);
+
+ sbar_nb = GTK_NOTEBOOK(geany->main_widgets->sidebar_notebook);
+ current_tab_id = gtk_notebook_get_current_page(sbar_nb);
+
+ if (current_tab_id == gtk_notebook_page_num(sbar_nb, self->priv->sb_notebook))
+ gtk_notebook_set_current_page(sbar_nb, self->priv->last_sb_tab_id);
+ else
+ {
+ if (tab == 0)
+ devhelp_plugin_activate_contents_tab(self);
+ else if (tab == 1)
+ devhelp_plugin_activate_search_tab(self);
+ else
+ g_warning("Can't toggle to unknown tab ID: %d", tab);
+ }
+}
+
+
+/**
+ * Toggle's between the Devhelp plugin's search tab and the previous Geany
+ * sidebar tab.
+ *
+ * @param self Devhelp plugin.
+ */
+void devhelp_plugin_toggle_search_tab(DevhelpPlugin *self)
+{
+ devhelp_plugin_toggle_sidebar_tab(self, 1);
+}
+
+
+/**
+ * Toggle's between the Devhelp plugin's contents tab and the previous Geany
+ * sidebar tab.
+ *
+ * @param self Devhelp plugin.
+ */
+void devhelp_plugin_toggle_contents_tab(DevhelpPlugin *self)
+{
+ devhelp_plugin_toggle_sidebar_tab(self, 0);
+}
+
+
+/**
+ * Toggle's between the Devhelp plugin's main notebook tab and the previous
+ * main notebook tab.
+ *
+ * @param self Devhelp plugin.
+ */
+void devhelp_plugin_toggle_webview_tab(DevhelpPlugin *self)
+{
+ gint current_tab_id;
+
+ g_return_if_fail(self != NULL);
+
+ current_tab_id = gtk_notebook_get_current_page(GTK_NOTEBOOK(self->priv->main_notebook));
+ if (current_tab_id == self->priv->last_main_tab_id)
+ {
+ gtk_notebook_set_current_page(GTK_NOTEBOOK(self->priv->main_notebook),
+ self->priv->last_main_tab_id);
+ }
+ else
+ devhelp_plugin_activate_webview_tab(self);
+}
+
+
+/**
+ * Activates/shows all the Devhelp plugins tabs.
+ *
+ * @param self Devhelp plugin.
+ */
+void devhelp_plugin_activate_all_tabs(DevhelpPlugin *self)
+{
+ devhelp_plugin_activate_sidebar_tab(self);
+ devhelp_plugin_activate_webview_tab(self);
+}
+
+
+/* Called when the editor menu item is selected */
+static void on_search_help_activate(GtkMenuItem * menuitem, DevhelpPlugin *self)
+{
+ gchar *current_tag;
+
+ g_return_if_fail(self != NULL);
+
+ if ((current_tag = devhelp_plugin_get_current_word(self)) == NULL)
+ return;
+
+ devhelp_plugin_search_books(self, current_tag);
+
+ g_free(current_tag);
+}
+
+
+/* Called when the editor menu item is selected */
+static void on_search_help_man_activate(GtkMenuItem * menuitem, DevhelpPlugin *self)
+{
+ gchar *current_tag;
+
+ g_return_if_fail(self != NULL);
+
+ if ((current_tag = devhelp_plugin_get_current_word(self)) == NULL)
+ return;
+
+ devhelp_plugin_search_manpages(self, current_tag);
+
+ g_free(current_tag);
+}
+
+
+static void on_search_help_code_activate(GtkMenuItem *menuitem, DevhelpPlugin *self)
+{
+ gchar *current_tag;
+ const gchar *lang = NULL;
+ GeanyDocument *doc;
+
+ g_return_if_fail(self != NULL);
+
+ if ((current_tag = devhelp_plugin_get_current_word(self)) == NULL)
+ return;
+
+ doc = document_get_current();
+ if (doc != NULL && doc->file_type != NULL && doc->file_type->name != NULL)
+ lang = doc->file_type->name;
+
+ devhelp_plugin_search_code(self, current_tag, lang);
+
+ g_free(current_tag);
+}
+
+
+/*
+ * Called when the editor context menu is shown so that the devhelp
+ * search item can be disabled if there isn't a selected tag.
+ */
+static void on_editor_menu_popup(GtkWidget * widget, DevhelpPlugin *self)
+{
+ gchar *label_tag, *curword, *new_label;
+
+ g_return_if_fail(self != NULL);
+
+ curword = devhelp_plugin_get_current_word(self);
+
+ if (curword == NULL)
+ {
+ gtk_widget_set_sensitive(self->priv->editor_menu_item, FALSE);
+ return;
+ }
+
+ label_tag = g_strstrip(g_strndup(curword, DHPLUG_MAX_LABEL_TAG));
+ new_label = g_strdup_printf(_("Search for '%s' Documentation in"), label_tag);
+
+ gtk_menu_item_set_label(GTK_MENU_ITEM(self->priv->editor_menu_item), new_label);
+
+ g_free(new_label);
+ g_free(label_tag);
+
+ gtk_widget_set_sensitive(self->priv->editor_menu_item, TRUE);
+
+ g_free(curword);
+}
+
+
+/*
+ * Called when a link in either the contents or search areas on the sidebar
+ * have a link clicked on, meaning to load that file into the webview.
+ */
+static void on_link_clicked(GObject * ignored, DhLink * dhlink, DevhelpPlugin *self)
+{
+ gchar *uri;
+
+ g_return_if_fail(DEVHELP_IS_PLUGIN(self));
+
+ uri = dh_link_get_uri(dhlink);
+ devhelp_plugin_set_webview_uri(self, uri);
+ devhelp_plugin_activate_webview_tab(self);
+ g_free(uri);
+}
+
+
+static void on_back_button_clicked(GtkToolButton * btn, DevhelpPlugin *self)
+{
+ g_return_if_fail(DEVHELP_IS_PLUGIN(self));
+ webkit_web_view_go_back(WEBKIT_WEB_VIEW(self->priv->webview));
+}
+
+
+static void on_forward_button_clicked(GtkToolButton * btn, DevhelpPlugin *self)
+{
+ g_return_if_fail(DEVHELP_IS_PLUGIN(self));
+ webkit_web_view_go_forward(WEBKIT_WEB_VIEW(self->priv->webview));
+}
+
+
+static void on_zoom_in_button_clicked(GtkToolButton * btn, DevhelpPlugin *self)
+{
+ g_return_if_fail(DEVHELP_IS_PLUGIN(self));
+ webkit_web_view_zoom_in(devhelp_plugin_get_webview(self));
+}
+
+
+static void on_zoom_out_button_clicked(GtkToolButton *btn, DevhelpPlugin *self)
+{
+ g_return_if_fail(DEVHELP_IS_PLUGIN(self));
+ webkit_web_view_zoom_out(devhelp_plugin_get_webview(self));
+}
+
+
+/* Controls the sensitivity of the back/forward buttons when webkit page changes. */
+static inline void update_history_buttons(DevhelpPlugin *self)
+{
+ g_return_if_fail(DEVHELP_IS_PLUGIN(self));
+
+ gtk_widget_set_sensitive(GTK_WIDGET(self->priv->btn_back),
+ webkit_web_view_can_go_back(devhelp_plugin_get_webview(self)));
+ gtk_widget_set_sensitive(GTK_WIDGET(self->priv->btn_forward),
+ webkit_web_view_can_go_forward(devhelp_plugin_get_webview(self)));
+}
+
+
+static void on_document_load_finished(WebKitWebView *view, WebKitWebFrame *frame, DevhelpPlugin *self)
+{
+ update_history_buttons(self);
+}
+
+
+static void on_uri_changed_notify(GObject *object, GParamSpec *pspec, DevhelpPlugin *self)
+{
+ update_history_buttons(self);
+}
+
+
+static void on_load_status_changed_notify(GObject *object, GParamSpec *pspec, DevhelpPlugin *self)
+{
+ update_history_buttons(self);
+}
+
Added: trunk/geany-plugins/devhelp/src/dhp-plugin.c
===================================================================
--- trunk/geany-plugins/devhelp/src/dhp-plugin.c (rev 0)
+++ trunk/geany-plugins/devhelp/src/dhp-plugin.c 2011-05-24 09:04:06 UTC (rev 2082)
@@ -0,0 +1,209 @@
+/*
+ * plugin.c - Part of the Geany Devhelp Plugin
+ *
+ * Copyright 2010 Matthew Brush <mbrush at leftclick.ca>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <sys/stat.h> /* for g_mkdir_with_parents, is it portable? */
+
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h> /* for keybindings */
+#include <geanyplugin.h>
+#include <devhelp/dh-search.h>
+
+#include "dhp-plugin.h"
+#include "dhp.h"
+
+
+PLUGIN_VERSION_CHECK(200)
+
+PLUGIN_SET_INFO(
+ _("Devhelp Plugin"),
+ _("Adds support for looking up documentation in Devhelp, manual pages, and "
+ "Google Code Search in the integrated viewer."),
+ "1.0", "Matthew Brush <mbrush at leftclick.ca>")
+
+
+GeanyPlugin *geany_plugin;
+GeanyData *geany_data;
+GeanyFunctions *geany_functions;
+
+struct PluginData plugin;
+
+/* keybindings */
+enum
+{
+ KB_DEVHELP_TOGGLE_CONTENTS,
+ KB_DEVHELP_TOGGLE_SEARCH,
+ KB_DEVHELP_TOGGLE_WEBVIEW,
+ KB_DEVHELP_ACTIVATE_DEVHELP,
+ KB_DEVHELP_SEARCH_SYMBOL,
+ KB_DEVHELP_SEARCH_MANPAGES,
+ KB_DEVHELP_SEARCH_CODESEARCH,
+ KB_COUNT
+};
+
+/* Called when a keybinding is activated */
+static void kb_activate(guint key_id)
+{
+ gchar *current_tag;
+
+ switch (key_id)
+ {
+ case KB_DEVHELP_TOGGLE_CONTENTS:
+ devhelp_plugin_toggle_contents_tab(plugin.devhelp);
+ break;
+ case KB_DEVHELP_TOGGLE_SEARCH:
+ devhelp_plugin_toggle_search_tab(plugin.devhelp);
+ break;
+ case KB_DEVHELP_TOGGLE_WEBVIEW: /* not working */
+ devhelp_plugin_toggle_webview_tab(plugin.devhelp);
+ break;
+ case KB_DEVHELP_ACTIVATE_DEVHELP:
+ devhelp_plugin_activate_all_tabs(plugin.devhelp);
+ break;
+ case KB_DEVHELP_SEARCH_SYMBOL:
+ {
+ current_tag = devhelp_plugin_get_current_word(plugin.devhelp);
+ if (current_tag == NULL)
+ return;
+ devhelp_plugin_search_books(plugin.devhelp, current_tag);
+ g_free(current_tag);
+ break;
+ }
+ case KB_DEVHELP_SEARCH_MANPAGES:
+ {
+ current_tag = devhelp_plugin_get_current_word(plugin.devhelp);
+ if (current_tag == NULL)
+ return;
+ devhelp_plugin_search_manpages(plugin.devhelp, current_tag);
+ g_free(current_tag);
+ break;
+ }
+ case KB_DEVHELP_SEARCH_CODESEARCH:
+ {
+ const gchar *lang = NULL;
+ GeanyDocument *doc;
+
+ if ((current_tag = devhelp_plugin_get_current_word(plugin.devhelp)) == NULL)
+ return;
+
+ doc = document_get_current();
+ if (doc == NULL || doc->file_type == NULL || doc->file_type->name == NULL)
+ lang = doc->file_type->name;
+
+ devhelp_plugin_search_code(plugin.devhelp, current_tag, lang);
+
+ g_free(current_tag);
+ break;
+ }
+ }
+}
+
+
+gboolean plugin_config_init(struct PluginData *pd)
+{
+ gchar *user_config_dir;
+
+ g_return_val_if_fail(pd != NULL, FALSE);
+
+ plugin.default_config = g_build_path(G_DIR_SEPARATOR_S, DHPLUG_DATA_DIR, "devhelp.conf", NULL);
+
+ user_config_dir = g_build_path(G_DIR_SEPARATOR_S, geany_data->app->configdir, "plugins", "devhelp", NULL);
+ plugin.user_config = g_build_path(G_DIR_SEPARATOR_S, user_config_dir, "devhelp.conf", NULL);
+ if (g_mkdir_with_parents(user_config_dir, S_IRUSR | S_IWUSR | S_IXUSR) != 0)
+ {
+ g_warning(_("Unable to create config dir at '%s'"), user_config_dir);
+ g_free(user_config_dir);
+ return FALSE;
+ }
+ g_free(user_config_dir);
+
+ /* copy default config into user config if it doesn't exist */
+ if (!g_file_test(pd->user_config, G_FILE_TEST_EXISTS))
+ {
+ gchar *config_text;
+ GError *error;
+
+ error = NULL;
+ if (!g_file_get_contents(pd->default_config, &config_text, NULL, &error))
+ {
+ g_warning(_("Unable to get default configuration: %s"), error->message);
+ g_error_free(error);
+ return FALSE;
+ }
+ else
+ {
+ if (!g_file_set_contents(pd->user_config, config_text, -1, &error))
+ {
+ g_warning(_("Unable to write default configuration: %s"), error->message);
+ g_error_free(error);
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+
+void plugin_init(GeanyData *data)
+{
+ GeanyKeyGroup *key_group;
+
+ plugin_module_make_resident(geany_plugin);
+
+ if (!g_thread_supported())
+ g_thread_init(NULL);
+
+ memset(&plugin, 0, sizeof(struct PluginData));
+
+ plugin.devhelp = devhelp_plugin_new();
+ plugin_config_init(&plugin);
+
+ devhelp_plugin_load_settings(plugin.devhelp, plugin.user_config);
+
+ key_group = plugin_set_key_group(geany_plugin, "devhelp", KB_COUNT, NULL);
+
+ keybindings_set_item(key_group, KB_DEVHELP_TOGGLE_CONTENTS, kb_activate,
+ 0, 0, "devhelp_toggle_contents", _("Toggle sidebar contents tab"), NULL);
+ keybindings_set_item(key_group, KB_DEVHELP_TOGGLE_SEARCH, kb_activate,
+ 0, 0, "devhelp_toggle_search", _("Toggle sidebar search tab"), NULL);
+ keybindings_set_item(key_group, KB_DEVHELP_TOGGLE_WEBVIEW, kb_activate,
+ 0, 0, "devhelp_toggle_webview", _("Toggle documentation tab"), NULL);
+ keybindings_set_item(key_group, KB_DEVHELP_ACTIVATE_DEVHELP, kb_activate,
+ 0, 0, "devhelp_activate_all", _("Activate all tabs"), NULL);
+ keybindings_set_item(key_group, KB_DEVHELP_SEARCH_SYMBOL, kb_activate,
+ 0, 0, "devhelp_search_symbol", _("Search for current tag in Devhelp"), NULL);
+ if (devhelp_plugin_get_have_man_prog(plugin.devhelp))
+ {
+ keybindings_set_item(key_group, KB_DEVHELP_SEARCH_MANPAGES, kb_activate,
+ 0, 0, "devhelp_search_manpages", _("Search for current tag in Manual Pages"), NULL);
+ }
+ keybindings_set_item(key_group, KB_DEVHELP_SEARCH_CODESEARCH, kb_activate,
+ 0, 0, "devhelp_search_codesearch", _("Search for current tag in Google Code Search"), NULL);
+}
+
+
+void plugin_cleanup(void)
+{
+ devhelp_plugin_store_settings(plugin.devhelp, plugin.user_config);
+ g_object_unref(plugin.devhelp);
+ g_free(plugin.default_config);
+ g_free(plugin.user_config);
+}
Copied: trunk/geany-plugins/devhelp/src/dhp-plugin.h (from rev 2081, trunk/geany-plugins/devhelp/src/plugin.h)
===================================================================
--- trunk/geany-plugins/devhelp/src/dhp-plugin.h (rev 0)
+++ trunk/geany-plugins/devhelp/src/dhp-plugin.h 2011-05-24 09:04:06 UTC (rev 2082)
@@ -0,0 +1,51 @@
+/*
+ * plugin.h - Part of the Geany Devhelp Plugin
+ *
+ * Copyright 2010 Matthew Brush <mbrush at leftclick.ca>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef PLUGIN_COMMON_H
+#define PLUGIN_COMMON_H
+
+
+#include <gtk/gtk.h>
+#include <geanyplugin.h>
+
+#include "dhp.h"
+
+
+extern GeanyPlugin *geany_plugin;
+extern GeanyData *geany_data;
+extern GeanyFunctions *geany_functions;
+
+
+struct PluginData
+{
+ gchar *default_config;
+ gchar *user_config;
+
+ DevhelpPlugin *devhelp;
+};
+
+extern struct PluginData plugin;
+
+
+gboolean plugin_config_init (struct PluginData *pd);
+
+
+#endif
Added: trunk/geany-plugins/devhelp/src/dhp-settings.c
===================================================================
--- trunk/geany-plugins/devhelp/src/dhp-settings.c (rev 0)
+++ trunk/geany-plugins/devhelp/src/dhp-settings.c 2011-05-24 09:04:06 UTC (rev 2082)
@@ -0,0 +1,343 @@
+/* Included directly into dhp-object.c just to keep this whole mess out
+ * of that file until it's not done so stupidly. */
+
+void devhelp_plugin_load_settings(DevhelpPlugin *self, const gchar *filename)
+{
+ GError *error;
+ GKeyFile *kf;
+ gboolean value;
+
+ g_return_if_fail(DEVHELP_IS_PLUGIN(self));
+
@@ Diff output truncated at 100000 characters. @@
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Plugins-Commits
mailing list