Implement rebasing
[anjuta-git-plugin.git] / plugins / git / plugin.c
blob10fce230e5f593f601634b5795e5c207f44657e3
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 plugin.c
4 Copyright (C) James Liggett 2008
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,
19 Boston, MA 02110-1301 USA
22 #include "plugin.h"
23 #include "git-diff-dialog.h"
24 #include "git-commit-dialog.h"
25 #include "git-add-dialog.h"
26 #include "git-remove-dialog.h"
27 #include "git-resolve-dialog.h"
28 #include "git-merge-dialog.h"
29 #include "git-switch-dialog.h"
30 #include "git-create-branch-dialog.h"
31 #include "git-delete-branch-dialog.h"
32 #include "git-unstage-dialog.h"
33 #include "git-checkout-files-dialog.h"
34 #include "git-log-dialog.h"
35 #include "git-create-tag-dialog.h"
36 #include "git-reset-dialog.h"
37 #include "git-revert-dialog.h"
38 #include "git-fetch-dialog.h"
39 #include "git-rebase-dialog.h"
41 #define UI_FILE PACKAGE_DATA_DIR"/ui/anjuta-git.ui"
43 static gpointer parent_class;
45 static GtkActionEntry actions_git[] =
48 "ActionMenuGit", /* Action name */
49 NULL, /* Stock icon, if any */
50 N_("_Git"), /* Display label */
51 NULL, /* short-cut */
52 NULL, /* Tooltip */
53 NULL /* action callback */
56 "ActionGitCommit", /* Action name */
57 GTK_STOCK_YES, /* Stock icon, if any */
58 N_("_Commit..."), /* Display label */
59 NULL, /* short-cut */
60 NULL, /* Tooltip */
61 G_CALLBACK (on_menu_git_commit) /* action callback */
64 "ActionGitFetch", /* Action name */
65 GTK_STOCK_CONNECT, /* Stock icon, if any */
66 N_("_Fetch"), /* Display label */
67 NULL, /* short-cut */
68 NULL, /* Tooltip */
69 G_CALLBACK (on_menu_git_fetch) /* action callback */
72 "ActionMenuGitRebase", /* Action name */
73 NULL, /* Stock icon, if any */
74 N_("_Rebase"), /* Display label */
75 NULL, /* short-cut */
76 NULL, /* Tooltip */
77 NULL /* action callback */
80 "ActionGitRebaseStart", /* Action name */
81 NULL, /* Stock icon, if any */
82 N_("_Start..."), /* Display label */
83 NULL, /* short-cut */
84 NULL, /* Tooltip */
85 G_CALLBACK (on_menu_git_rebase_start) /* action callback */
88 "ActionGitRebaseContinue", /* Action name */
89 NULL, /* Stock icon, if any */
90 N_("_Continue"), /* Display label */
91 NULL, /* short-cut */
92 NULL, /* Tooltip */
93 G_CALLBACK (on_menu_git_rebase_continue) /* action callback */
96 "ActionGitRebaseSkip", /* Action name */
97 NULL, /* Stock icon, if any */
98 N_("_Skip"), /* Display label */
99 NULL, /* short-cut */
100 NULL, /* Tooltip */
101 G_CALLBACK (on_menu_git_rebase_skip) /* action callback */
104 "ActionGitRebaseAbort", /* Action name */
105 NULL, /* Stock icon, if any */
106 N_("_Abort"), /* Display label */
107 NULL, /* short-cut */
108 NULL, /* Tooltip */
109 G_CALLBACK (on_menu_git_rebase_abort) /* action callback */
112 "ActionGitUnstageFiles", /* Action name */
113 GTK_STOCK_CANCEL, /* Stock icon, if any */
114 N_("_Unstage files..."), /* Display label */
115 NULL, /* short-cut */
116 NULL, /* Tooltip */
117 G_CALLBACK (on_menu_git_unstage) /* action callback */
120 "ActionGitCheckoutFiles", /* Action name */
121 GTK_STOCK_UNDO, /* Stock icon, if any */
122 N_("_Check out files..."), /* Display label */
123 NULL, /* short-cut */
124 NULL, /* Tooltip */
125 G_CALLBACK (on_menu_git_checkout_files) /* action callback */
128 "ActionGitResolve", /* Action name */
129 GTK_STOCK_PREFERENCES, /* Stock icon, if any */
130 N_("_Resolve conflicts..."), /* Display label */
131 NULL, /* short-cut */
132 NULL, /* Tooltip */
133 G_CALLBACK (on_menu_git_resolve) /* action callback */
136 "ActionGitReset", /* Action name */
137 GTK_STOCK_REFRESH, /* Stock icon, if any */
138 N_("_Reset tree..."), /* Display label */
139 NULL, /* short-cut */
140 NULL, /* Tooltip */
141 G_CALLBACK (on_menu_git_reset) /* action callback */
144 "ActionGitRevert", /* Action name */
145 GTK_STOCK_UNDO, /* Stock icon, if any */
146 N_("_Revert commit..."), /* Display label */
147 NULL, /* short-cut */
148 NULL, /* Tooltip */
149 G_CALLBACK (on_menu_git_revert) /* action callback */
152 "ActionGitLog", /* Action name */
153 GTK_STOCK_ZOOM_100, /* Stock icon, if any */
154 N_("_View log..."), /* Display label */
155 NULL, /* short-cut */
156 NULL, /* Tooltip */
157 G_CALLBACK (on_menu_git_log) /* action callback */
160 "ActionGitAdd", /* Action name */
161 GTK_STOCK_ADD, /* Stock icon, if any */
162 N_("_Add..."), /* Display label */
163 NULL, /* short-cut */
164 NULL, /* Tooltip */
165 G_CALLBACK (on_menu_git_add) /* action callback */
168 "ActionGitRemove", /* Action name */
169 GTK_STOCK_REMOVE, /* Stock icon, if any */
170 N_("_Remove..."), /* Display label */
171 NULL, /* short-cut */
172 NULL, /* Tooltip */
173 G_CALLBACK (on_menu_git_remove) /* action callback */
176 "ActionGitCreateBranch", /* Action name */
177 NULL, /* Stock icon, if any */
178 N_("_Create branch..."), /* Display label */
179 NULL, /* short-cut */
180 NULL, /* Tooltip */
181 G_CALLBACK (on_menu_git_create_branch) /* action callback */
184 "ActionGitDeleteBranch", /* Action name */
185 GTK_STOCK_DELETE, /* Stock icon, if any */
186 N_("_Delete branch..."), /* Display label */
187 NULL, /* short-cut */
188 NULL, /* Tooltip */
189 G_CALLBACK (on_menu_git_delete_branch) /* action callback */
192 "ActionGitSwitch", /* Action name */
193 GTK_STOCK_JUMP_TO, /* Stock icon, if any */
194 N_("_Switch to another branch..."), /* Display label */
195 NULL, /* short-cut */
196 NULL, /* Tooltip */
197 G_CALLBACK (on_menu_git_switch) /* action callback */
200 "ActionGitMerge", /* Action name */
201 GTK_STOCK_CONVERT, /* Stock icon, if any */
202 N_("_Merge..."), /* Display label */
203 NULL, /* short-cut */
204 NULL, /* Tooltip */
205 G_CALLBACK (on_menu_git_merge) /* action callback */
208 "ActionGitCreateTag", /* Action name */
209 NULL, /* Stock icon, if any */
210 N_("_Create tag..."), /* Display label */
211 NULL, /* short-cut */
212 NULL, /* Tooltip */
213 G_CALLBACK (on_menu_git_create_tag) /* action callback */
216 "ActionGitDiffUncommitted", /* Action name */
217 GTK_STOCK_ZOOM_100, /* Stock icon, if any */
218 N_("_Diff uncommitted changes"), /* Display label */
219 NULL, /* short-cut */
220 NULL, /* Tooltip */
221 G_CALLBACK (on_menu_git_diff) /* action callback */
225 static GtkActionEntry actions_log[] =
228 "ActionGitLogCommitDiff", /* Action name */
229 GTK_STOCK_ZOOM_100, /* Stock icon, if any */
230 N_("_Show commit diff"), /* Display label */
231 NULL, /* short-cut */
232 NULL, /* Tooltip */
233 G_CALLBACK (on_log_menu_git_commit_diff) /* action callback */
236 "ActionGitLogCreateBranch", /* Action name */
237 NULL, /* Stock icon, if any */
238 N_("_Create branch..."), /* Display label */
239 NULL, /* short-cut */
240 NULL, /* Tooltip */
241 G_CALLBACK (on_log_menu_git_create_branch) /* action callback */
244 "ActionGitLogCreateTag", /* Action name */
245 NULL, /* Stock icon, if any */
246 N_("_Create tag..."), /* Display label */
247 NULL, /* short-cut */
248 NULL, /* Tooltip */
249 G_CALLBACK (on_log_menu_git_create_tag) /* action callback */
252 "ActionGitLogReset", /* Action name */
253 GTK_STOCK_REFRESH, /* Stock icon, if any */
254 N_("_Reset tree..."), /* Display label */
255 NULL, /* short-cut */
256 NULL, /* Tooltip */
257 G_CALLBACK (on_log_menu_git_reset) /* action callback */
260 "ActionGitLogRevert", /* Action name */
261 GTK_STOCK_UNDO, /* Stock icon, if any */
262 N_("_Revert commit..."), /* Display label */
263 NULL, /* short-cut */
264 NULL, /* Tooltip */
265 G_CALLBACK (on_log_menu_git_revert) /* action callback */
269 static void
270 on_project_root_added (AnjutaPlugin *plugin, const gchar *name,
271 const GValue *value, gpointer user_data)
273 Git *git_plugin;
274 gchar *project_root_uri;
275 GtkAction *git_menu_action;
277 git_plugin = ANJUTA_PLUGIN_GIT (plugin);
279 g_free (git_plugin->project_root_directory);
280 project_root_uri = g_value_dup_string (value);
281 git_plugin->project_root_directory = gnome_vfs_get_local_path_from_uri (project_root_uri);
283 git_menu_action = anjuta_ui_get_action (anjuta_shell_get_ui (plugin->shell,
284 NULL),
285 "ActionGroupGit",
286 "ActionMenuGit");
288 gtk_action_set_sensitive (git_menu_action, TRUE);
289 gtk_widget_set_sensitive (git_plugin->log_viewer, TRUE);
291 g_free (project_root_uri);
294 static void
295 on_project_root_removed (AnjutaPlugin *plugin, const gchar *name,
296 gpointer user_data)
298 GtkAction *git_menu_action;
299 Git *git_plugin;
301 git_plugin = ANJUTA_PLUGIN_GIT (plugin);
303 g_free (git_plugin->project_root_directory);
304 git_plugin->project_root_directory = NULL;
306 git_menu_action = anjuta_ui_get_action (anjuta_shell_get_ui (plugin->shell,
307 NULL),
308 "ActionGroupGit",
309 "ActionMenuGit");
311 gtk_action_set_sensitive (git_menu_action, FALSE);
312 gtk_widget_set_sensitive (git_plugin->log_viewer, FALSE);
313 git_log_window_clear (git_plugin);
316 static void
317 on_editor_added (AnjutaPlugin *plugin, const gchar *name, const GValue *value,
318 gpointer user_data)
320 Git *git_plugin;
321 gchar *current_editor_uri;
322 IAnjutaEditor *editor;
324 git_plugin = ANJUTA_PLUGIN_GIT (plugin);
325 editor = g_value_get_object (value);
327 if (IANJUTA_IS_EDITOR (editor))
329 g_free (git_plugin->current_editor_filename);
330 current_editor_uri = ianjuta_file_get_uri (IANJUTA_FILE (editor), NULL);
331 git_plugin->current_editor_filename = gnome_vfs_get_local_path_from_uri (current_editor_uri);
335 static void
336 on_editor_removed (AnjutaPlugin *plugin, const gchar *name, gpointer user_data)
338 Git *git_plugin;
340 git_plugin = ANJUTA_PLUGIN_GIT (plugin);
342 g_free (git_plugin->current_editor_filename);
343 git_plugin->current_editor_filename = NULL;
346 static gboolean
347 git_activate_plugin (AnjutaPlugin *plugin)
349 AnjutaUI *ui;
350 Git *git_plugin;
351 GtkAction *git_menu_action;
353 DEBUG_PRINT ("Git: Activating Git plugin ...");
355 git_plugin = ANJUTA_PLUGIN_GIT (plugin);
356 ui = anjuta_shell_get_ui (plugin->shell, NULL);
358 /* Add all our actions */
359 anjuta_ui_add_action_group_entries (ui, "ActionGroupGit",
360 _("Git operations"),
361 actions_git,
362 G_N_ELEMENTS (actions_git),
363 GETTEXT_PACKAGE, TRUE, plugin);
364 anjuta_ui_add_action_group_entries (ui, "ActionGroupGitLog",
365 _("Git log operations"),
366 actions_log,
367 G_N_ELEMENTS (actions_log),
368 GETTEXT_PACKAGE, TRUE, plugin);
370 git_plugin->uiid = anjuta_ui_merge (ui, UI_FILE);
372 git_plugin->log_popup_menu = gtk_ui_manager_get_widget (GTK_UI_MANAGER (ui),
373 "/PopupLog");
375 /* Add watches */
376 git_plugin->project_root_watch_id = anjuta_plugin_add_watch (plugin,
377 "project_root_uri",
378 on_project_root_added,
379 on_project_root_removed,
380 NULL);
382 git_plugin->editor_watch_id = anjuta_plugin_add_watch (plugin,
383 "document_manager_current_editor",
384 on_editor_added,
385 on_editor_removed,
386 NULL);
388 /* Log viewer */
389 git_plugin->log_viewer = git_log_window_create (git_plugin);
390 anjuta_shell_add_widget (plugin->shell,
391 git_plugin->log_viewer,
392 "GitLogViewer",
393 _("Git Log"),
394 GTK_STOCK_ZOOM_100,
395 ANJUTA_SHELL_PLACEMENT_CENTER,
396 NULL);
397 g_object_unref (git_plugin->log_viewer);
401 /* Git needs a working directory to work with; it can't take full paths,
402 * so make sure that Git can't be used if there's no project opened. */
403 git_menu_action = anjuta_ui_get_action (anjuta_shell_get_ui (plugin->shell,
404 NULL),
405 "ActionGroupGit",
406 "ActionMenuGit");
408 if (!git_plugin->project_root_directory)
410 gtk_action_set_sensitive (git_menu_action, FALSE);
411 gtk_widget_set_sensitive (git_plugin->log_viewer, FALSE);
414 return TRUE;
417 static gboolean
418 git_deactivate_plugin (AnjutaPlugin *plugin)
420 AnjutaUI *ui = anjuta_shell_get_ui (plugin->shell, NULL);
421 Git *git_plugin;
423 git_plugin = ANJUTA_PLUGIN_GIT (plugin);
425 DEBUG_PRINT ("Git: Dectivating Git plugin ...");
426 anjuta_ui_unmerge (ui, git_plugin->uiid);
427 anjuta_plugin_remove_watch (plugin, git_plugin->project_root_watch_id,
428 TRUE);
429 anjuta_plugin_remove_watch (plugin, git_plugin->editor_watch_id,
430 TRUE);
432 anjuta_shell_remove_widget (plugin->shell, git_plugin->log_viewer, NULL);
433 gtk_widget_destroy (git_plugin->log_popup_menu);
435 return TRUE;
438 static void
439 git_finalize (GObject *obj)
441 /* Finalization codes here */
442 G_OBJECT_CLASS (parent_class)->finalize (obj);
445 static void
446 git_dispose (GObject *obj)
448 /* Disposition codes */
449 G_OBJECT_CLASS (parent_class)->dispose (obj);
452 static void
453 git_instance_init (GObject *obj)
455 Git *plugin = ANJUTA_PLUGIN_GIT (obj);
456 plugin->uiid = 0;
459 static void
460 git_class_init (GObjectClass *klass)
462 AnjutaPluginClass *plugin_class = ANJUTA_PLUGIN_CLASS (klass);
464 parent_class = g_type_class_peek_parent (klass);
466 plugin_class->activate = git_activate_plugin;
467 plugin_class->deactivate = git_deactivate_plugin;
468 klass->finalize = git_finalize;
469 klass->dispose = git_dispose;
472 ANJUTA_PLUGIN_BOILERPLATE (Git, git);
473 ANJUTA_SIMPLE_PLUGIN (Git, git);