Implement patch series creation
[anjuta-git-plugin.git] / plugins / git / plugin.c
bloba33dc66636f5c2fd3fb19904003e692a6dab234a
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"
40 #include "git-bisect-dialog.h"
41 #include "git-ignore-dialog.h"
42 #include "git-add-remote-dialog.h"
43 #include "git-delete-remote-dialog.h"
44 #include "git-create-patch-series-dialog.h"
46 #define UI_FILE PACKAGE_DATA_DIR"/ui/anjuta-git.ui"
48 static gpointer parent_class;
50 static GtkActionEntry actions_git[] =
53 "ActionMenuGit", /* Action name */
54 NULL, /* Stock icon, if any */
55 N_("_Git"), /* Display label */
56 NULL, /* short-cut */
57 NULL, /* Tooltip */
58 NULL /* action callback */
61 "ActionGitCommit", /* Action name */
62 GTK_STOCK_YES, /* Stock icon, if any */
63 N_("_Commit..."), /* Display label */
64 NULL, /* short-cut */
65 NULL, /* Tooltip */
66 G_CALLBACK (on_menu_git_commit) /* action callback */
69 "ActionGitFetch", /* Action name */
70 GTK_STOCK_CONNECT, /* Stock icon, if any */
71 N_("_Fetch"), /* Display label */
72 NULL, /* short-cut */
73 NULL, /* Tooltip */
74 G_CALLBACK (on_menu_git_fetch) /* action callback */
77 "ActionMenuGitRebase", /* Action name */
78 NULL, /* Stock icon, if any */
79 N_("_Rebase"), /* Display label */
80 NULL, /* short-cut */
81 NULL, /* Tooltip */
82 NULL /* action callback */
85 "ActionGitRebaseStart", /* Action name */
86 NULL, /* Stock icon, if any */
87 N_("_Start..."), /* Display label */
88 NULL, /* short-cut */
89 NULL, /* Tooltip */
90 G_CALLBACK (on_menu_git_rebase_start) /* action callback */
93 "ActionGitRebaseContinue", /* Action name */
94 NULL, /* Stock icon, if any */
95 N_("_Continue"), /* Display label */
96 NULL, /* short-cut */
97 NULL, /* Tooltip */
98 G_CALLBACK (on_menu_git_rebase_continue) /* action callback */
101 "ActionGitRebaseSkip", /* Action name */
102 NULL, /* Stock icon, if any */
103 N_("_Skip"), /* Display label */
104 NULL, /* short-cut */
105 NULL, /* Tooltip */
106 G_CALLBACK (on_menu_git_rebase_skip) /* action callback */
109 "ActionGitRebaseAbort", /* Action name */
110 NULL, /* Stock icon, if any */
111 N_("_Abort"), /* Display label */
112 NULL, /* short-cut */
113 NULL, /* Tooltip */
114 G_CALLBACK (on_menu_git_rebase_abort) /* action callback */
117 "ActionGitUnstageFiles", /* Action name */
118 GTK_STOCK_CANCEL, /* Stock icon, if any */
119 N_("_Unstage files..."), /* Display label */
120 NULL, /* short-cut */
121 NULL, /* Tooltip */
122 G_CALLBACK (on_menu_git_unstage) /* action callback */
125 "ActionGitCheckoutFiles", /* Action name */
126 GTK_STOCK_UNDO, /* Stock icon, if any */
127 N_("_Check out files..."), /* Display label */
128 NULL, /* short-cut */
129 NULL, /* Tooltip */
130 G_CALLBACK (on_menu_git_checkout_files) /* action callback */
133 "ActionGitResolve", /* Action name */
134 GTK_STOCK_PREFERENCES, /* Stock icon, if any */
135 N_("_Resolve conflicts..."), /* Display label */
136 NULL, /* short-cut */
137 NULL, /* Tooltip */
138 G_CALLBACK (on_menu_git_resolve) /* action callback */
141 "ActionGitCreatePatchSeries", /* Action name */
142 GTK_STOCK_DND_MULTIPLE, /* Stock icon, if any */
143 N_("Create patch series..."), /* Display label */
144 NULL, /* short-cut */
145 NULL, /* Tooltip */
146 G_CALLBACK (on_menu_git_create_patch_series) /* action callback */
149 "ActionGitReset", /* Action name */
150 GTK_STOCK_REFRESH, /* Stock icon, if any */
151 N_("_Reset tree..."), /* Display label */
152 NULL, /* short-cut */
153 NULL, /* Tooltip */
154 G_CALLBACK (on_menu_git_reset) /* action callback */
157 "ActionGitRevert", /* Action name */
158 GTK_STOCK_UNDO, /* Stock icon, if any */
159 N_("_Revert commit..."), /* Display label */
160 NULL, /* short-cut */
161 NULL, /* Tooltip */
162 G_CALLBACK (on_menu_git_revert) /* action callback */
165 "ActionMenuGitBisect", /* Action name */
166 NULL, /* Stock icon, if any */
167 N_("_Bisect"), /* Display label */
168 NULL, /* short-cut */
169 NULL, /* Tooltip */
170 NULL /* action callback */
173 "ActionGitBisectStart", /* Action name */
174 GTK_STOCK_MEDIA_PLAY, /* Stock icon, if any */
175 N_("_Start..."), /* Display label */
176 NULL, /* short-cut */
177 NULL, /* Tooltip */
178 G_CALLBACK (on_menu_git_bisect_start) /* action callback */
181 "ActionGitBisectReset", /* Action name */
182 GTK_STOCK_REFRESH, /* Stock icon, if any */
183 N_("_Reset"), /* Display label */
184 NULL, /* short-cut */
185 NULL, /* Tooltip */
186 G_CALLBACK (on_menu_git_bisect_reset) /* action callback */
189 "ActionGitBisectGood", /* Action name */
190 GTK_STOCK_YES, /* Stock icon, if any */
191 N_("_Good"), /* Display label */
192 NULL, /* short-cut */
193 NULL, /* Tooltip */
194 G_CALLBACK (on_menu_git_bisect_good) /* action callback */
197 "ActionGitBisectBad", /* Action name */
198 GTK_STOCK_NO, /* Stock icon, if any */
199 N_("_Bad"), /* Display label */
200 NULL, /* short-cut */
201 NULL, /* Tooltip */
202 G_CALLBACK (on_menu_git_bisect_bad) /* action callback */
205 "ActionGitLog", /* Action name */
206 GTK_STOCK_ZOOM_100, /* Stock icon, if any */
207 N_("_View log..."), /* Display label */
208 NULL, /* short-cut */
209 NULL, /* Tooltip */
210 G_CALLBACK (on_menu_git_log) /* action callback */
213 "ActionGitAdd", /* Action name */
214 GTK_STOCK_ADD, /* Stock icon, if any */
215 N_("_Add..."), /* Display label */
216 NULL, /* short-cut */
217 NULL, /* Tooltip */
218 G_CALLBACK (on_menu_git_add) /* action callback */
221 "ActionGitRemove", /* Action name */
222 GTK_STOCK_REMOVE, /* Stock icon, if any */
223 N_("_Remove..."), /* Display label */
224 NULL, /* short-cut */
225 NULL, /* Tooltip */
226 G_CALLBACK (on_menu_git_remove) /* action callback */
229 "ActionGitIgnore", /* Action name */
230 GTK_STOCK_DIALOG_ERROR, /* Stock icon, if any */
231 N_("_Ignore..."), /* Display label */
232 NULL, /* short-cut */
233 NULL, /* Tooltip */
234 G_CALLBACK (on_menu_git_ignore) /* action callback */
238 "ActionGitCreateBranch", /* Action name */
239 NULL, /* Stock icon, if any */
240 N_("_Create branch..."), /* Display label */
241 NULL, /* short-cut */
242 NULL, /* Tooltip */
243 G_CALLBACK (on_menu_git_create_branch) /* action callback */
246 "ActionGitDeleteBranch", /* Action name */
247 GTK_STOCK_DELETE, /* Stock icon, if any */
248 N_("_Delete branch..."), /* Display label */
249 NULL, /* short-cut */
250 NULL, /* Tooltip */
251 G_CALLBACK (on_menu_git_delete_branch) /* action callback */
254 "ActionGitSwitch", /* Action name */
255 GTK_STOCK_JUMP_TO, /* Stock icon, if any */
256 N_("_Switch to another branch..."), /* Display label */
257 NULL, /* short-cut */
258 NULL, /* Tooltip */
259 G_CALLBACK (on_menu_git_switch) /* action callback */
262 "ActionGitMerge", /* Action name */
263 GTK_STOCK_CONVERT, /* Stock icon, if any */
264 N_("_Merge..."), /* Display label */
265 NULL, /* short-cut */
266 NULL, /* Tooltip */
267 G_CALLBACK (on_menu_git_merge) /* action callback */
270 "ActionMenuGitRemoteBranches", /* Action name */
271 GTK_STOCK_NETWORK, /* Stock icon, if any */
272 N_("_Remote branches"), /* Display label */
273 NULL, /* short-cut */
274 NULL, /* Tooltip */
275 NULL /* action callback */
278 "ActionGitRemoteAdd", /* Action name */
279 GTK_STOCK_ADD, /* Stock icon, if any */
280 N_("_Add..."), /* Display label */
281 NULL, /* short-cut */
282 NULL, /* Tooltip */
283 G_CALLBACK (on_menu_git_add_remote) /* action callback */
286 "ActionGitRemoteDelete", /* Action name */
287 GTK_STOCK_DELETE, /* Stock icon, if any */
288 N_("_Delete..."), /* Display label */
289 NULL, /* short-cut */
290 NULL, /* Tooltip */
291 G_CALLBACK (on_menu_git_delete_remote) /* action callback */
294 "ActionGitCreateTag", /* Action name */
295 NULL, /* Stock icon, if any */
296 N_("_Create tag..."), /* Display label */
297 NULL, /* short-cut */
298 NULL, /* Tooltip */
299 G_CALLBACK (on_menu_git_create_tag) /* action callback */
302 "ActionGitDiffUncommitted", /* Action name */
303 GTK_STOCK_ZOOM_100, /* Stock icon, if any */
304 N_("_Diff uncommitted changes"), /* Display label */
305 NULL, /* short-cut */
306 NULL, /* Tooltip */
307 G_CALLBACK (on_menu_git_diff) /* action callback */
311 static GtkActionEntry actions_log[] =
314 "ActionGitLogCommitDiff", /* Action name */
315 GTK_STOCK_ZOOM_100, /* Stock icon, if any */
316 N_("_Show commit diff"), /* Display label */
317 NULL, /* short-cut */
318 NULL, /* Tooltip */
319 G_CALLBACK (on_log_menu_git_commit_diff) /* action callback */
322 "ActionGitLogCreateBranch", /* Action name */
323 NULL, /* Stock icon, if any */
324 N_("_Create branch..."), /* Display label */
325 NULL, /* short-cut */
326 NULL, /* Tooltip */
327 G_CALLBACK (on_log_menu_git_create_branch) /* action callback */
330 "ActionGitLogCreateTag", /* Action name */
331 NULL, /* Stock icon, if any */
332 N_("_Create tag..."), /* Display label */
333 NULL, /* short-cut */
334 NULL, /* Tooltip */
335 G_CALLBACK (on_log_menu_git_create_tag) /* action callback */
338 "ActionGitLogReset", /* Action name */
339 GTK_STOCK_REFRESH, /* Stock icon, if any */
340 N_("_Reset tree..."), /* Display label */
341 NULL, /* short-cut */
342 NULL, /* Tooltip */
343 G_CALLBACK (on_log_menu_git_reset) /* action callback */
346 "ActionGitLogRevert", /* Action name */
347 GTK_STOCK_UNDO, /* Stock icon, if any */
348 N_("_Revert commit..."), /* Display label */
349 NULL, /* short-cut */
350 NULL, /* Tooltip */
351 G_CALLBACK (on_log_menu_git_revert) /* action callback */
354 "ActionMenuGitLogBisect", /* Action name */
355 NULL, /* Stock icon, if any */
356 N_("_Bisect"), /* Display label */
357 NULL, /* short-cut */
358 NULL, /* Tooltip */
359 NULL /* action callback */
362 "ActionGitLogBisectGood", /* Action name */
363 GTK_STOCK_YES, /* Stock icon, if any */
364 N_("_Set good revision"), /* Display label */
365 NULL, /* short-cut */
366 NULL, /* Tooltip */
367 G_CALLBACK (on_log_menu_git_bisect_good) /* action callback */
370 "ActionGitLogBisectBad", /* Action name */
371 GTK_STOCK_NO, /* Stock icon, if any */
372 N_("_Set bad revision"), /* Display label */
373 NULL, /* short-cut */
374 NULL, /* Tooltip */
375 G_CALLBACK (on_log_menu_git_bisect_bad) /* action callback */
379 static void
380 on_project_root_added (AnjutaPlugin *plugin, const gchar *name,
381 const GValue *value, gpointer user_data)
383 Git *git_plugin;
384 gchar *project_root_uri;
385 GFile *file;
386 AnjutaUI *ui;
387 GtkAction *git_menu_action;
389 git_plugin = ANJUTA_PLUGIN_GIT (plugin);
391 g_free (git_plugin->project_root_directory);
392 project_root_uri = g_value_dup_string (value);
393 file = g_file_new_for_uri (project_root_uri);
394 git_plugin->project_root_directory = g_file_get_path (file);
395 g_object_unref (file);
397 ui = anjuta_shell_get_ui (plugin->shell, NULL);
398 git_menu_action = anjuta_ui_get_action (ui,
399 "ActionGroupGit",
400 "ActionMenuGit");
402 gtk_action_set_sensitive (git_menu_action, TRUE);
403 gtk_widget_set_sensitive (git_plugin->log_viewer, TRUE);
405 g_free (project_root_uri);
407 git_plugin->bisect_file_monitor = bisect_menus_init (git_plugin);
410 static void
411 on_project_root_removed (AnjutaPlugin *plugin, const gchar *name,
412 gpointer user_data)
414 GtkAction *git_menu_action;
415 Git *git_plugin;
417 git_plugin = ANJUTA_PLUGIN_GIT (plugin);
419 g_free (git_plugin->project_root_directory);
420 git_plugin->project_root_directory = NULL;
422 git_menu_action = anjuta_ui_get_action (anjuta_shell_get_ui (plugin->shell,
423 NULL),
424 "ActionGroupGit",
425 "ActionMenuGit");
427 gtk_action_set_sensitive (git_menu_action, FALSE);
428 gtk_widget_set_sensitive (git_plugin->log_viewer, FALSE);
429 git_log_window_clear (git_plugin);
431 g_file_monitor_cancel (git_plugin->bisect_file_monitor);
432 g_object_unref (git_plugin->bisect_file_monitor);
435 static void
436 on_editor_added (AnjutaPlugin *plugin, const gchar *name, const GValue *value,
437 gpointer user_data)
439 Git *git_plugin;
440 IAnjutaEditor *editor;
441 GFile *current_editor_file;
443 git_plugin = ANJUTA_PLUGIN_GIT (plugin);
444 editor = g_value_get_object (value);
446 g_free (git_plugin->current_editor_filename);
447 git_plugin->current_editor_filename = NULL;
449 if (IANJUTA_IS_EDITOR (editor))
451 current_editor_file = ianjuta_file_get_file (IANJUTA_FILE (editor),
452 NULL);
454 if (current_editor_file)
456 git_plugin->current_editor_filename = g_file_get_path (current_editor_file);
457 g_object_unref (current_editor_file);
462 static void
463 on_editor_removed (AnjutaPlugin *plugin, const gchar *name, gpointer user_data)
465 Git *git_plugin;
467 git_plugin = ANJUTA_PLUGIN_GIT (plugin);
469 g_free (git_plugin->current_editor_filename);
470 git_plugin->current_editor_filename = NULL;
473 static gboolean
474 git_activate_plugin (AnjutaPlugin *plugin)
476 AnjutaUI *ui;
477 Git *git_plugin;
478 GtkAction *git_menu_action;
480 DEBUG_PRINT ("Git: Activating Git plugin ...");
482 git_plugin = ANJUTA_PLUGIN_GIT (plugin);
483 ui = anjuta_shell_get_ui (plugin->shell, NULL);
485 /* Add all our actions */
486 anjuta_ui_add_action_group_entries (ui, "ActionGroupGit",
487 _("Git operations"),
488 actions_git,
489 G_N_ELEMENTS (actions_git),
490 GETTEXT_PACKAGE, TRUE, plugin);
491 anjuta_ui_add_action_group_entries (ui, "ActionGroupGitLog",
492 _("Git log operations"),
493 actions_log,
494 G_N_ELEMENTS (actions_log),
495 GETTEXT_PACKAGE, TRUE, plugin);
497 git_plugin->uiid = anjuta_ui_merge (ui, UI_FILE);
499 git_plugin->log_popup_menu = gtk_ui_manager_get_widget (GTK_UI_MANAGER (ui),
500 "/PopupLog");
502 /* Add watches */
503 git_plugin->project_root_watch_id = anjuta_plugin_add_watch (plugin,
504 IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI,
505 on_project_root_added,
506 on_project_root_removed,
507 NULL);
509 git_plugin->editor_watch_id = anjuta_plugin_add_watch (plugin,
510 IANJUTA_DOCUMENT_MANAGER_CURRENT_DOCUMENT,
511 on_editor_added,
512 on_editor_removed,
513 NULL);
515 /* Log viewer */
516 git_plugin->log_viewer = git_log_window_create (git_plugin);
517 anjuta_shell_add_widget (plugin->shell,
518 git_plugin->log_viewer,
519 "GitLogViewer",
520 _("Git Log"),
521 GTK_STOCK_ZOOM_100,
522 ANJUTA_SHELL_PLACEMENT_CENTER,
523 NULL);
524 g_object_unref (git_plugin->log_viewer);
528 /* Git needs a working directory to work with; it can't take full paths,
529 * so make sure that Git can't be used if there's no project opened. */
530 git_menu_action = anjuta_ui_get_action (anjuta_shell_get_ui (plugin->shell,
531 NULL),
532 "ActionGroupGit",
533 "ActionMenuGit");
535 if (!git_plugin->project_root_directory)
537 gtk_action_set_sensitive (git_menu_action, FALSE);
538 gtk_widget_set_sensitive (git_plugin->log_viewer, FALSE);
541 return TRUE;
544 static gboolean
545 git_deactivate_plugin (AnjutaPlugin *plugin)
547 AnjutaUI *ui = anjuta_shell_get_ui (plugin->shell, NULL);
548 Git *git_plugin;
550 git_plugin = ANJUTA_PLUGIN_GIT (plugin);
552 DEBUG_PRINT ("Git: Dectivating Git plugin ...");
553 anjuta_ui_unmerge (ui, git_plugin->uiid);
554 anjuta_plugin_remove_watch (plugin, git_plugin->project_root_watch_id,
555 TRUE);
556 anjuta_plugin_remove_watch (plugin, git_plugin->editor_watch_id,
557 TRUE);
559 anjuta_shell_remove_widget (plugin->shell, git_plugin->log_viewer, NULL);
560 gtk_widget_destroy (git_plugin->log_popup_menu);
562 return TRUE;
565 static void
566 git_finalize (GObject *obj)
568 /* Finalization codes here */
569 G_OBJECT_CLASS (parent_class)->finalize (obj);
572 static void
573 git_dispose (GObject *obj)
575 /* Disposition codes */
576 G_OBJECT_CLASS (parent_class)->dispose (obj);
579 static void
580 git_instance_init (GObject *obj)
582 Git *plugin = ANJUTA_PLUGIN_GIT (obj);
583 plugin->uiid = 0;
586 static void
587 git_class_init (GObjectClass *klass)
589 AnjutaPluginClass *plugin_class = ANJUTA_PLUGIN_CLASS (klass);
591 parent_class = g_type_class_peek_parent (klass);
593 plugin_class->activate = git_activate_plugin;
594 plugin_class->deactivate = git_deactivate_plugin;
595 klass->finalize = git_finalize;
596 klass->dispose = git_dispose;
599 ANJUTA_PLUGIN_BOILERPLATE (Git, git);
600 ANJUTA_SIMPLE_PLUGIN (Git, git);