1 /*
2  *      addons.c - this file is part of Addons, a Geany plugin
3  *
4  *      Copyright 2009-2011 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
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 2 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  * $Id$
22  */
23 
24 
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28 
29 #include <geanyplugin.h>
30 
31 #include "addons.h"
32 #include "ao_blanklines.h"
33 #include "ao_doclist.h"
34 #include "ao_openuri.h"
35 #include "ao_systray.h"
36 #include "ao_bookmarklist.h"
37 #include "ao_markword.h"
38 #include "ao_tasks.h"
39 #include "ao_xmltagging.h"
40 #include "ao_wrapwords.h"
41 #include "ao_copyfilepath.h"
42 #include "ao_colortip.h"
43 
44 
45 GeanyPlugin		*geany_plugin = NULL;
46 GeanyData		*geany_data = NULL;
47 
48 
49 /* Keybinding(s) */
50 enum
51 {
52 	KB_FOCUS_BOOKMARK_LIST,
53 	KB_FOCUS_TASKS,
54 	KB_UPDATE_TASKS,
55 	KB_XMLTAGGING,
56 	KB_COPYFILEPATH,
57 	KB_COUNT
58 };
59 
60 
61 typedef struct
62 {
63 	/* general settings */
64 	gchar *config_file;
65 	gboolean enable_doclist;
66 	gboolean enable_openuri;
67 	gboolean enable_tasks;
68 	gboolean enable_systray;
69 	gboolean enable_bookmarklist;
70 	gboolean enable_markword;
71 	gboolean enable_markword_single_click_deselect;
72 	gboolean enable_xmltagging;
73 	gboolean enable_enclose_words;
74 	gboolean enable_enclose_words_auto;
75 	gboolean strip_trailing_blank_lines;
76 	gboolean enable_colortip;
77 	gboolean enable_double_click_color_chooser;
78 
79 	gchar *tasks_token_list;
80 	gboolean tasks_scan_all_documents;
81 
82 	DocListSortMode doclist_sort_mode;
83 
84 	/* instances and variables of components */
85 	AoDocList *doclist;
86 	AoOpenUri *openuri;
87 	AoSystray *systray;
88 	AoBookmarkList *bookmarklist;
89 	AoMarkWord *markword;
90 	AoTasks *tasks;
91 	AoCopyFilePath *copyfilepath;
92 	AoColorTip *colortip;
93 } AddonsInfo;
94 static AddonsInfo *ao_info = NULL;
95 
96 
ao_startup_complete_cb(GObject * obj,gpointer data)97 static void ao_startup_complete_cb(GObject *obj, gpointer data)
98 {
99 	ao_tasks_set_active(ao_info->tasks);
100 }
101 
102 
kb_bmlist_activate(guint key_id)103 static void kb_bmlist_activate(guint key_id)
104 {
105 	ao_bookmark_list_activate(ao_info->bookmarklist);
106 }
107 
108 
kb_tasks_activate(guint key_id)109 static void kb_tasks_activate(guint key_id)
110 {
111 	ao_tasks_activate(ao_info->tasks);
112 }
113 
114 
kb_tasks_update(guint key_id)115 static void kb_tasks_update(guint key_id)
116 {
117 	ao_tasks_update(ao_info->tasks, NULL);
118 }
119 
120 
kb_ao_xmltagging(guint key_id)121 static void kb_ao_xmltagging(guint key_id)
122 {
123 	if (ao_info->enable_xmltagging == TRUE)
124 	{
125 		ao_xmltagging();
126 	}
127 }
128 
129 
kb_ao_copyfilepath(guint key_id)130 static void kb_ao_copyfilepath(guint key_id)
131 {
132 	ao_copy_file_path_copy(ao_info->copyfilepath);
133 }
134 
135 
ao_editor_notify_cb(GObject * object,GeanyEditor * editor,SCNotification * nt,gpointer data)136 static gboolean ao_editor_notify_cb(GObject *object, GeanyEditor *editor,
137 							 SCNotification *nt, gpointer data)
138 {
139 	ao_bookmark_list_update_marker(ao_info->bookmarklist, editor, nt);
140 
141 	ao_mark_editor_notify(ao_info->markword, editor, nt);
142 
143 	ao_color_tip_editor_notify(ao_info->colortip, editor, nt);
144 
145 	return FALSE;
146 }
147 
148 
ao_update_editor_menu_cb(GObject * obj,const gchar * word,gint pos,GeanyDocument * doc,gpointer data)149 static void ao_update_editor_menu_cb(GObject *obj, const gchar *word, gint pos,
150 									 GeanyDocument *doc, gpointer data)
151 {
152 	g_return_if_fail(doc != NULL && doc->is_valid);
153 
154 	ao_open_uri_update_menu(ao_info->openuri, doc, pos);
155 }
156 
157 
ao_document_activate_cb(GObject * obj,GeanyDocument * doc,gpointer data)158 static void ao_document_activate_cb(GObject *obj, GeanyDocument *doc, gpointer data)
159 {
160 	g_return_if_fail(doc != NULL && doc->is_valid);
161 
162 	ao_bookmark_list_update(ao_info->bookmarklist, doc);
163 	ao_tasks_update_single(ao_info->tasks, doc);
164 }
165 
166 
ao_document_new_cb(GObject * obj,GeanyDocument * doc,gpointer data)167 static void ao_document_new_cb(GObject *obj, GeanyDocument *doc, gpointer data)
168 {
169 	g_return_if_fail(doc != NULL && doc->is_valid);
170 
171 	ao_mark_document_new(ao_info->markword, doc);
172 	ao_color_tip_document_new(ao_info->colortip, doc);
173 }
174 
175 
ao_document_open_cb(GObject * obj,GeanyDocument * doc,gpointer data)176 static void ao_document_open_cb(GObject *obj, GeanyDocument *doc, gpointer data)
177 {
178 	g_return_if_fail(doc != NULL && doc->is_valid);
179 
180 	ao_tasks_update(ao_info->tasks, doc);
181 	ao_mark_document_open(ao_info->markword, doc);
182 	ao_color_tip_document_open(ao_info->colortip, doc);
183 }
184 
185 
ao_document_close_cb(GObject * obj,GeanyDocument * doc,gpointer data)186 static void ao_document_close_cb(GObject *obj, GeanyDocument *doc, gpointer data)
187 {
188 	g_return_if_fail(doc != NULL && doc->is_valid);
189 
190 	ao_tasks_remove(ao_info->tasks, doc);
191 	ao_mark_document_close(ao_info->markword, doc);
192 	ao_color_tip_document_close(ao_info->colortip, doc);
193 }
194 
195 
ao_document_save_cb(GObject * obj,GeanyDocument * doc,gpointer data)196 static void ao_document_save_cb(GObject *obj, GeanyDocument *doc, gpointer data)
197 {
198 	g_return_if_fail(doc != NULL && doc->is_valid);
199 
200 	ao_tasks_update(ao_info->tasks, doc);
201 }
202 
203 
ao_document_before_save_cb(GObject * obj,GeanyDocument * doc,gpointer data)204 static void ao_document_before_save_cb(GObject *obj, GeanyDocument *doc, gpointer data)
205 {
206 	g_return_if_fail(doc != NULL && doc->is_valid);
207 
208 	ao_blanklines_on_document_before_save(obj, doc, data);
209 }
210 
211 
ao_document_reload_cb(GObject * obj,GeanyDocument * doc,gpointer data)212 static void ao_document_reload_cb(GObject *obj, GeanyDocument *doc, gpointer data)
213 {
214 	g_return_if_fail(doc != NULL && doc->is_valid);
215 
216 	ao_tasks_update(ao_info->tasks, doc);
217 }
218 
219 
ao_image_menu_item_new(const gchar * stock_id,const gchar * label)220 GtkWidget *ao_image_menu_item_new(const gchar *stock_id, const gchar *label)
221 {
222 	GtkWidget *item = gtk_image_menu_item_new_with_label(label);
223 	GtkWidget *image = gtk_image_new_from_icon_name(stock_id, GTK_ICON_SIZE_MENU);
224 
225 	gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
226 	gtk_widget_show(image);
227 	return item;
228 }
229 
230 
ao_configure_tasks_toggled_cb(GtkToggleButton * togglebutton,gpointer data)231 static void ao_configure_tasks_toggled_cb(GtkToggleButton *togglebutton, gpointer data)
232 {
233 	gboolean sens = gtk_toggle_button_get_active(togglebutton);
234 
235 	gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(data), "check_tasks_scan_mode"), sens);
236 	gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(data), "entry_tasks_tokens"), sens);
237 }
238 
239 
ao_configure_markword_toggled_cb(GtkToggleButton * togglebutton,gpointer data)240 static void ao_configure_markword_toggled_cb(GtkToggleButton *togglebutton, gpointer data)
241 {
242 	gboolean sens = gtk_toggle_button_get_active(togglebutton);
243 
244 	gtk_widget_set_sensitive(g_object_get_data(
245 		G_OBJECT(data), "check_markword_single_click_deselect"), sens);
246 }
247 
248 
ao_configure_doclist_toggled_cb(GtkToggleButton * togglebutton,gpointer data)249 static void ao_configure_doclist_toggled_cb(GtkToggleButton *togglebutton, gpointer data)
250 {
251 	gboolean sens = gtk_toggle_button_get_active(togglebutton);
252 
253 	gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(data),
254 		"radio_doclist_name"), sens);
255 	gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(data),
256 		"radio_doclist_tab_order"), sens);
257 	gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(data),
258 		"radio_doclist_tab_order_reversed"), sens);
259 }
260 
261 
ao_configure_response_cb(GtkDialog * dialog,gint response,gpointer user_data)262 static void ao_configure_response_cb(GtkDialog *dialog, gint response, gpointer user_data)
263 {
264 	if (response == GTK_RESPONSE_OK || response == GTK_RESPONSE_APPLY)
265 	{
266 		GKeyFile *config = g_key_file_new();
267 		gchar *data;
268 		gchar *config_dir = g_path_get_dirname(ao_info->config_file);
269 
270 		ao_info->enable_doclist = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
271 			g_object_get_data(G_OBJECT(dialog), "check_doclist"))));
272 		if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(g_object_get_data(
273 				G_OBJECT(dialog), "radio_doclist_name"))))
274 			ao_info->doclist_sort_mode = DOCLIST_SORT_BY_NAME;
275 		else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(g_object_get_data(
276 				G_OBJECT(dialog), "radio_doclist_tab_order_reversed"))))
277 			ao_info->doclist_sort_mode = DOCLIST_SORT_BY_TAB_ORDER_REVERSE;
278 		else
279 			ao_info->doclist_sort_mode = DOCLIST_SORT_BY_TAB_ORDER;
280 
281 		ao_info->enable_openuri = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
282 			g_object_get_data(G_OBJECT(dialog), "check_openuri"))));
283 		ao_info->enable_tasks = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
284 			g_object_get_data(G_OBJECT(dialog), "check_tasks"))));
285 		ao_info->tasks_scan_all_documents = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
286 			g_object_get_data(G_OBJECT(dialog), "check_tasks_scan_mode"))));
287 		g_free(ao_info->tasks_token_list);
288 		ao_info->tasks_token_list = g_strdup(gtk_entry_get_text(GTK_ENTRY(
289 			g_object_get_data(G_OBJECT(dialog), "entry_tasks_tokens"))));
290 		ao_info->enable_systray = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
291 			g_object_get_data(G_OBJECT(dialog), "check_systray"))));
292 		ao_info->enable_bookmarklist = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
293 			g_object_get_data(G_OBJECT(dialog), "check_bookmarklist"))));
294 		ao_info->enable_markword = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
295 			g_object_get_data(G_OBJECT(dialog), "check_markword"))));
296 		ao_info->enable_markword_single_click_deselect = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
297 			g_object_get_data(G_OBJECT(dialog), "check_markword_single_click_deselect"))));
298 		ao_info->strip_trailing_blank_lines = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
299 			g_object_get_data(G_OBJECT(dialog), "check_blanklines"))));
300 		ao_info->enable_xmltagging = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
301 			g_object_get_data(G_OBJECT(dialog), "check_xmltagging"))));
302 		ao_info->enable_enclose_words = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
303 			g_object_get_data(G_OBJECT(dialog), "check_enclose_words"))));
304 		ao_info->enable_enclose_words_auto = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
305 			g_object_get_data(G_OBJECT(dialog), "check_enclose_words_auto"))));
306 		ao_info->enable_colortip = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
307 			g_object_get_data(G_OBJECT(dialog), "check_colortip"))));
308 		ao_info->enable_double_click_color_chooser = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
309 			g_object_get_data(G_OBJECT(dialog), "check_double_click_color_chooser"))));
310 
311 		ao_enclose_words_set_enabled (ao_info->enable_enclose_words, ao_info->enable_enclose_words_auto);
312 
313 		g_key_file_load_from_file(config, ao_info->config_file, G_KEY_FILE_NONE, NULL);
314 		g_key_file_set_boolean(config, "addons",
315 			"show_toolbar_doclist_item", ao_info->enable_doclist);
316 		g_key_file_set_integer(config, "addons", "doclist_sort_mode", ao_info->doclist_sort_mode);
317 		g_key_file_set_boolean(config, "addons", "enable_openuri", ao_info->enable_openuri);
318 		g_key_file_set_boolean(config, "addons", "enable_tasks", ao_info->enable_tasks);
319 		g_key_file_set_string(config, "addons", "tasks_token_list", ao_info->tasks_token_list);
320 		g_key_file_set_boolean(config, "addons", "tasks_scan_all_documents",
321 			ao_info->tasks_scan_all_documents);
322 		g_key_file_set_boolean(config, "addons", "enable_systray", ao_info->enable_systray);
323 		g_key_file_set_boolean(config, "addons", "enable_bookmarklist",
324 			ao_info->enable_bookmarklist);
325 		g_key_file_set_boolean(config, "addons", "enable_markword", ao_info->enable_markword);
326 		g_key_file_set_boolean(config, "addons", "enable_markword_single_click_deselect",
327 			ao_info->enable_markword_single_click_deselect);
328 		g_key_file_set_boolean(config, "addons", "strip_trailing_blank_lines",
329 		  ao_info->strip_trailing_blank_lines);
330 		g_key_file_set_boolean(config, "addons", "enable_xmltagging",
331 			ao_info->enable_xmltagging);
332 		g_key_file_set_boolean(config, "addons", "enable_enclose_words",
333 			ao_info->enable_enclose_words);
334 		g_key_file_set_boolean(config, "addons", "enable_enclose_words_auto",
335 			ao_info->enable_enclose_words_auto);
336 		g_key_file_set_boolean(config, "addons", "enable_colortip", ao_info->enable_colortip);
337 		g_key_file_set_boolean(config, "addons", "enable_double_click_color_chooser",
338 			ao_info->enable_double_click_color_chooser);
339 
340 		g_object_set(ao_info->doclist, "enable-doclist", ao_info->enable_doclist, NULL);
341 		g_object_set(ao_info->doclist, "sort-mode", ao_info->doclist_sort_mode, NULL);
342 		g_object_set(ao_info->openuri, "enable-openuri", ao_info->enable_openuri, NULL);
343 		g_object_set(ao_info->systray, "enable-systray", ao_info->enable_systray, NULL);
344 		g_object_set(ao_info->bookmarklist, "enable-bookmarklist",
345 			ao_info->enable_bookmarklist, NULL);
346 		g_object_set(ao_info->markword,
347 			"enable-markword", ao_info->enable_markword,
348 			"enable-single-click-deselect", ao_info->enable_markword_single_click_deselect,
349 			NULL);
350 		g_object_set(ao_info->tasks,
351 			"enable-tasks", ao_info->enable_tasks,
352 			"scan-all-documents", ao_info->tasks_scan_all_documents,
353 			"tokens", ao_info->tasks_token_list,
354 			NULL);
355 		ao_blanklines_set_enable(ao_info->strip_trailing_blank_lines);
356 		g_object_set(ao_info->colortip,
357 			"enable-colortip", ao_info->enable_colortip,
358 			"enable-double-click-color-chooser", ao_info->enable_double_click_color_chooser,
359 			NULL);
360 
361 		if (! g_file_test(config_dir, G_FILE_TEST_IS_DIR) && utils_mkdir(config_dir, TRUE) != 0)
362 		{
363 			dialogs_show_msgbox(GTK_MESSAGE_ERROR,
364 				_("Plugin configuration directory could not be created."));
365 		}
366 		else
367 		{
368 			/* write config to file */
369 			data = g_key_file_to_data(config, NULL, NULL);
370 			utils_write_file(ao_info->config_file, data);
371 			g_free(data);
372 		}
373 		g_free(config_dir);
374 		g_key_file_free(config);
375 	}
376 }
377 
378 
379 /* Initialization */
plugin_addons_init(GeanyPlugin * plugin,G_GNUC_UNUSED gpointer pdata)380 static gboolean plugin_addons_init(GeanyPlugin *plugin, G_GNUC_UNUSED gpointer pdata)
381 {
382 	GKeyFile *config = g_key_file_new();
383 	GtkWidget *ao_copy_file_path_menu_item;
384 	GeanyKeyGroup *key_group;
385 
386 	geany_plugin = plugin;
387 	geany_data = plugin->geany_data;
388 
389 	ao_info = g_new0(AddonsInfo, 1);
390 
391 	ao_info->config_file = g_strconcat(geany->app->configdir, G_DIR_SEPARATOR_S,
392 		"plugins", G_DIR_SEPARATOR_S, "addons", G_DIR_SEPARATOR_S, "addons.conf", NULL);
393 
394 	g_key_file_load_from_file(config, ao_info->config_file, G_KEY_FILE_NONE, NULL);
395 	ao_info->enable_doclist = utils_get_setting_boolean(config,
396 		"addons", "show_toolbar_doclist_item", TRUE);
397 	ao_info->doclist_sort_mode = utils_get_setting_integer(config,
398 		"addons", "doclist_sort_mode", DOCLIST_SORT_BY_TAB_ORDER);
399 	ao_info->enable_openuri = utils_get_setting_boolean(config,
400 		"addons", "enable_openuri", FALSE);
401 	ao_info->enable_tasks = utils_get_setting_boolean(config,
402 		"addons", "enable_tasks", TRUE);
403 	ao_info->tasks_scan_all_documents = utils_get_setting_boolean(config,
404 		"addons", "tasks_scan_all_documents", FALSE);
405 	ao_info->tasks_token_list = utils_get_setting_string(config,
406 		"addons", "tasks_token_list", "TODO;FIXME");
407 	ao_info->enable_systray = utils_get_setting_boolean(config,
408 		"addons", "enable_systray", FALSE);
409 	ao_info->enable_bookmarklist = utils_get_setting_boolean(config,
410 		"addons", "enable_bookmarklist", FALSE);
411 	ao_info->enable_markword = utils_get_setting_boolean(config,
412 		"addons", "enable_markword", FALSE);
413 	ao_info->enable_markword_single_click_deselect = utils_get_setting_boolean(config,
414 		"addons", "enable_markword_single_click_deselect", FALSE);
415 	ao_info->strip_trailing_blank_lines = utils_get_setting_boolean(config,
416 		"addons", "strip_trailing_blank_lines", FALSE);
417 	ao_info->enable_xmltagging = utils_get_setting_boolean(config, "addons",
418 		"enable_xmltagging", FALSE);
419 	ao_info->enable_enclose_words = utils_get_setting_boolean(config, "addons",
420 		"enable_enclose_words", FALSE);
421 	ao_info->enable_enclose_words_auto = utils_get_setting_boolean(config, "addons",
422 		"enable_enclose_words_auto", FALSE);
423 	ao_info->enable_colortip = utils_get_setting_boolean(config,
424 		"addons", "enable_colortip", FALSE);
425 	ao_info->enable_double_click_color_chooser = utils_get_setting_boolean(config,
426 		"addons", "enable_double_click_color_chooser", FALSE);
427 
428 	plugin_module_make_resident(geany_plugin);
429 
430 	ao_info->doclist = ao_doc_list_new(ao_info->enable_doclist, ao_info->doclist_sort_mode);
431 	ao_info->openuri = ao_open_uri_new(ao_info->enable_openuri);
432 	ao_info->systray = ao_systray_new(ao_info->enable_systray);
433 	ao_info->bookmarklist = ao_bookmark_list_new(ao_info->enable_bookmarklist);
434 	ao_info->markword = ao_mark_word_new(ao_info->enable_markword,
435 		ao_info->enable_markword_single_click_deselect);
436 	ao_info->tasks = ao_tasks_new(ao_info->enable_tasks,
437 						ao_info->tasks_token_list, ao_info->tasks_scan_all_documents);
438 	ao_info->copyfilepath = ao_copy_file_path_new();
439 	ao_info->colortip = ao_color_tip_new(ao_info->enable_colortip,
440 		ao_info->enable_double_click_color_chooser);
441 
442 	ao_blanklines_set_enable(ao_info->strip_trailing_blank_lines);
443 
444 	/* setup keybindings */
445 	key_group = plugin_set_key_group(geany_plugin, "addons", KB_COUNT + AO_WORDWRAP_KB_COUNT, NULL);
446 	keybindings_set_item(key_group, KB_FOCUS_BOOKMARK_LIST, kb_bmlist_activate,
447 		0, 0, "focus_bookmark_list", _("Focus Bookmark List"), NULL);
448 	keybindings_set_item(key_group, KB_FOCUS_TASKS, kb_tasks_activate,
449 		0, 0, "focus_tasks", _("Focus Tasks List"), NULL);
450 	keybindings_set_item(key_group, KB_UPDATE_TASKS, kb_tasks_update,
451 		0, 0, "update_tasks", _("Update Tasks List"), NULL);
452 	keybindings_set_item(key_group, KB_XMLTAGGING, kb_ao_xmltagging,
453 		0, 0, "xml_tagging", _("Run XML tagging"), NULL);
454 	ao_copy_file_path_menu_item = ao_copy_file_path_get_menu_item(ao_info->copyfilepath);
455 	keybindings_set_item(key_group, KB_COPYFILEPATH, kb_ao_copyfilepath,
456 		0, 0, "copy_file_path", _("Copy File Path"), ao_copy_file_path_menu_item);
457 
458 	ao_enclose_words_init(ao_info->config_file, key_group, KB_COUNT);
459 	ao_enclose_words_set_enabled (ao_info->enable_enclose_words, ao_info->enable_enclose_words_auto);
460 
461 	g_key_file_free(config);
462 
463 	return TRUE;
464 }
465 
466 
467 /* Configuration */
plugin_addons_configure(G_GNUC_UNUSED GeanyPlugin * plugin,GtkDialog * dialog,G_GNUC_UNUSED gpointer pdata)468 static GtkWidget *plugin_addons_configure(G_GNUC_UNUSED GeanyPlugin *plugin, GtkDialog *dialog, G_GNUC_UNUSED gpointer pdata)
469 {
470 	GtkWidget *vbox, *check_openuri, *check_tasks, *check_systray;
471 	GtkWidget *check_doclist, *vbox_doclist, *frame_doclist;
472 	GtkWidget *radio_doclist_name, *radio_doclist_tab_order, *radio_doclist_tab_order_reversed;
473 	GtkWidget *check_bookmarklist, *check_markword, *check_markword_single_click_deselect;
474 	GtkWidget *frame_markword, *frame_tasks, *vbox_tasks;
475 	GtkWidget *check_tasks_scan_mode, *entry_tasks_tokens, *label_tasks_tokens, *tokens_hbox;
476 	GtkWidget *check_blanklines, *check_xmltagging;
477 	GtkWidget *check_enclose_words, *check_enclose_words_auto, *enclose_words_config_button, *enclose_words_hbox;
478 	GtkWidget *check_colortip, *check_double_click_color_chooser;
479 
480 	vbox = gtk_vbox_new(FALSE, 6);
481 
482 	check_doclist = gtk_check_button_new_with_label(
483 		_("Show toolbar item to show a list of currently open documents"));
484 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_doclist), ao_info->enable_doclist);
485 	g_signal_connect(check_doclist, "toggled", G_CALLBACK(ao_configure_doclist_toggled_cb), dialog);
486 
487 	radio_doclist_name = gtk_radio_button_new_with_mnemonic(NULL, _("Sort documents by _name"));
488 	gtk_widget_set_tooltip_text(radio_doclist_name,
489 		_("Sort the documents in the list by their filename"));
490 
491 	radio_doclist_tab_order = gtk_radio_button_new_with_mnemonic_from_widget(
492 		GTK_RADIO_BUTTON(radio_doclist_name), _("Sort documents by _occurrence"));
493 	gtk_widget_set_tooltip_text(radio_doclist_tab_order,
494 		_("Sort the documents in the order of the document tabs"));
495 
496 	radio_doclist_tab_order_reversed = gtk_radio_button_new_with_mnemonic_from_widget(
497 		GTK_RADIO_BUTTON(radio_doclist_name), _("Sort documents by _occurrence (reversed)"));
498 	gtk_widget_set_tooltip_text(radio_doclist_tab_order_reversed,
499 		_("Sort the documents in the order of the document tabs (reversed)"));
500 
501 	switch (ao_info->doclist_sort_mode)
502 	{
503 		case DOCLIST_SORT_BY_NAME:
504 			gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_doclist_name), TRUE);
505 			break;
506 		case DOCLIST_SORT_BY_TAB_ORDER_REVERSE:
507 			gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_doclist_tab_order_reversed), TRUE);
508 			break;
509 		case DOCLIST_SORT_BY_TAB_ORDER:
510 		default:
511 			gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_doclist_tab_order), TRUE);
512 			break;
513 	}
514 
515 	vbox_doclist = gtk_vbox_new(FALSE, 0);
516 	gtk_box_pack_start(GTK_BOX(vbox_doclist), radio_doclist_name, FALSE, FALSE, 3);
517 	gtk_box_pack_start(GTK_BOX(vbox_doclist), radio_doclist_tab_order, TRUE, TRUE, 3);
518 	gtk_box_pack_start(GTK_BOX(vbox_doclist), radio_doclist_tab_order_reversed, TRUE, TRUE, 3);
519 
520 	frame_doclist = gtk_frame_new(NULL);
521 	gtk_frame_set_label_widget(GTK_FRAME(frame_doclist), check_doclist);
522 	gtk_container_add(GTK_CONTAINER(frame_doclist), vbox_doclist);
523 	gtk_box_pack_start(GTK_BOX(vbox), frame_doclist, FALSE, FALSE, 3);
524 
525 	check_openuri = gtk_check_button_new_with_label(
526 		_("Show an 'Open URI' item in the editor menu"));
527 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_openuri),
528 		ao_info->enable_openuri);
529 	gtk_box_pack_start(GTK_BOX(vbox), check_openuri, FALSE, FALSE, 3);
530 
531 	check_tasks = gtk_check_button_new_with_label(
532 		_("Show available Tasks in the Messages Window"));
533 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_tasks),
534 		ao_info->enable_tasks);
535 	g_signal_connect(check_tasks, "toggled", G_CALLBACK(ao_configure_tasks_toggled_cb), dialog);
536 
537 	check_tasks_scan_mode = gtk_check_button_new_with_label(
538 		_("Show tasks of all documents"));
539 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_tasks_scan_mode),
540 		ao_info->tasks_scan_all_documents);
541 	gtk_widget_set_tooltip_text(check_tasks_scan_mode,
542 		_("Whether to show the tasks of all open documents in the list or only those of the current document."));
543 
544 	entry_tasks_tokens = gtk_entry_new();
545 	if (!EMPTY(ao_info->tasks_token_list))
546 		gtk_entry_set_text(GTK_ENTRY(entry_tasks_tokens), ao_info->tasks_token_list);
547 	ui_entry_add_clear_icon(GTK_ENTRY(entry_tasks_tokens));
548 	gtk_widget_set_tooltip_text(entry_tasks_tokens,
549 		_("Specify a semicolon separated list of search tokens."));
550 
551 	label_tasks_tokens = gtk_label_new_with_mnemonic(_("Search tokens:"));
552 	gtk_label_set_mnemonic_widget(GTK_LABEL(label_tasks_tokens), entry_tasks_tokens);
553 
554 	tokens_hbox = gtk_hbox_new(FALSE, 0);
555 	gtk_box_pack_start(GTK_BOX(tokens_hbox), label_tasks_tokens, FALSE, FALSE, 3);
556 	gtk_box_pack_start(GTK_BOX(tokens_hbox), entry_tasks_tokens, TRUE, TRUE, 3);
557 
558 	vbox_tasks = gtk_vbox_new(FALSE, 0);
559 	gtk_box_pack_start(GTK_BOX(vbox_tasks), check_tasks_scan_mode, FALSE, FALSE, 3);
560 	gtk_box_pack_start(GTK_BOX(vbox_tasks), tokens_hbox, TRUE, TRUE, 3);
561 
562 	frame_tasks = gtk_frame_new(NULL);
563 	gtk_frame_set_label_widget(GTK_FRAME(frame_tasks), check_tasks);
564 	gtk_container_add(GTK_CONTAINER(frame_tasks), vbox_tasks);
565 	gtk_box_pack_start(GTK_BOX(vbox), frame_tasks, FALSE, FALSE, 3);
566 
567 	check_systray = gtk_check_button_new_with_label(
568 		_("Show status icon in the Notification Area"));
569 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_systray),
570 		ao_info->enable_systray);
571 	gtk_box_pack_start(GTK_BOX(vbox), check_systray, FALSE, FALSE, 3);
572 
573 	check_bookmarklist = gtk_check_button_new_with_label(
574 		_("Show defined bookmarks (marked lines) in the sidebar"));
575 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_bookmarklist),
576 		ao_info->enable_bookmarklist);
577 	gtk_box_pack_start(GTK_BOX(vbox), check_bookmarklist, FALSE, FALSE, 3);
578 
579 	check_markword = gtk_check_button_new_with_label(
580 		_("Mark all occurrences of a word when double-clicking it"));
581 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_markword),
582 		ao_info->enable_markword);
583 	g_signal_connect(check_markword, "toggled", G_CALLBACK(ao_configure_markword_toggled_cb), dialog);
584 
585 	check_markword_single_click_deselect = gtk_check_button_new_with_label(
586 		_("Deselect a previous highlight by single click"));
587 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_markword_single_click_deselect),
588 		ao_info->enable_markword_single_click_deselect);
589 
590 	frame_markword = gtk_frame_new(NULL);
591 	gtk_frame_set_label_widget(GTK_FRAME(frame_markword), check_markword);
592 	gtk_container_add(GTK_CONTAINER(frame_markword), check_markword_single_click_deselect);
593 	gtk_box_pack_start(GTK_BOX(vbox), frame_markword, FALSE, FALSE, 3);
594 
595 	check_blanklines = gtk_check_button_new_with_label(
596 		_("Strip trailing blank lines"));
597 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_blanklines),
598 		ao_info->strip_trailing_blank_lines);
599 	gtk_box_pack_start(GTK_BOX(vbox), check_blanklines, FALSE, FALSE, 3);
600 
601 	check_xmltagging = gtk_check_button_new_with_label(
602 		_("XML tagging for selection"));
603 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_xmltagging),
604 		ao_info->enable_xmltagging);
605 	gtk_box_pack_start(GTK_BOX(vbox), check_xmltagging, FALSE, FALSE, 3);
606 
607 	check_enclose_words = gtk_check_button_new_with_label(
608 		_("Enclose selection on configurable keybindings"));
609 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_enclose_words),
610 		ao_info->enable_enclose_words);
611 
612 	enclose_words_config_button = gtk_button_new_with_label (_("Configure enclose pairs"));
613 	g_signal_connect(enclose_words_config_button, "clicked", G_CALLBACK(ao_enclose_words_config), dialog);
614 	enclose_words_hbox = gtk_hbox_new(FALSE, 0);
615 	gtk_box_pack_start(GTK_BOX(enclose_words_hbox), check_enclose_words, FALSE, FALSE, 3);
616 	gtk_box_pack_start(GTK_BOX(enclose_words_hbox), enclose_words_config_button, TRUE, TRUE, 3);
617 	gtk_box_pack_start(GTK_BOX(vbox), enclose_words_hbox, FALSE, FALSE, 3);
618 
619 	check_enclose_words_auto = gtk_check_button_new_with_label(
620 		_("Enclose selection automatically (without having to press a keybinding)"));
621 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_enclose_words_auto),
622 		ao_info->enable_enclose_words_auto);
623 	gtk_box_pack_start(GTK_BOX(vbox), check_enclose_words_auto, FALSE, FALSE, 3);
624 
625 	check_colortip = gtk_check_button_new_with_label(
626 		_("Show a calltip when hovering over a color value"));
627 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_colortip),
628 		ao_info->enable_colortip);
629 	gtk_box_pack_start(GTK_BOX(vbox), check_colortip, FALSE, FALSE, 3);
630 
631 	check_double_click_color_chooser = gtk_check_button_new_with_label(
632 		_("Open Color Chooser when double-clicking a color value"));
633 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_double_click_color_chooser),
634 		ao_info->enable_double_click_color_chooser);
635 	gtk_box_pack_start(GTK_BOX(vbox), check_double_click_color_chooser, FALSE, FALSE, 3);
636 
637 	g_object_set_data(G_OBJECT(dialog), "check_doclist", check_doclist);
638 	g_object_set_data(G_OBJECT(dialog), "radio_doclist_name", radio_doclist_name);
639 	g_object_set_data(G_OBJECT(dialog), "radio_doclist_tab_order", radio_doclist_tab_order);
640 	g_object_set_data(G_OBJECT(dialog), "radio_doclist_tab_order_reversed",
641 		radio_doclist_tab_order_reversed);
642 	g_object_set_data(G_OBJECT(dialog), "check_openuri", check_openuri);
643 	g_object_set_data(G_OBJECT(dialog), "check_tasks", check_tasks);
644 	g_object_set_data(G_OBJECT(dialog), "entry_tasks_tokens", entry_tasks_tokens);
645 	g_object_set_data(G_OBJECT(dialog), "check_tasks_scan_mode", check_tasks_scan_mode);
646 	g_object_set_data(G_OBJECT(dialog), "check_systray", check_systray);
647 	g_object_set_data(G_OBJECT(dialog), "check_bookmarklist", check_bookmarklist);
648 	g_object_set_data(G_OBJECT(dialog), "check_markword", check_markword);
649 	g_object_set_data(G_OBJECT(dialog), "check_markword_single_click_deselect",
650 		check_markword_single_click_deselect);
651 	g_object_set_data(G_OBJECT(dialog), "check_blanklines", check_blanklines);
652 	g_object_set_data(G_OBJECT(dialog), "check_xmltagging", check_xmltagging);
653 	g_object_set_data(G_OBJECT(dialog), "check_enclose_words", check_enclose_words);
654 	g_object_set_data(G_OBJECT(dialog), "check_enclose_words_auto", check_enclose_words_auto);
655 	g_object_set_data(G_OBJECT(dialog), "enclose_words_config_button", enclose_words_config_button);
656 	g_object_set_data(G_OBJECT(dialog), "check_colortip", check_colortip);
657 	g_object_set_data(G_OBJECT(dialog), "check_double_click_color_chooser",
658 		check_double_click_color_chooser);
659 	g_signal_connect(dialog, "response", G_CALLBACK(ao_configure_response_cb), NULL);
660 
661 	ao_configure_tasks_toggled_cb(GTK_TOGGLE_BUTTON(check_tasks), dialog);
662 	ao_configure_markword_toggled_cb(GTK_TOGGLE_BUTTON(check_markword), dialog);
663 	ao_configure_doclist_toggled_cb(GTK_TOGGLE_BUTTON(check_doclist), dialog);
664 
665 	gtk_widget_show_all(vbox);
666 
667 #if ! GTK_CHECK_VERSION(2, 10, 0)
668 	gtk_widget_hide(check_systray);
669 #endif
670 
671 	return vbox;
672 }
673 
674 
675 /* Cleanup */
plugin_addons_cleanup(G_GNUC_UNUSED GeanyPlugin * plugin,G_GNUC_UNUSED gpointer pdata)676 static void plugin_addons_cleanup(G_GNUC_UNUSED GeanyPlugin *plugin, G_GNUC_UNUSED gpointer pdata)
677 {
678 	g_object_unref(ao_info->doclist);
679 	g_object_unref(ao_info->openuri);
680 	g_object_unref(ao_info->systray);
681 	g_object_unref(ao_info->bookmarklist);
682 	g_object_unref(ao_info->markword);
683 	g_object_unref(ao_info->tasks);
684 	g_object_unref(ao_info->copyfilepath);
685 	g_object_unref(ao_info->colortip);
686 	g_free(ao_info->tasks_token_list);
687 
688 	ao_blanklines_set_enable(FALSE);
689 
690 	g_free(ao_info->config_file);
691 	g_free(ao_info);
692 }
693 
694 
695 /* Show help */
plugin_addons_help(G_GNUC_UNUSED GeanyPlugin * plugin,G_GNUC_UNUSED gpointer pdata)696 static void plugin_addons_help (G_GNUC_UNUSED GeanyPlugin *plugin, G_GNUC_UNUSED gpointer pdata)
697 {
698 	utils_open_browser("https://plugins.geany.org/addons.html");
699 }
700 
701 
702 static PluginCallback plugin_addons_callbacks[] =
703 {
704 	{ "update-editor-menu", (GCallback) &ao_update_editor_menu_cb, FALSE, NULL },
705 	{ "editor-notify", (GCallback) &ao_editor_notify_cb, TRUE, NULL },
706 
707 	{ "document-new", (GCallback) &ao_document_new_cb, TRUE, NULL },
708 	{ "document-open", (GCallback) &ao_document_open_cb, TRUE, NULL },
709 	{ "document-save", (GCallback) &ao_document_save_cb, TRUE, NULL },
710 	{ "document-close", (GCallback) &ao_document_close_cb, TRUE, NULL },
711 	{ "document-activate", (GCallback) &ao_document_activate_cb, TRUE, NULL },
712 	{ "document-before-save", (GCallback) &ao_document_before_save_cb, TRUE, NULL },
713 	{ "document-reload", (GCallback) &ao_document_reload_cb, TRUE, NULL },
714 
715 	{ "geany-startup-complete", (GCallback) &ao_startup_complete_cb, TRUE, NULL },
716 
717 	{ NULL, NULL, FALSE, NULL }
718 };
719 
720 
721 /* Load module */
722 G_MODULE_EXPORT
geany_load_module(GeanyPlugin * plugin)723 void geany_load_module(GeanyPlugin *plugin)
724 {
725 	/* Setup translation */
726 	main_locale_init(LOCALEDIR, GETTEXT_PACKAGE);
727 
728 	/* Set metadata */
729 	plugin->info->name = _("Addons");
730 	plugin->info->description = _("Various small addons for Geany.");
731 	plugin->info->version = VERSION;
732 	plugin->info->author = "Enrico Tröger, Bert Vermeulen, Eugene Arshinov, Frank Lanitz";
733 
734 	/* Set functions */
735 	plugin->funcs->init = plugin_addons_init;
736 	plugin->funcs->cleanup = plugin_addons_cleanup;
737 	plugin->funcs->help = plugin_addons_help;
738 	plugin->funcs->configure = plugin_addons_configure;
739 	plugin->funcs->callbacks = plugin_addons_callbacks;
740 
741 	/* Register! */
742 	GEANY_PLUGIN_REGISTER(plugin, 226);
743 }
744