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 #include <string.h>
24 #include <sys/time.h>
25 
26 #ifdef HAVE_CONFIG_H
27 	#include "config.h" /* for the gettext domain */
28 #endif
29 #include <geanyplugin.h>
30 
31 #include "geanyprj.h"
32 
33 
34 struct GeanyPrj *g_current_project = NULL;
35 static GPtrArray *g_projects = NULL;
36 
37 
collect_tags(G_GNUC_UNUSED gpointer key,gpointer value,gpointer user_data)38 static void collect_tags(G_GNUC_UNUSED gpointer key, gpointer value, gpointer user_data)
39 {
40 	GPtrArray *array = user_data;
41 
42 	debug("%s file=%s\n", __FUNCTION__, (const gchar *)key);
43 	if (value != NULL)
44 	{
45 		g_ptr_array_add(array, value);
46 	}
47 }
48 
49 
50 /* This fonction should keep in sync with geany code */
xproject_close(gboolean cache)51 void xproject_close(gboolean cache)
52 {
53 	debug("%s\n", __FUNCTION__);
54 
55 	if (!g_current_project)
56 		return;
57 
58 	if (cache)
59 	{
60 		g_ptr_array_add(g_projects, g_current_project);
61 	}
62 	else
63 	{
64 		geany_project_free(g_current_project);
65 	}
66 
67 	g_current_project = NULL;
68 	sidebar_refresh();
69 }
70 
71 
xproject_open(const gchar * path)72 void xproject_open(const gchar *path)
73 {
74 	guint i;
75 	struct GeanyPrj *p = NULL;
76 	GPtrArray *to_reload;
77 	debug("%s\n", __FUNCTION__);
78 
79 	for (i = 0; i < g_projects->len; i++)
80 	{
81 		if (strcmp(path, ((struct GeanyPrj *) g_projects->pdata[i])->path) == 0)
82 		{
83 			p = (struct GeanyPrj *)g_projects->pdata[i];
84 			g_ptr_array_remove_index(g_projects, i);
85 			break;
86 		}
87 	}
88 	if (!p)
89 		p = geany_project_load(path);
90 
91 	if (!p)
92 		return;
93 
94 	ui_set_statusbar(TRUE, _("Project \"%s\" opened."), p->name);
95 	to_reload = g_ptr_array_new();
96 	g_hash_table_foreach(p->tags, collect_tags, to_reload);
97 	tm_workspace_remove_source_files(to_reload);
98 	tm_workspace_add_source_files(to_reload);
99 	g_ptr_array_free(to_reload, TRUE);
100 
101 	g_current_project = p;
102 	sidebar_refresh();
103 }
104 
105 
xproject_update_tag(const gchar * filename)106 void xproject_update_tag(const gchar *filename)
107 {
108 	guint i;
109 	TMSourceFile *tm_obj;
110 
111 	if (g_current_project)
112 	{
113 		tm_obj = g_hash_table_lookup(g_current_project->tags, filename);
114 		if (tm_obj)
115 		{
116 			/* force tag update */
117 			tm_workspace_remove_source_file(tm_obj);
118 			tm_workspace_add_source_file(tm_obj);
119 		}
120 	}
121 
122 	for (i = 0; i < g_projects->len; i++)
123 	{
124 		tm_obj = (TMSourceFile *)g_hash_table_lookup(((struct GeanyPrj *)(g_projects->pdata[i]))->tags, filename);
125 		if (tm_obj)
126 		{
127 			/* force tag update */
128 			tm_workspace_remove_source_file(tm_obj);
129 			tm_workspace_add_source_file(tm_obj);
130 		}
131 	}
132 }
133 
134 
xproject_add_file(const gchar * path)135 gboolean xproject_add_file(const gchar *path)
136 {
137 	debug("%s path=%s\n", __FUNCTION__, path);
138 
139 	if (!g_current_project)
140 		return FALSE;
141 
142 	if (geany_project_add_file(g_current_project, path))
143 	{
144 		sidebar_refresh();
145 		return TRUE;
146 	}
147 	return FALSE;
148 }
149 
150 
xproject_remove_file(const gchar * path)151 gboolean xproject_remove_file(const gchar *path)
152 {
153 	TMSourceFile *tm_obj;
154 
155 	debug("%s path=%s\n", __FUNCTION__, path);
156 
157 	if (!g_current_project)
158 		return FALSE;
159 
160 	tm_obj = (TMSourceFile *) g_hash_table_lookup(g_current_project->tags, path);
161 	if (tm_obj)
162 	{
163 		tm_workspace_remove_source_file(tm_obj);
164 	}
165 
166 	if (geany_project_remove_file(g_current_project, path))
167 	{
168 		sidebar_refresh();
169 		return TRUE;
170 	}
171 	return FALSE;
172 }
173 
174 
xproject_init(void)175 void xproject_init(void)
176 {
177 	g_projects = g_ptr_array_sized_new(10);
178 	g_current_project = NULL;
179 }
180 
181 
xproject_cleanup(void)182 void xproject_cleanup(void)
183 {
184 	guint i;
185 	for (i = 0; i < g_projects->len; i++)
186 	{
187 		geany_project_free(((struct GeanyPrj *)(g_projects->pdata[i])));
188 	}
189 	g_ptr_array_free(g_projects, TRUE);
190 	g_projects = NULL;
191 }
192