1 /*
2 * geanyprj - Alternative project support for geany light IDE.
3 *
4 * Copyright 2007 Frank Lanitz <frank(at)frank(dot)uvena(dot)de>
5 * Copyright 2007 Enrico Tröger <enrico.troeger@uvena.de>
6 * Copyright 2007 Nick Treleaven <nick.treleaven@btinternet.com>
7 * Copyright 2007, 2008 Yura Siamashka <yurand2@gmail.com>
8 *
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #ifdef HAVE_LOCALE_H
24 # include <locale.h>
25 #endif
26
27 #ifdef HAVE_CONFIG_H
28 #include "config.h" /* for the gettext domain */
29 #endif
30 #include <geanyplugin.h>
31
32 #include <sys/time.h>
33 #include <string.h>
34
35 #include "geanyprj.h"
36
37 PLUGIN_VERSION_CHECK(224)
38 PLUGIN_SET_TRANSLATABLE_INFO(LOCALEDIR, GETTEXT_PACKAGE,
39 "GeanyPrj", _("Alternative project support. \nThis plugin currently "
40 "has no maintainer. Would you like to help by contributing "
41 "to this plugin?"),
42 VERSION,
43 "Yura Siamashka <yurand2@gmail.com>")
44
45 GeanyPlugin *geany_plugin;
46 GeanyData *geany_data;
47
48
49 static gchar *config_file;
50 static gboolean display_sidebar = TRUE;
51
52
53 /* Keybinding(s) */
54 enum
55 {
56 KB_FIND_IN_PROJECT,
57 KB_COUNT
58 };
59
60
reload_project(void)61 static void reload_project(void)
62 {
63 gchar *dir;
64 gchar *proj;
65 GeanyDocument *doc;
66
67 debug("%s\n", __FUNCTION__);
68
69 doc = document_get_current();
70 if (doc == NULL || doc->file_name == NULL)
71 return;
72
73 dir = g_path_get_dirname(doc->file_name);
74 proj = find_file_path(dir, ".geanyprj");
75
76 if (!proj)
77 {
78 if (g_current_project)
79 xproject_close(TRUE);
80 return;
81 }
82
83 if (!g_current_project)
84 {
85 xproject_open(proj);
86 }
87 else if (strcmp(proj, g_current_project->path) != 0)
88 {
89 xproject_close(TRUE);
90 xproject_open(proj);
91 }
92 if (proj)
93 g_free(proj);
94 }
95
96
on_doc_save(G_GNUC_UNUSED GObject * obj,GeanyDocument * doc,G_GNUC_UNUSED gpointer user_data)97 static void on_doc_save(G_GNUC_UNUSED GObject *obj, GeanyDocument *doc, G_GNUC_UNUSED gpointer user_data)
98 {
99 gchar *name;
100
101 g_return_if_fail(doc != NULL && doc->file_name != NULL);
102
103 name = g_path_get_basename(doc->file_name);
104 if (g_current_project && strcmp(name, ".geanyprj") == 0)
105 {
106 xproject_close(FALSE);
107 }
108 reload_project();
109 xproject_update_tag(doc->file_name);
110 }
111
112
on_doc_open(G_GNUC_UNUSED GObject * obj,G_GNUC_UNUSED GeanyDocument * doc,G_GNUC_UNUSED gpointer user_data)113 static void on_doc_open(G_GNUC_UNUSED GObject *obj, G_GNUC_UNUSED GeanyDocument *doc,
114 G_GNUC_UNUSED gpointer user_data)
115 {
116 reload_project();
117 }
118
119
on_doc_activate(G_GNUC_UNUSED GObject * obj,G_GNUC_UNUSED GeanyDocument * doc,G_GNUC_UNUSED gpointer user_data)120 static void on_doc_activate(G_GNUC_UNUSED GObject *obj, G_GNUC_UNUSED GeanyDocument *doc,
121 G_GNUC_UNUSED gpointer user_data)
122 {
123 reload_project();
124 }
125
126
127 PluginCallback plugin_callbacks[] = {
128 {"document-open", (GCallback) & on_doc_open, TRUE, NULL},
129 {"document-save", (GCallback) & on_doc_save, TRUE, NULL},
130 {"document-activate", (GCallback) & on_doc_activate, TRUE, NULL},
131 {NULL, NULL, FALSE, NULL}
132 };
133
134
135 /* Keybinding callback */
kb_find_in_project(guint key_id)136 static void kb_find_in_project(guint key_id)
137 {
138 on_find_in_project(NULL, NULL);
139 }
140
141
load_settings(void)142 static void load_settings(void)
143 {
144 GKeyFile *config = g_key_file_new();
145 GError *err = NULL;
146 gboolean tmp;
147
148 config_file = g_strconcat(geany->app->configdir, G_DIR_SEPARATOR_S, "plugins", G_DIR_SEPARATOR_S,
149 "geanyprj", G_DIR_SEPARATOR_S, "geanyprj.conf", NULL);
150 g_key_file_load_from_file(config, config_file, G_KEY_FILE_NONE, NULL);
151
152 tmp = g_key_file_get_boolean(config, "geanyprj", "display_sidebar", &err);
153
154 if (err)
155 g_error_free(err);
156 else
157 display_sidebar = tmp;
158
159 g_key_file_free(config);
160 }
161
162
save_settings(void)163 static void save_settings(void)
164 {
165 GKeyFile *config = g_key_file_new();
166 gchar *data;
167 gchar *config_dir = g_path_get_dirname(config_file);
168
169 g_key_file_load_from_file(config, config_file, G_KEY_FILE_NONE, NULL);
170
171 g_key_file_set_boolean(config, "geanyprj", "display_sidebar", display_sidebar);
172
173 if (! g_file_test(config_dir, G_FILE_TEST_IS_DIR) && utils_mkdir(config_dir, TRUE) != 0)
174 {
175 dialogs_show_msgbox(GTK_MESSAGE_ERROR,
176 _("Plugin configuration directory could not be created."));
177 }
178 else
179 {
180 /* write config to file */
181 data = g_key_file_to_data(config, NULL, NULL);
182 utils_write_file(config_file, data);
183 g_free(data);
184 }
185 g_free(config_dir);
186 g_key_file_free(config);
187 }
188
189
on_configure_response(G_GNUC_UNUSED GtkDialog * dialog,G_GNUC_UNUSED gint response,GtkWidget * checkbox)190 static void on_configure_response(G_GNUC_UNUSED GtkDialog *dialog, G_GNUC_UNUSED gint response, GtkWidget *checkbox)
191 {
192 gboolean old_display_sidebar = display_sidebar;
193
194 display_sidebar = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbox));
195
196 if (display_sidebar ^ old_display_sidebar)
197 {
198 if (display_sidebar)
199 {
200 create_sidebar();
201 sidebar_refresh();
202 }
203 else
204 {
205 destroy_sidebar();
206 }
207 save_settings();
208 }
209 }
210
211
212 /* Called by Geany to initialize the plugin */
plugin_init(G_GNUC_UNUSED GeanyData * data)213 void plugin_init(G_GNUC_UNUSED GeanyData *data)
214 {
215 GeanyKeyGroup *key_group;
216
217 load_settings();
218 tools_menu_init();
219
220 xproject_init();
221 if (display_sidebar)
222 create_sidebar();
223 reload_project();
224
225 key_group = plugin_set_key_group(geany_plugin, "geanyprj", KB_COUNT, NULL);
226 keybindings_set_item(key_group, KB_FIND_IN_PROJECT,
227 kb_find_in_project, 0, 0, "find_in_project",
228 _("Find a text in geanyprj's project"), NULL);
229 }
230
231
232 /* Called by Geany to show the plugin's configure dialog. This function is always called after
233 * plugin_init() was called.
234 */
plugin_configure(GtkDialog * dialog)235 GtkWidget *plugin_configure(GtkDialog *dialog)
236 {
237 GtkWidget *vbox;
238 GtkWidget *checkbox;
239
240 vbox = gtk_vbox_new(FALSE, 6);
241
242 checkbox = gtk_check_button_new_with_label(_("Display sidebar"));
243 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbox), display_sidebar);
244
245 gtk_box_pack_start(GTK_BOX(vbox), checkbox, FALSE, FALSE, 0);
246
247 gtk_widget_show_all(vbox);
248
249 /* Connect a callback for when the user clicks a dialog button */
250 g_signal_connect(dialog, "response", G_CALLBACK(on_configure_response), checkbox);
251
252 return vbox;
253 }
254
255
256 /* Called by Geany before unloading the plugin. */
plugin_cleanup(void)257 void plugin_cleanup(void)
258 {
259 tools_menu_uninit();
260
261 if (g_current_project)
262 geany_project_free(g_current_project);
263 g_current_project = NULL;
264
265 g_free(config_file);
266
267 xproject_cleanup();
268 destroy_sidebar();
269 }
270