1 /*
2 * plugin.c - Part of the Geany Devhelp Plugin
3 *
4 * Copyright 2010 Matthew Brush <mbrush@leftclick.ca>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 * MA 02110-1301, USA.
20 */
21
22 #include <string.h>
23 #include <sys/stat.h> /* for g_mkdir_with_parents, is it portable? */
24
25 #include <gtk/gtk.h>
26 #include <gdk/gdkkeysyms.h> /* for keybindings */
27
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31 #include <geanyplugin.h>
32
33 #include <devhelp/dh-search.h>
34
35 #include "dhp-plugin.h"
36 #include "dhp.h"
37
38
39 GeanyPlugin *geany_plugin;
40 GeanyData *geany_data;
41
42
43 struct PluginData
44 {
45 gchar *default_config;
46 gchar *user_config;
47
48 DevhelpPlugin *devhelp;
49 };
50
51
52 struct PluginData plugin_data;
53
54 /* keybindings */
55 enum
56 {
57 KB_DEVHELP_TOGGLE_CONTENTS,
58 KB_DEVHELP_TOGGLE_SEARCH,
59 KB_DEVHELP_TOGGLE_WEBVIEW,
60 KB_DEVHELP_ACTIVATE_DEVHELP,
61 KB_DEVHELP_SEARCH_SYMBOL,
62 KB_DEVHELP_SEARCH_MANPAGES,
63 KB_COUNT
64 };
65
66 /* Called when a keybinding is activated */
kb_activate(guint key_id)67 static void kb_activate(guint key_id)
68 {
69 gchar *current_tag;
70
71 switch (key_id)
72 {
73 case KB_DEVHELP_TOGGLE_CONTENTS:
74 devhelp_plugin_toggle_contents_tab(plugin_data.devhelp);
75 break;
76 case KB_DEVHELP_TOGGLE_SEARCH:
77 devhelp_plugin_toggle_search_tab(plugin_data.devhelp);
78 break;
79 case KB_DEVHELP_TOGGLE_WEBVIEW: /* not working */
80 devhelp_plugin_toggle_webview_tab(plugin_data.devhelp);
81 break;
82 case KB_DEVHELP_ACTIVATE_DEVHELP:
83 devhelp_plugin_activate_all_tabs(plugin_data.devhelp);
84 break;
85 case KB_DEVHELP_SEARCH_SYMBOL:
86 {
87 current_tag = devhelp_plugin_get_current_word(plugin_data.devhelp);
88 if (current_tag == NULL)
89 return;
90 devhelp_plugin_search_books(plugin_data.devhelp, current_tag);
91 g_free(current_tag);
92 break;
93 }
94 case KB_DEVHELP_SEARCH_MANPAGES:
95 {
96 current_tag = devhelp_plugin_get_current_word(plugin_data.devhelp);
97 if (current_tag == NULL)
98 return;
99 devhelp_plugin_search_manpages(plugin_data.devhelp, current_tag);
100 g_free(current_tag);
101 break;
102 }
103 }
104 }
105
106
plugin_config_init(struct PluginData * pd)107 gboolean plugin_config_init(struct PluginData *pd)
108 {
109 gchar *user_config_dir;
110
111 g_return_val_if_fail(pd != NULL, FALSE);
112
113 plugin_data.default_config = g_build_path(G_DIR_SEPARATOR_S, DHPLUG_DATA_DIR, "devhelp.conf", NULL);
114
115 user_config_dir = g_build_path(G_DIR_SEPARATOR_S, geany_data->app->configdir, "plugins", "devhelp", NULL);
116 plugin_data.user_config = g_build_path(G_DIR_SEPARATOR_S, user_config_dir, "devhelp.conf", NULL);
117 if (g_mkdir_with_parents(user_config_dir, S_IRUSR | S_IWUSR | S_IXUSR) != 0)
118 {
119 g_warning(_("Unable to create config dir at '%s'"), user_config_dir);
120 g_free(user_config_dir);
121 return FALSE;
122 }
123 g_free(user_config_dir);
124
125 /* copy default config into user config if it doesn't exist */
126 if (!g_file_test(pd->user_config, G_FILE_TEST_EXISTS))
127 {
128 gchar *config_text;
129 GError *error;
130
131 error = NULL;
132 if (!g_file_get_contents(pd->default_config, &config_text, NULL, &error))
133 {
134 g_warning(_("Unable to get default configuration: %s"), error->message);
135 g_error_free(error);
136 return FALSE;
137 }
138 else
139 {
140 if (!g_file_set_contents(pd->user_config, config_text, -1, &error))
141 {
142 g_warning(_("Unable to write default configuration: %s"), error->message);
143 g_error_free(error);
144 return FALSE;
145 }
146 }
147 }
148
149 return TRUE;
150 }
151
152
plugin_devhelp_init(GeanyPlugin * plugin,G_GNUC_UNUSED gpointer pdata)153 static gboolean plugin_devhelp_init(GeanyPlugin *plugin, G_GNUC_UNUSED gpointer pdata)
154 {
155 GeanyKeyGroup *key_group;
156
157 geany_plugin = plugin;
158 geany_data = plugin->geany_data;
159
160 plugin_module_make_resident(geany_plugin);
161
162 if (!g_thread_supported())
163 g_thread_init(NULL);
164
165 memset(&plugin_data, 0, sizeof(struct PluginData));
166
167 plugin_data.devhelp = devhelp_plugin_new();
168 plugin_config_init(&plugin_data);
169
170 devhelp_plugin_load_settings(plugin_data.devhelp, plugin_data.user_config);
171
172 key_group = plugin_set_key_group(geany_plugin, "devhelp", KB_COUNT, NULL);
173
174 keybindings_set_item(key_group, KB_DEVHELP_TOGGLE_CONTENTS, kb_activate,
175 0, 0, "devhelp_toggle_contents", _("Toggle sidebar contents tab"), NULL);
176 keybindings_set_item(key_group, KB_DEVHELP_TOGGLE_SEARCH, kb_activate,
177 0, 0, "devhelp_toggle_search", _("Toggle sidebar search tab"), NULL);
178 keybindings_set_item(key_group, KB_DEVHELP_TOGGLE_WEBVIEW, kb_activate,
179 0, 0, "devhelp_toggle_webview", _("Toggle documentation tab"), NULL);
180 keybindings_set_item(key_group, KB_DEVHELP_ACTIVATE_DEVHELP, kb_activate,
181 0, 0, "devhelp_activate_all", _("Activate all tabs"), NULL);
182 keybindings_set_item(key_group, KB_DEVHELP_SEARCH_SYMBOL, kb_activate,
183 0, 0, "devhelp_search_symbol", _("Search for current tag in Devhelp"), NULL);
184 if (devhelp_plugin_get_have_man_prog(plugin_data.devhelp))
185 {
186 keybindings_set_item(key_group, KB_DEVHELP_SEARCH_MANPAGES, kb_activate,
187 0, 0, "devhelp_search_manpages", _("Search for current tag in Manual Pages"), NULL);
188 }
189
190 return TRUE;
191 }
192
193
plugin_devhelp_cleanup(G_GNUC_UNUSED GeanyPlugin * plugin,G_GNUC_UNUSED gpointer pdata)194 static void plugin_devhelp_cleanup(G_GNUC_UNUSED GeanyPlugin *plugin, G_GNUC_UNUSED gpointer pdata)
195 {
196 devhelp_plugin_store_settings(plugin_data.devhelp, plugin_data.user_config);
197 g_object_unref(plugin_data.devhelp);
198 g_free(plugin_data.default_config);
199 g_free(plugin_data.user_config);
200 }
201
202
plugin_devhelp_help(G_GNUC_UNUSED GeanyPlugin * plugin,G_GNUC_UNUSED gpointer pdata)203 static void plugin_devhelp_help (G_GNUC_UNUSED GeanyPlugin *plugin, G_GNUC_UNUSED gpointer pdata)
204 {
205 utils_open_browser("https://plugins.geany.org/devhelp.html");
206 }
207
208
209 /* Load module */
210 G_MODULE_EXPORT
geany_load_module(GeanyPlugin * plugin)211 void geany_load_module(GeanyPlugin *plugin)
212 {
213 /* Setup translation */
214 main_locale_init(LOCALEDIR, GETTEXT_PACKAGE);
215
216 /* Set metadata */
217 plugin->info->name = _("Devhelp Plugin");
218 plugin->info->description = _("Adds support for looking up documentation in Devhelp, manual pages, and "
219 "Google Code Search in the integrated viewer.");
220 plugin->info->version = "1.0";
221 plugin->info->author = "Matthew Brush <mbrush@leftclick.ca>";
222
223 /* Set functions */
224 plugin->funcs->init = plugin_devhelp_init;
225 plugin->funcs->cleanup = plugin_devhelp_cleanup;
226 plugin->funcs->help = plugin_devhelp_help;
227
228 /* Register! */
229 GEANY_PLUGIN_REGISTER(plugin, 226);
230 }
231