2 * geanyprj - 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,2008 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 3 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, see <http://www.gnu.org/licenses/>.
28 #include "plugindata.h"
30 #include "filetypes.h"
32 #include "pluginmacros.h"
38 extern GeanyData
*geany_data
;
39 extern GeanyFunctions
*geany_functions
;
41 const gchar
*project_type_string
[NEW_PROJECT_TYPE_SIZE
] = {
50 project_filter_c_cpp(const gchar
* file
)
52 if (p_filetypes
->detect_from_filename(file
)->id
== GEANY_FILETYPES_C
||
53 p_filetypes
->detect_from_filename(file
)->id
== GEANY_FILETYPES_CPP
)
59 project_filter_c(const gchar
* file
)
61 if (p_filetypes
->detect_from_filename(file
)->id
== GEANY_FILETYPES_C
)
67 project_filter_python(const gchar
* file
)
69 if (p_filetypes
->detect_from_filename(file
)->id
== GEANY_FILETYPES_PYTHON
)
75 project_filter_all(const gchar
* file
)
77 if (p_filetypes
->detect_from_filename(file
)->id
!= GEANY_FILETYPES_ALL
)
83 project_filter_none(G_GNUC_UNUSED
const gchar
* file
)
89 void *project_type_filter
[NEW_PROJECT_TYPE_SIZE
] = {
93 project_filter_python
,
99 free_tag_object(gpointer obj
)
101 p_tm
->workspace_remove_object((TMWorkObject
*) obj
, TRUE
, FALSE
);
104 struct PluginProject
*
107 struct PluginProject
*ret
;
109 ret
= (struct PluginProject
*) g_new0(struct PluginProject
, 1);
110 ret
->tags
= g_hash_table_new_full(g_str_hash
, g_str_equal
, g_free
, free_tag_object
);
115 struct PluginProject
*
116 geany_project_load(const gchar
* path
)
118 struct PluginProject
*ret
;
119 TMWorkObject
*tm_obj
= NULL
;
123 gchar
*filename
, *locale_filename
;
127 debug("%s path=%s\n", __FUNCTION__
, path
);
132 config
= g_key_file_new();
133 if (!g_key_file_load_from_file(config
, path
, G_KEY_FILE_NONE
, NULL
))
135 g_key_file_free(config
);
140 ret
= geany_project_new();
141 geany_project_set_path(ret
, path
);
143 tmp
= p_utils
->get_setting_string(config
, "project", "name", GEANY_STRING_UNTITLED
);
144 geany_project_set_name(ret
, tmp
);
147 tmp
= p_utils
->get_setting_string(config
, "project", "description", "");
148 geany_project_set_description(ret
, tmp
);
151 tmp
= p_utils
->get_setting_string(config
, "project", "base_path", "");
152 geany_project_set_base_path(ret
, tmp
);
155 tmp
= p_utils
->get_setting_string(config
, "project", "run_cmd", "");
156 geany_project_set_run_cmd(ret
, tmp
);
159 geany_project_set_type_string(ret
,
160 p_utils
->get_setting_string(config
, "project", "type",
161 project_type_string
[0]));
162 geany_project_set_regenerate(ret
,
163 g_key_file_get_boolean(config
, "project", "regenerate", NULL
));
167 geany_project_regenerate_file_list(ret
);
172 key
= g_strdup_printf("file%d", i
);
173 while ((file
= g_key_file_get_string(config
, "files", key
, NULL
)))
175 filename
= get_full_path(path
, file
);
177 locale_filename
= p_utils
->get_locale_from_utf8(filename
);
178 tm_obj
= p_tm
->source_file_new(locale_filename
, FALSE
,
180 detect_from_filename(filename
)->name
);
181 g_free(locale_filename
);
184 g_hash_table_insert(ret
->tags
, filename
, tm_obj
);
185 p_tm
->source_file_update(tm_obj
, TRUE
, FALSE
, TRUE
);
192 key
= g_strdup_printf("file%d", i
);
196 g_key_file_free(config
);
201 geany_project_regenerate_file_list(struct PluginProject
*prj
)
205 debug("%s path=%s\n", __FUNCTION__
, prj
->base_path
);
206 g_hash_table_remove_all(prj
->tags
);
208 lst
= get_file_list(prj
->base_path
, NULL
, project_type_filter
[prj
->type
], NULL
);
209 geany_project_set_tags_from_list(prj
, lst
);
211 g_slist_foreach(lst
, (GFunc
) g_free
, NULL
);
216 geany_project_set_path(struct PluginProject
*prj
, const gchar
* path
)
218 gchar
*norm_path
= normpath(path
);
221 if (strcmp(prj
->path
, norm_path
) == 0)
227 prj
->path
= norm_path
;
231 geany_project_set_name(struct PluginProject
*prj
, const gchar
* name
)
235 prj
->name
= g_strdup(name
);
237 if (prj
== g_current_project
)
242 g_free(project
->name
);
243 project
->name
= g_strdup(name
);
249 geany_project_set_type_int(struct PluginProject
*prj
, gint val
)
255 geany_project_set_type_string(struct PluginProject
*prj
, const gchar
* val
)
259 for (i
= 0; i
< sizeof(project_type_string
) / sizeof(project_type_string
[0]); i
++)
261 if (strcmp(val
, project_type_string
[i
]) == 0)
262 return geany_project_set_type_int(prj
, i
);
267 geany_project_set_regenerate(struct PluginProject
*prj
, gboolean val
)
269 prj
->regenerate
= val
;
273 geany_project_set_description(struct PluginProject
*prj
, const gchar
* description
)
275 if (prj
->description
)
276 g_free(prj
->description
);
277 prj
->description
= g_strdup(description
);
279 if (prj
== g_current_project
)
283 if (project
->description
)
284 g_free(project
->description
);
285 project
->description
= g_strdup(description
);
291 geany_project_set_base_path(struct PluginProject
*prj
, const gchar
* base_path
)
294 g_free(prj
->base_path
);
296 if (g_path_is_absolute(base_path
))
298 prj
->base_path
= g_strdup(base_path
);
302 prj
->base_path
= get_full_path(prj
->path
, base_path
);
305 if (prj
== g_current_project
)
309 if (project
->base_path
)
310 g_free(project
->base_path
);
311 project
->base_path
= g_strdup(base_path
);
317 geany_project_set_run_cmd(struct PluginProject
*prj
, const gchar
* run_cmd
)
320 g_free(prj
->run_cmd
);
321 prj
->run_cmd
= g_strdup(run_cmd
);
323 if (prj
== g_current_project
)
327 if (project
->run_cmd
)
328 g_free(project
->run_cmd
);
329 project
->run_cmd
= g_strdup(run_cmd
);
337 geany_project_set_tags_from_list(struct PluginProject
*prj
, GSList
* files
)
340 gchar
*locale_filename
;
341 TMWorkObject
*tm_obj
= NULL
;
344 g_hash_table_destroy(prj
->tags
);
345 prj
->tags
= g_hash_table_new_full(g_str_hash
, g_str_equal
, g_free
, free_tag_object
);
347 for (tmp
= files
; tmp
!= NULL
; tmp
= g_slist_next(tmp
))
349 locale_filename
= p_utils
->get_locale_from_utf8(tmp
->data
);
350 tm_obj
= p_tm
->source_file_new(locale_filename
, FALSE
,
351 p_filetypes
->detect_from_filename(tmp
->data
)->name
);
352 g_free(locale_filename
);
355 g_hash_table_insert(prj
->tags
, g_strdup(tmp
->data
), tm_obj
);
356 p_tm
->source_file_update(tm_obj
, TRUE
, FALSE
, TRUE
);
363 geany_project_free(struct PluginProject
*prj
)
365 debug("%s prj=%p\n", __FUNCTION__
, prj
);
366 g_return_if_fail(prj
);
372 if (prj
->description
)
373 g_free(prj
->description
);
375 g_free(prj
->base_path
);
377 g_free(prj
->run_cmd
);
379 g_hash_table_destroy(prj
->tags
);
385 geany_project_add_file(struct PluginProject
*prj
, const gchar
* path
)
388 TMWorkObject
*tm_obj
= NULL
;
392 config
= g_key_file_new();
393 if (!g_key_file_load_from_file(config
, prj
->path
, G_KEY_FILE_NONE
, NULL
))
395 g_key_file_free(config
);
399 if (g_hash_table_lookup(prj
->tags
, path
))
401 g_key_file_free(config
);
405 filename
= p_utils
->get_locale_from_utf8(path
);
406 tm_obj
= p_tm
->source_file_new(filename
, FALSE
,
407 p_filetypes
->detect_from_filename(path
)->name
);
411 g_hash_table_insert(prj
->tags
, g_strdup(path
), tm_obj
);
412 p_tm
->source_file_update(tm_obj
, TRUE
, FALSE
, TRUE
);
414 geany_project_save(prj
);
420 struct PluginProject
*prj
;
426 geany_project_save_files(gpointer key
, G_GNUC_UNUSED gpointer value
, gpointer user_data
)
430 struct CFGData
*data
= (struct CFGData
*) user_data
;
432 filename
= get_relative_path(data
->prj
->path
, (const gchar
*) key
);
435 fkey
= g_strdup_printf("file%d", data
->i
);
436 g_key_file_set_string(data
->config
, "files", fkey
, filename
);
444 geany_project_remove_file(struct PluginProject
*prj
, const gchar
* path
)
446 if (!g_hash_table_remove(prj
->tags
, path
))
451 geany_project_save(prj
);
456 geany_project_save(struct PluginProject
*prj
)
462 base_path
= get_relative_path(prj
->path
, prj
->base_path
);
464 config
= g_key_file_new();
465 g_key_file_load_from_file(config
, prj
->path
, G_KEY_FILE_NONE
, NULL
);
467 g_key_file_set_string(config
, "project", "name", prj
->name
);
468 g_key_file_set_string(config
, "project", "description", prj
->description
);
469 g_key_file_set_string(config
, "project", "base_path", base_path
);
470 g_key_file_set_string(config
, "project", "run_cmd", prj
->run_cmd
);
471 g_key_file_set_boolean(config
, "project", "regenerate", prj
->regenerate
);
472 g_key_file_set_string(config
, "project", "type", project_type_string
[prj
->type
]);
475 data
.config
= config
;
478 g_key_file_remove_group(config
, "files", NULL
);
479 if (!prj
->regenerate
)
481 g_hash_table_foreach(prj
->tags
, geany_project_save_files
, &data
);
483 save_config(config
, prj
->path
);