load .geanyprj file as geany project on open/switch tabs
[geanyprj.git] / geanyprj.c
blob66d059f94c76825715f097a4b4bc1e0e4765454e
1 /*
2 * geanyprj.c - Alternative project support for geany light IDE.
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 Yura Siamashka <yurand2@gmail.com>
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 2 of the License, or
12 * (at your option) any later version.
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.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 #include "geany.h"
25 #include "support.h"
26 #include "plugindata.h"
27 #include "document.h"
28 #include "filetypes.h"
29 #include "utils.h"
30 #include "project.h"
31 #include "pluginmacros.h"
33 VERSION_CHECK(36);
34 PLUGIN_INFO(_("Project"), _("Alternative project support."), VERSION,
35 _("Yura Siamashka <yurand2@gmail.com>"));
37 #define DEBUG
39 #ifdef DEBUG
40 #define debug printf
41 #else
42 #define debug
43 #endif
45 PluginFields *plugin_fields;
46 GeanyData *geany_data;
49 static gchar *
50 find_file_path(const gchar * dir, const gchar * filename)
52 gboolean ret = FALSE;
53 gchar *base;
54 gchar *gitdir = NULL;
55 gchar *base_prev = g_strdup(":");
57 base = g_strdup(dir);
59 while (strcmp(base, base_prev) != 0)
61 gitdir = g_build_path("/", base, filename, NULL);
62 ret = g_file_test(gitdir, G_FILE_TEST_IS_REGULAR);
63 if (ret)
65 g_free(base_prev);
66 g_free(base);
67 return gitdir;
69 g_free(gitdir);
70 g_free(base_prev);
71 base_prev = base;
72 base = g_path_get_dirname(base);
75 g_free(base_prev);
76 g_free(base);
77 return NULL;
80 /* Reads the given filename and creates a new project with the data found in the file.
81 * At this point there should not be an already opened project in Geany otherwise it will just
82 * return.
83 * The filename is expected in the locale encoding. */
84 static gboolean
85 xload_config(const gchar * filename)
87 GKeyFile *config;
88 GeanyProject *p;
90 // there should not be an open project
91 g_return_val_if_fail(project == NULL && filename != NULL, FALSE);
93 config = g_key_file_new();
94 if (!g_key_file_load_from_file(config, filename, G_KEY_FILE_NONE, NULL))
96 g_key_file_free(config);
97 return FALSE;
100 p = project = g_new0(GeanyProject, 1);
102 p->name = utils->get_setting_string(config, "project", "name", GEANY_STRING_UNTITLED);
103 p->description = utils->get_setting_string(config, "project", "description", "");
104 p->file_name = utils->get_utf8_from_locale(filename);
105 p->base_path = utils->get_setting_string(config, "project", "base_path", "");
106 p->run_cmd = utils->get_setting_string(config, "project", "run_cmd", "");
107 p->file_patterns =
108 g_key_file_get_string_list(config, "project", "file_patterns", NULL, NULL);
110 g_key_file_free(config);
112 return TRUE;
116 static gboolean
117 xproject_load_file(const gchar * locale_file_name)
119 g_return_val_if_fail(locale_file_name != NULL, FALSE);
121 if (xload_config(locale_file_name))
123 ui->set_statusbar(TRUE, _("Project \"%s\" opened."), project->name);
124 return TRUE;
126 else
128 gchar *utf8_filename = utils->get_utf8_from_locale(locale_file_name);
129 ui->set_statusbar(TRUE, _("Project file \"%s\" could not be loaded."),
130 utf8_filename);
131 g_free(utf8_filename);
133 return FALSE;
137 /* This fonction should keep in sync with geany code */
138 static void
139 xproject_close()
141 g_return_if_fail(project != NULL);
143 ui->set_statusbar(TRUE, _("Project \"%s\" closed."), project->name);
145 g_free(project->name);
146 g_free(project->description);
147 g_free(project->file_name);
148 g_free(project->base_path);
149 g_free(project->run_cmd);
151 g_free(project);
152 project = NULL;
155 static void
156 reload_project()
158 gint idx;
159 gchar *dir;
160 gchar *proj;
162 idx = documents->get_cur_idx();
163 g_return_if_fail(DOC_IDX_VALID(idx) && doc_list[idx].file_name != NULL);
165 dir = g_path_get_dirname(doc_list[idx].file_name);
166 proj = find_file_path(dir, ".geanyprj");
169 if (!proj)
171 if (project)
172 xproject_close();
173 return;
176 if (!project)
178 xproject_load_file(proj);
180 else if (strcmp(proj, project->file_name) != 0)
182 xproject_close();
183 xproject_load_file(proj);
185 if (proj)
186 g_free(proj);
189 static void
190 on_doc_save(GObject * obj, gint idx, gpointer user_data)
192 debug("%s obj=%p, idx = %d, user_data = %p\n", __FUNCTION__, obj, idx, user_data);
193 reload_project();
196 static void
197 on_doc_open(GObject * obj, gint idx, gpointer user_data)
199 debug("%s obj=%p, idx = %d, user_data = %p\n", __FUNCTION__, obj, idx, user_data);
200 reload_project();
203 static void
204 on_doc_activate(GObject * obj, gint idx, gpointer user_data)
206 debug("%s obj=%p, idx = %d, user_data = %p\n", __FUNCTION__, obj, idx, user_data);
207 reload_project();
210 GeanyCallback geany_callbacks[] = {
211 {"document-open", (GCallback) & on_doc_open, TRUE, NULL},
212 {"document-save", (GCallback) & on_doc_save, TRUE, NULL},
213 {"document-activate", (GCallback) & on_doc_activate, TRUE, NULL},
214 {NULL, NULL, FALSE, NULL}
217 /* Called by Geany to initialize the plugin */
218 void
219 init(GeanyData * data)
224 /* Called by Geany before unloading the plugin. */
225 void
226 cleanup()