2007-07-17 Johannes Schmid <jhs@gnome.org>
[anjuta-git-plugin.git] / plugins / subversion / plugin.c
blobf798e78178fdd2a4faaa3adb70cfa117eabb5376
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 plugin.c
4 Copyright (C) 2004 Naba Kumar, Johannes Schmid
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <libgnomevfs/gnome-vfs-utils.h>
22 #include <libgnomevfs/gnome-vfs.h>
24 #include <libanjuta/anjuta-shell.h>
25 #include <libanjuta/anjuta-preferences.h>
26 #include <libanjuta/anjuta-debug.h>
27 #include <libanjuta/interfaces/ianjuta-file.h>
28 #include <libanjuta/interfaces/ianjuta-document-manager.h>
29 #include <libanjuta/interfaces/ianjuta-vcs.h>
31 #include "plugin.h"
32 #include "subversion-actions.h"
33 #include "svn-backend.h"
35 #define UI_FILE PACKAGE_DATA_DIR"/ui/anjuta-subversion.ui"
37 static gpointer parent_class;
39 static GtkActionEntry actions_subversion[] = {
41 "ActionMenuSubversion", /* Action name */
42 NULL, /* Stock icon, if any */
43 N_("_Subversion"), /* Display label */
44 NULL, /* short-cut */
45 NULL, /* Tooltip */
46 NULL
49 "ActionSubversionAdd", /* Action name */
50 GTK_STOCK_ADD, /* Stock icon, if any */
51 N_("_Add..."), /* Display label */
52 NULL, /* short-cut */
53 N_("Add a new file/directory to the Subversion tree"), /* Tooltip */
54 G_CALLBACK (on_menu_subversion_add) /* action callback */
57 "ActionSubversionRemove", /* Action name */
58 GTK_STOCK_REMOVE, /* Stock icon, if any */
59 N_("_Remove..."), /* Display label */
60 NULL, /* short-cut */
61 N_("Remove a file/directory from Subversion tree"), /* Tooltip */
62 G_CALLBACK (on_menu_subversion_remove) /* action callback */
65 "ActionSubversionCommit", /* Action name */
66 GTK_STOCK_YES, /* Stock icon, if any */
67 N_("_Commit..."), /* Display label */
68 NULL, /* short-cut */
69 N_("Commit your changes to the Subversion tree"), /* Tooltip */
70 G_CALLBACK (on_menu_subversion_commit) /* action callback */
73 "ActionSubversionUpdate", /* Action name */
74 GTK_STOCK_REFRESH, /* Stock icon, if any */
75 N_("_Update..."), /* Display label */
76 NULL, /* short-cut */
77 N_("Sync your local copy with the Subversion tree"), /* Tooltip */
78 G_CALLBACK (on_menu_subversion_update) /* action callback */
81 "ActionSubversionDiff", /* Action name */
82 GTK_STOCK_ZOOM_100, /* Stock icon, if any */
83 N_("_Diff..."), /* Display label */
84 NULL, /* short-cut */
85 N_("Diff local tree with repositry"), /* Tooltip */
86 G_CALLBACK (on_menu_subversion_diff) /* action callback */
90 static GtkActionEntry popup_actions_subversion[] = {
92 "ActionPopupSubversion", /* Action name */
93 NULL, /* Stock icon, if any */
94 N_("_Subversion"), /* Display label */
95 NULL, /* short-cut */
96 NULL, /* Tooltip */
97 NULL
100 "ActionPopupSubversionCommit", /* Action name */
101 GTK_STOCK_YES, /* Stock icon, if any */
102 N_("_Commit..."), /* Display label */
103 NULL, /* short-cut */
104 N_("Commit your changes to the Subversion tree"), /* Tooltip */
105 G_CALLBACK (on_fm_subversion_commit) /* action callback */
108 "ActionPopupSubversionUpdate", /* Action name */
109 GTK_STOCK_REFRESH, /* Stock icon, if any */
110 N_("_Update..."), /* Display label */
111 NULL, /* short-cut */
112 N_("Sync your local copy with the Subversion tree"), /* Tooltip */
113 G_CALLBACK (on_fm_subversion_update) /* action callback */
117 static void
118 value_added_fm_current_uri (AnjutaPlugin *plugin, const char *name,
119 const GValue *value, gpointer data)
121 AnjutaUI *ui;
122 GtkAction *subversion_menu_action;
123 const gchar *uri;
124 GnomeVFSURI *subversion_uri = NULL;
125 gchar *subversion_text_uri = NULL;
126 gchar *subversion_dir;
127 gchar *filename;
128 GnomeVFSDirectoryHandle* handle;
129 GnomeVFSFileInfo info;
130 GnomeVFSResult result;
132 uri = g_value_get_string (value);
133 filename = gnome_vfs_get_local_path_from_uri (uri);
134 g_return_if_fail (filename != NULL);
136 Subversion *subversion = ANJUTA_PLUGIN_SUBVERSION (plugin);
137 ui = anjuta_shell_get_ui (plugin->shell, NULL);
139 if (subversion->fm_current_filename)
140 g_free (subversion->fm_current_filename);
141 subversion->fm_current_filename = filename;
143 /* Show popup menu if Subversion directory exists */
144 subversion_menu_action = anjuta_ui_get_action (ui, "ActionGroupPopupSubversion", "ActionPopupSubversion");
146 /* If a directory is selected we check if it contains a "Subversion" directory,
147 if it is a file we check if it's directory contains a "Subversion" directory */
148 result = gnome_vfs_get_file_info(uri, &info,
149 GNOME_VFS_FILE_INFO_DEFAULT);
150 if (result == GNOME_VFS_OK)
152 if (info.type == GNOME_VFS_FILE_TYPE_DIRECTORY)
154 /* Is "Subversion" a valid svn directory in a local checkout,
155 * If yes, we should check for both .svn and Subversion.
157 /* subversion_dir = g_build_filename (uri, "Subversion", NULL); */
158 subversion_dir = g_build_filename (uri, ".svn", NULL);
161 else
163 subversion_uri = gnome_vfs_uri_new (uri);
164 subversion_text_uri = gnome_vfs_uri_extract_dirname(subversion_uri);
165 /* subversion_dir = g_strconcat(subversion_text_uri, "/Subversion", NULL); */
166 subversion_dir = g_build_filename(subversion_text_uri, ".svn", NULL);
167 g_free(subversion_text_uri);
168 gnome_vfs_uri_unref(subversion_uri);
171 else
172 return; /* Strange... */
173 if (gnome_vfs_directory_open(&handle, subversion_dir,
174 GNOME_VFS_FILE_INFO_DEFAULT) == GNOME_VFS_OK)
177 g_object_set (G_OBJECT (subversion_menu_action), "sensitive", TRUE, NULL);
179 else
181 g_object_set (G_OBJECT (subversion_menu_action), "sensitive", FALSE, NULL);
183 g_free (subversion_dir);
186 static void
187 value_removed_fm_current_uri (AnjutaPlugin *plugin,
188 const char *name, gpointer data)
190 AnjutaUI *ui;
191 GtkAction *action;
193 Subversion *subversion = ANJUTA_PLUGIN_SUBVERSION (plugin);
195 if (subversion->fm_current_filename)
196 g_free (subversion->fm_current_filename);
197 subversion->fm_current_filename = NULL;
199 ui = anjuta_shell_get_ui (plugin->shell, NULL);
200 action = anjuta_ui_get_action (ui, "ActionGroupPopupSubversion", "ActionPopupSubversion");
201 g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
204 static void
205 value_added_project_root_uri (AnjutaPlugin *plugin, const gchar *name,
206 const GValue *value, gpointer user_data)
208 Subversion *bb_plugin;
209 const gchar *root_uri;
211 bb_plugin = ANJUTA_PLUGIN_SUBVERSION (plugin);
213 DEBUG_PRINT ("Project added");
215 if (bb_plugin->project_root_dir)
216 g_free (bb_plugin->project_root_dir);
217 bb_plugin->project_root_dir = NULL;
219 root_uri = g_value_get_string (value);
220 if (root_uri)
222 bb_plugin->project_root_dir =
223 gnome_vfs_get_local_path_from_uri (root_uri);
224 if (bb_plugin->project_root_dir)
226 // update_project_ui (bb_plugin);
231 static void
232 value_removed_project_root_uri (AnjutaPlugin *plugin, const gchar *name,
233 gpointer user_data)
235 Subversion *bb_plugin;
237 bb_plugin = ANJUTA_PLUGIN_SUBVERSION (plugin);
238 if (bb_plugin->project_root_dir)
239 g_free (bb_plugin->project_root_dir);
240 bb_plugin->project_root_dir = NULL;
241 // update_project_ui (bb_plugin);
244 static void
245 value_added_current_editor (AnjutaPlugin *plugin, const char *name,
246 const GValue *value, gpointer data)
248 AnjutaUI *ui;
249 gchar *uri;
250 GObject *editor;
252 editor = g_value_get_object (value);
254 if (!IANJUTA_IS_EDITOR(editor))
255 return;
257 Subversion *subversion = ANJUTA_PLUGIN_SUBVERSION (plugin);
258 ui = anjuta_shell_get_ui (plugin->shell, NULL);
260 if (subversion->current_editor_filename)
261 g_free (subversion->current_editor_filename);
262 subversion->current_editor_filename = NULL;
264 uri = ianjuta_file_get_uri (IANJUTA_FILE (editor), NULL);
265 if (uri)
267 gchar *filename;
269 filename = gnome_vfs_get_local_path_from_uri (uri);
270 g_return_if_fail (filename != NULL);
271 subversion->current_editor_filename = filename;
272 g_free (uri);
273 // update_module_ui (subversion);
277 static void
278 value_removed_current_editor (AnjutaPlugin *plugin,
279 const char *name, gpointer data)
281 Subversion *subversion = ANJUTA_PLUGIN_SUBVERSION (plugin);
283 if (subversion->current_editor_filename)
284 g_free (subversion->current_editor_filename);
285 subversion->current_editor_filename = NULL;
287 // update_module_ui (subversion);
290 static gboolean
291 activate_plugin (AnjutaPlugin *plugin)
294 GladeXML* gxml;
295 AnjutaPreferences *prefs;
297 AnjutaUI *ui;
298 Subversion *subversion;
300 DEBUG_PRINT ("Subversion: Activating Subversion plugin ...");
301 subversion = ANJUTA_PLUGIN_SUBVERSION (plugin);
303 ui = anjuta_shell_get_ui (plugin->shell, NULL);
305 /* Create the messages preferences page */
307 prefs = anjuta_shell_get_preferences (plugin->shell, NULL);
308 gxml = glade_xml_new (GLADE_FILE, "subversion", NULL);
309 anjuta_preferences_add_page (prefs, gxml, "subversion", ICON_FILE);
310 g_object_unref (gxml);
313 /* Add all our actions */
314 subversion->action_group =
315 anjuta_ui_add_action_group_entries (ui, "ActionGroupSubversion",
316 _("Subversion operations"),
317 actions_subversion,
318 G_N_ELEMENTS (actions_subversion),
319 GETTEXT_PACKAGE, TRUE, plugin);
320 subversion->popup_action_group =
321 anjuta_ui_add_action_group_entries (ui, "ActionGroupPopupSubversion",
322 _("Subversion popup operations"),
323 popup_actions_subversion,
324 G_N_ELEMENTS (popup_actions_subversion),
325 GETTEXT_PACKAGE, FALSE, plugin);
327 /* Merge UI */
328 subversion->uiid = anjuta_ui_merge (ui, UI_FILE);
330 /* Add watches */
331 subversion->fm_watch_id =
332 anjuta_plugin_add_watch (plugin, "file_manager_current_uri",
333 value_added_fm_current_uri,
334 value_removed_fm_current_uri, NULL);
335 subversion->project_watch_id =
336 anjuta_plugin_add_watch (plugin, "project_root_uri",
337 value_added_project_root_uri,
338 value_removed_project_root_uri, NULL);
339 subversion->editor_watch_id =
340 anjuta_plugin_add_watch (plugin, "document_manager_current_editor",
341 value_added_current_editor,
342 value_removed_current_editor, NULL);
343 return TRUE;
346 static gboolean
347 deactivate_plugin (AnjutaPlugin *plugin)
349 Subversion *subversion = ANJUTA_PLUGIN_SUBVERSION (plugin);
350 AnjutaUI *ui = anjuta_shell_get_ui (plugin->shell, NULL);
351 DEBUG_PRINT ("Subversion: Dectivating Subversion plugin ...");
352 anjuta_plugin_remove_watch (plugin, subversion->fm_watch_id, TRUE);
353 anjuta_plugin_remove_watch (plugin, subversion->project_watch_id, TRUE);
354 anjuta_plugin_remove_watch (plugin, subversion->editor_watch_id, TRUE);
355 anjuta_ui_unmerge (ui, ANJUTA_PLUGIN_SUBVERSION (plugin)->uiid);
356 anjuta_ui_remove_action_group (ui, ANJUTA_PLUGIN_SUBVERSION (plugin)->action_group);
357 anjuta_ui_remove_action_group (ui, ANJUTA_PLUGIN_SUBVERSION (plugin)->popup_action_group);
358 return TRUE;
361 static void
362 finalize (GObject *obj)
364 // Subversion *plugin = ANJUTA_PLUGIN_SUBVERSION (obj);
365 GNOME_CALL_PARENT (G_OBJECT_CLASS, finalize, (G_OBJECT(obj)));
368 static void
369 dispose (GObject *obj)
371 // Subversion *plugin = ANJUTA_PLUGIN_SUBVERSION (obj);
372 GNOME_CALL_PARENT (G_OBJECT_CLASS, dispose, (G_OBJECT(obj)));
375 static void
376 subversion_instance_init (GObject *obj)
378 Subversion *plugin = ANJUTA_PLUGIN_SUBVERSION (obj);
379 plugin->uiid = 0;
380 plugin->mesg_view = NULL;
381 plugin->launcher = NULL;
382 plugin->diff_editor = NULL;
383 plugin->fm_current_filename = NULL;
384 plugin->project_root_dir = NULL;
385 plugin->current_editor_filename = NULL;
386 plugin->backend = svn_backend_new(plugin);
389 static void
390 subversion_class_init (GObjectClass *klass)
392 AnjutaPluginClass *plugin_class = ANJUTA_PLUGIN_CLASS (klass);
394 parent_class = g_type_class_peek_parent (klass);
396 plugin_class->activate = activate_plugin;
397 plugin_class->deactivate = deactivate_plugin;
398 klass->dispose = dispose;
399 klass->finalize = finalize;
402 /* Interface */
404 static void
405 ianjuta_subversion_add (IAnjutaVcs *obj, const gchar* filename,
406 GError **err)
408 Subversion* plugin = ANJUTA_PLUGIN_SUBVERSION (obj);
409 svn_backend_add(plugin->backend, filename, FALSE, FALSE);
412 static void
413 ianjuta_subversion_commit (IAnjutaVcs *obj, const gchar* filename, const gchar* log,
414 gboolean recurse, GError **err)
416 Subversion* plugin = ANJUTA_PLUGIN_SUBVERSION (obj);
417 svn_backend_commit(plugin->backend, filename, log, recurse);
420 static void
421 ianjuta_subversion_remove (IAnjutaVcs *obj, const gchar* filename, GError **err)
423 Subversion* plugin = ANJUTA_PLUGIN_SUBVERSION (obj);
424 svn_backend_remove(plugin->backend, filename, FALSE);
428 static void
429 ianjuta_subversion_update (IAnjutaVcs *obj, const gchar* filename, gboolean recurse, GError **err)
431 Subversion* plugin = ANJUTA_PLUGIN_SUBVERSION (obj);
432 svn_backend_update(plugin->backend, filename, NULL, recurse);
435 static void
436 ianjuta_vcs_iface_init (IAnjutaVcsIface *iface)
438 iface->add = ianjuta_subversion_add;
439 iface->remove = ianjuta_subversion_remove;
440 iface->update = ianjuta_subversion_update;
441 iface->commit = ianjuta_subversion_commit;
444 ANJUTA_PLUGIN_BEGIN (Subversion, subversion);
445 ANJUTA_PLUGIN_ADD_INTERFACE(ianjuta_vcs, IANJUTA_TYPE_VCS);
446 ANJUTA_PLUGIN_END;
448 ANJUTA_SIMPLE_PLUGIN (Subversion, subversion);