Add progress handling to GitCommand
[anjuta-git-plugin.git] / plugins / subversion / plugin.c
blob1f5279b34a6f0fe24e6d7a6e38f14924eda5c3a9
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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-add-dialog.h"
33 #include "subversion-remove-dialog.h"
34 #include "subversion-commit-dialog.h"
35 #include "subversion-update-dialog.h"
36 #include "subversion-revert-dialog.h"
37 #include "subversion-log-dialog.h"
38 #include "subversion-diff-dialog.h"
39 #include "subversion-copy-dialog.h"
40 #include "subversion-switch-dialog.h"
41 #include "subversion-merge-dialog.h"
42 #include "subversion-resolve-dialog.h"
44 #define UI_FILE PACKAGE_DATA_DIR"/ui/anjuta-subversion.ui"
46 static gpointer parent_class;
48 static GtkActionEntry actions_subversion[] = {
50 "ActionMenuSubversion", /* Action name */
51 NULL, /* Stock icon, if any */
52 N_("_Subversion"), /* Display label */
53 NULL, /* short-cut */
54 NULL, /* Tooltip */
55 NULL
58 "ActionSubversionAdd", /* Action name */
59 GTK_STOCK_ADD, /* Stock icon, if any */
60 N_("_Add..."), /* Display label */
61 NULL, /* short-cut */
62 N_("Add a new file/directory to the Subversion tree"), /* Tooltip */
63 G_CALLBACK (on_menu_subversion_add) /* action callback */
66 "ActionSubversionRemove", /* Action name */
67 GTK_STOCK_REMOVE, /* Stock icon, if any */
68 N_("_Remove..."), /* Display label */
69 NULL, /* short-cut */
70 N_("Remove a file/directory from Subversion tree"), /* Tooltip */
71 G_CALLBACK (on_menu_subversion_remove) /* action callback */
74 "ActionSubversionCommit", /* Action name */
75 GTK_STOCK_YES, /* Stock icon, if any */
76 N_("_Commit..."), /* Display label */
77 NULL, /* short-cut */
78 N_("Commit your changes to the Subversion tree"), /* Tooltip */
79 G_CALLBACK (on_menu_subversion_commit) /* action callback */
82 "ActionSubversionRevert", /* Action name */
83 GTK_STOCK_UNDO, /* Stock icon, if any */
84 N_("_Revert..."), /* Display label */
85 NULL, /* short-cut */
86 N_("Revert changes to your working copy."), /* Tooltip */
87 G_CALLBACK (on_menu_subversion_revert) /* action callback */
90 "ActionSubversionResolve", /* Action name */
91 GTK_STOCK_PREFERENCES, /* Stock icon, if any */
92 N_("_Resolve Conflicts..."), /* Display label */
93 NULL, /* short-cut */
94 N_("Resolve conflicts in your working copy."), /* Tooltip */
95 G_CALLBACK (on_menu_subversion_resolve) /* action callback */
98 "ActionSubversionUpdate", /* Action name */
99 GTK_STOCK_REFRESH, /* Stock icon, if any */
100 N_("_Update..."), /* Display label */
101 NULL, /* short-cut */
102 N_("Sync your local copy with the Subversion tree"), /* Tooltip */
103 G_CALLBACK (on_menu_subversion_update) /* action callback */
106 "ActionSubversionCopy", /* Action name */
107 GTK_STOCK_COPY, /* Stock icon, if any */
108 N_("Copy Files/Folders..."), /* Display label */
109 NULL, /* short-cut */
110 N_("Copy files/folders in the repository"), /* Tooltip */
111 G_CALLBACK (on_menu_subversion_copy) /* action callback */
114 "ActionSubversionSwitch", /* Action name */
115 GTK_STOCK_JUMP_TO, /* Stock icon, if any */
116 N_("Switch to a Branch/Tag..."), /* Display label */
117 NULL, /* short-cut */
118 N_("Switch your local copy to a branch or tag in the repository"), /* Tooltip */
119 G_CALLBACK (on_menu_subversion_switch) /* action callback */
122 "ActionSubversionMerge", /* Action name */
123 GTK_STOCK_CONVERT, /* Stock icon, if any */
124 N_("Merge..."), /* Display label */
125 NULL, /* short-cut */
126 N_("Merge changes into your working copy"), /* Tooltip */
127 G_CALLBACK (on_menu_subversion_merge) /* action callback */
130 "ActionSubversionLog", /* Action name */
131 GTK_STOCK_ZOOM_100, /* Stock icon, if any */
132 N_("_View Log..."), /* Display label */
133 NULL, /* short-cut */
134 N_("View file history"), /* Tooltip */
135 G_CALLBACK (on_menu_subversion_log) /* action callback */
138 "ActionSubversionDiff", /* Action name */
139 GTK_STOCK_ZOOM_100, /* Stock icon, if any */
140 N_("_Diff..."), /* Display label */
141 NULL, /* short-cut */
142 N_("Diff local tree with repository"), /* Tooltip */
143 G_CALLBACK (on_menu_subversion_diff) /* action callback */
147 static GtkActionEntry popup_actions_subversion[] = {
149 "ActionPopupSubversion", /* Action name */
150 NULL, /* Stock icon, if any */
151 N_("_Subversion"), /* Display label */
152 NULL, /* short-cut */
153 NULL, /* Tooltip */
154 NULL
157 "ActionPopupSubversionUpdate", /* Action name */
158 GTK_STOCK_REFRESH, /* Stock icon, if any */
159 N_("_Update..."), /* Display label */
160 NULL, /* short-cut */
161 N_("Sync your local copy with the Subversion tree"), /* Tooltip */
162 G_CALLBACK (on_fm_subversion_update) /* action callback */
165 "ActionPopupSubversionAdd", /* Action name */
166 GTK_STOCK_ADD, /* Stock icon, if any */
167 N_("_Add..."), /* Display label */
168 NULL, /* short-cut */
169 N_("Add a new file/directory to the Subversion tree"), /* Tooltip */
170 G_CALLBACK (on_fm_subversion_add) /* action callback */
173 "ActionPopupSubversionRemove", /* Action name */
174 GTK_STOCK_REMOVE, /* Stock icon, if any */
175 N_("_Remove..."), /* Display label */
176 NULL, /* short-cut */
177 N_("Remove a file/directory from Subversion tree"), /* Tooltip */
178 G_CALLBACK (on_fm_subversion_remove) /* action callback */
181 "ActionPopupSubversionLog", /* Action name */
182 GTK_STOCK_ZOOM_100, /* Stock icon, if any */
183 N_("_View Log..."), /* Display label */
184 NULL, /* short-cut */
185 N_("View file history"), /* Tooltip */
186 G_CALLBACK (on_fm_subversion_log) /* action callback */
189 "ActionPopupSubversionCopy", /* Action name */
190 GTK_STOCK_COPY, /* Stock icon, if any */
191 N_("Copy..."), /* Display label */
192 NULL, /* short-cut */
193 N_("Copy files/folders in the repository"), /* Tooltip */
194 G_CALLBACK (on_fm_subversion_copy) /* action callback */
197 "ActionPopupSubversionDiff", /* Action name */
198 GTK_STOCK_ZOOM_100, /* Stock icon, if any */
199 N_("Diff..."), /* Display label */
200 NULL, /* short-cut */
201 N_("Diff local tree with repository"), /* Tooltip */
202 G_CALLBACK (on_fm_subversion_diff) /* action callback */
206 static void
207 value_added_fm_current_uri (AnjutaPlugin *plugin, const char *name,
208 const GValue *value, gpointer data)
210 AnjutaUI *ui;
211 GtkAction *subversion_menu_action;
212 const gchar *uri;
213 GnomeVFSURI *subversion_uri = NULL;
214 gchar *subversion_text_uri = NULL;
215 gchar *subversion_dir;
216 gchar *filename;
217 GnomeVFSDirectoryHandle* handle;
218 GnomeVFSFileInfo info;
219 GnomeVFSResult result;
221 uri = g_value_get_string (value);
222 filename = gnome_vfs_get_local_path_from_uri (uri);
223 g_return_if_fail (filename != NULL);
225 Subversion *subversion = ANJUTA_PLUGIN_SUBVERSION (plugin);
226 ui = anjuta_shell_get_ui (plugin->shell, NULL);
228 if (subversion->fm_current_filename)
229 g_free (subversion->fm_current_filename);
230 subversion->fm_current_filename = filename;
232 /* Show popup menu if Subversion directory exists */
233 subversion_menu_action = anjuta_ui_get_action (ui, "ActionGroupPopupSubversion", "ActionPopupSubversion");
235 /* If a directory is selected we check if it contains a "Subversion" directory,
236 if it is a file we check if it's directory contains a "Subversion" directory */
237 result = gnome_vfs_get_file_info(uri, &info,
238 GNOME_VFS_FILE_INFO_DEFAULT);
239 if (result == GNOME_VFS_OK)
241 if (info.type == GNOME_VFS_FILE_TYPE_DIRECTORY)
243 /* Is "Subversion" a valid svn directory in a local checkout,
244 * If yes, we should check for both .svn and Subversion.
246 /* subversion_dir = g_build_filename (uri, "Subversion", NULL); */
247 subversion_dir = g_build_filename (uri, ".svn", NULL);
250 else
252 subversion_uri = gnome_vfs_uri_new (uri);
253 subversion_text_uri = gnome_vfs_uri_extract_dirname(subversion_uri);
254 /* subversion_dir = g_strconcat(subversion_text_uri, "/Subversion", NULL); */
255 subversion_dir = g_build_filename(subversion_text_uri, ".svn", NULL);
256 g_free(subversion_text_uri);
257 gnome_vfs_uri_unref(subversion_uri);
260 else
261 return; /* Strange... */
262 if (gnome_vfs_directory_open(&handle, subversion_dir,
263 GNOME_VFS_FILE_INFO_DEFAULT) == GNOME_VFS_OK)
266 g_object_set (G_OBJECT (subversion_menu_action), "sensitive", TRUE, NULL);
268 else
270 g_object_set (G_OBJECT (subversion_menu_action), "sensitive", FALSE, NULL);
272 g_free (subversion_dir);
275 static void
276 value_removed_fm_current_uri (AnjutaPlugin *plugin,
277 const char *name, gpointer data)
279 AnjutaUI *ui;
280 GtkAction *action;
282 Subversion *subversion = ANJUTA_PLUGIN_SUBVERSION (plugin);
284 if (subversion->fm_current_filename)
285 g_free (subversion->fm_current_filename);
286 subversion->fm_current_filename = NULL;
288 ui = anjuta_shell_get_ui (plugin->shell, NULL);
289 action = anjuta_ui_get_action (ui, "ActionGroupPopupSubversion", "ActionPopupSubversion");
290 g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
293 static void
294 value_added_project_root_uri (AnjutaPlugin *plugin, const gchar *name,
295 const GValue *value, gpointer user_data)
297 Subversion *bb_plugin;
298 const gchar *root_uri;
299 GtkAction *commit_action;
300 GtkAction *revert_action;
301 GtkAction *resolve_action;
303 bb_plugin = ANJUTA_PLUGIN_SUBVERSION (plugin);
304 commit_action = anjuta_ui_get_action (anjuta_shell_get_ui (plugin->shell,
305 NULL),
306 "ActionGroupSubversion",
307 "ActionSubversionCommit");
308 revert_action = anjuta_ui_get_action (anjuta_shell_get_ui (plugin->shell,
309 NULL),
310 "ActionGroupSubversion",
311 "ActionSubversionRevert");
312 resolve_action = anjuta_ui_get_action (anjuta_shell_get_ui (plugin->shell,
313 NULL),
314 "ActionGroupSubversion",
315 "ActionSubversionResolve");
317 DEBUG_PRINT ("Project added");
319 if (bb_plugin->project_root_dir)
320 g_free (bb_plugin->project_root_dir);
321 bb_plugin->project_root_dir = NULL;
323 root_uri = g_value_get_string (value);
324 if (root_uri)
326 bb_plugin->project_root_dir =
327 gnome_vfs_get_local_path_from_uri (root_uri);
328 if (bb_plugin->project_root_dir)
330 // update_project_ui (bb_plugin);
331 subversion_log_set_whole_project_sensitive (bb_plugin->log_gxml,
332 TRUE);
333 gtk_action_set_sensitive (commit_action, TRUE);
334 gtk_action_set_sensitive (revert_action, TRUE);
335 gtk_action_set_sensitive (resolve_action, TRUE);
342 static void
343 value_removed_project_root_uri (AnjutaPlugin *plugin, const gchar *name,
344 gpointer user_data)
346 Subversion *bb_plugin;
347 GtkAction *commit_action;
348 GtkAction *revert_action;
349 GtkAction *resolve_action;
351 bb_plugin = ANJUTA_PLUGIN_SUBVERSION (plugin);
352 commit_action = anjuta_ui_get_action (anjuta_shell_get_ui (plugin->shell,
353 NULL),
354 "ActionGroupSubversion",
355 "ActionSubversionCommit");
356 revert_action = anjuta_ui_get_action (anjuta_shell_get_ui (plugin->shell,
357 NULL),
358 "ActionGroupSubversion",
359 "ActionSubversionRevert");
360 resolve_action = anjuta_ui_get_action (anjuta_shell_get_ui (plugin->shell,
361 NULL),
362 "ActionGroupSubversion",
363 "ActionSubversionResolve");
365 if (bb_plugin->project_root_dir)
366 g_free (bb_plugin->project_root_dir);
367 bb_plugin->project_root_dir = NULL;
368 // update_project_ui (bb_plugin);
370 subversion_log_set_whole_project_sensitive (bb_plugin->log_gxml,
371 FALSE);
372 gtk_action_set_sensitive (commit_action, FALSE);
373 gtk_action_set_sensitive (revert_action, FALSE);
374 gtk_action_set_sensitive (resolve_action, FALSE);
377 static void
378 value_added_current_editor (AnjutaPlugin *plugin, const char *name,
379 const GValue *value, gpointer data)
381 AnjutaUI *ui;
382 gchar *uri;
383 GObject *editor;
385 editor = g_value_get_object (value);
387 if (!IANJUTA_IS_EDITOR(editor))
388 return;
390 Subversion *subversion = ANJUTA_PLUGIN_SUBVERSION (plugin);
391 ui = anjuta_shell_get_ui (plugin->shell, NULL);
393 if (subversion->current_editor_filename)
394 g_free (subversion->current_editor_filename);
395 subversion->current_editor_filename = NULL;
397 uri = ianjuta_file_get_uri (IANJUTA_FILE (editor), NULL);
398 if (uri)
400 gchar *filename;
402 filename = gnome_vfs_get_local_path_from_uri (uri);
403 g_return_if_fail (filename != NULL);
404 subversion->current_editor_filename = filename;
405 g_free (uri);
406 // update_module_ui (subversion);
410 static void
411 value_removed_current_editor (AnjutaPlugin *plugin,
412 const char *name, gpointer data)
414 Subversion *subversion = ANJUTA_PLUGIN_SUBVERSION (plugin);
416 if (subversion->current_editor_filename)
417 g_free (subversion->current_editor_filename);
418 subversion->current_editor_filename = NULL;
420 // update_module_ui (subversion);
423 static gboolean
424 activate_plugin (AnjutaPlugin *plugin)
426 AnjutaUI *ui;
427 Subversion *subversion;
428 GtkAction *commit_action;
429 GtkAction *revert_action;
430 GtkAction *resolve_action;
432 DEBUG_PRINT ("Subversion: Activating Subversion plugin ...");
433 subversion = ANJUTA_PLUGIN_SUBVERSION (plugin);
435 ui = anjuta_shell_get_ui (plugin->shell, NULL);
437 /* Add all our actions */
438 subversion->action_group =
439 anjuta_ui_add_action_group_entries (ui, "ActionGroupSubversion",
440 _("Subversion operations"),
441 actions_subversion,
442 G_N_ELEMENTS (actions_subversion),
443 GETTEXT_PACKAGE, TRUE, plugin);
444 subversion->popup_action_group =
445 anjuta_ui_add_action_group_entries (ui, "ActionGroupPopupSubversion",
446 _("Subversion popup operations"),
447 popup_actions_subversion,
448 G_N_ELEMENTS (popup_actions_subversion),
449 GETTEXT_PACKAGE, FALSE, plugin);
451 /* Merge UI */
452 subversion->uiid = anjuta_ui_merge (ui, UI_FILE);
454 subversion->log_gxml = glade_xml_new (GLADE_FILE, "subversion_log",
455 NULL);
457 /* Add watches */
458 subversion->fm_watch_id =
459 anjuta_plugin_add_watch (plugin, "file_manager_current_uri",
460 value_added_fm_current_uri,
461 value_removed_fm_current_uri, NULL);
462 subversion->project_watch_id =
463 anjuta_plugin_add_watch (plugin, "project_root_uri",
464 value_added_project_root_uri,
465 value_removed_project_root_uri, NULL);
466 subversion->editor_watch_id =
467 anjuta_plugin_add_watch (plugin, "document_manager_current_editor",
468 value_added_current_editor,
469 value_removed_current_editor, NULL);
471 subversion->log_viewer = subversion_log_window_create (subversion);
472 anjuta_shell_add_widget (plugin->shell, subversion->log_viewer,
473 "AnjutaSubversionLogViewer",
474 _("Subversion Log"),
475 GTK_STOCK_ZOOM_100,
476 ANJUTA_SHELL_PLACEMENT_CENTER,
477 NULL);
479 g_object_unref (subversion->log_viewer);
481 commit_action = anjuta_ui_get_action (anjuta_shell_get_ui (plugin->shell,
482 NULL),
483 "ActionGroupSubversion",
484 "ActionSubversionCommit");
485 revert_action = anjuta_ui_get_action (anjuta_shell_get_ui (plugin->shell,
486 NULL),
487 "ActionGroupSubversion",
488 "ActionSubversionRevert");
489 resolve_action = anjuta_ui_get_action (anjuta_shell_get_ui (plugin->shell,
490 NULL),
491 "ActionGroupSubversion",
492 "ActionSubversionResolve");
494 if (!subversion->project_root_dir)
496 gtk_action_set_sensitive (commit_action, FALSE);
497 gtk_action_set_sensitive (revert_action, FALSE);
498 gtk_action_set_sensitive (resolve_action, FALSE);
501 return TRUE;
504 static gboolean
505 deactivate_plugin (AnjutaPlugin *plugin)
507 Subversion *subversion = ANJUTA_PLUGIN_SUBVERSION (plugin);
508 AnjutaUI *ui = anjuta_shell_get_ui (plugin->shell, NULL);
509 DEBUG_PRINT ("Subversion: Dectivating Subversion plugin ...");
510 anjuta_plugin_remove_watch (plugin, subversion->fm_watch_id, TRUE);
511 anjuta_plugin_remove_watch (plugin, subversion->project_watch_id, TRUE);
512 anjuta_plugin_remove_watch (plugin, subversion->editor_watch_id, TRUE);
513 anjuta_ui_unmerge (ui, ANJUTA_PLUGIN_SUBVERSION (plugin)->uiid);
514 anjuta_ui_remove_action_group (ui, ANJUTA_PLUGIN_SUBVERSION (plugin)->action_group);
515 anjuta_ui_remove_action_group (ui, ANJUTA_PLUGIN_SUBVERSION (plugin)->popup_action_group);
517 anjuta_shell_remove_widget (plugin->shell,
518 ANJUTA_PLUGIN_SUBVERSION (plugin)->log_viewer,
519 NULL);
521 g_object_unref (ANJUTA_PLUGIN_SUBVERSION (plugin)->log_gxml);
523 return TRUE;
526 static void
527 finalize (GObject *obj)
529 apr_terminate ();
530 G_OBJECT_CLASS (parent_class)->finalize (obj);
533 static void
534 dispose (GObject *obj)
536 // Subversion *plugin = ANJUTA_PLUGIN_SUBVERSION (obj);
537 G_OBJECT_CLASS (parent_class)->dispose (obj);
540 static void
541 subversion_instance_init (GObject *obj)
543 Subversion *plugin = ANJUTA_PLUGIN_SUBVERSION (obj);
544 plugin->uiid = 0;
545 plugin->mesg_view = NULL;
546 plugin->launcher = NULL;
547 plugin->fm_current_filename = NULL;
548 plugin->project_root_dir = NULL;
549 plugin->current_editor_filename = NULL;
550 plugin->log_gxml = NULL;
551 plugin->log_viewer = NULL;
553 apr_initialize ();
556 static void
557 subversion_class_init (GObjectClass *klass)
559 AnjutaPluginClass *plugin_class = ANJUTA_PLUGIN_CLASS (klass);
561 parent_class = g_type_class_peek_parent (klass);
563 plugin_class->activate = activate_plugin;
564 plugin_class->deactivate = deactivate_plugin;
565 klass->dispose = dispose;
566 klass->finalize = finalize;
569 ANJUTA_PLUGIN_BEGIN (Subversion, subversion);
570 ANJUTA_PLUGIN_END;
572 ANJUTA_SIMPLE_PLUGIN (Subversion, subversion);