glade: Fix make file some files were not installed
[anjuta.git] / plugins / git / git-push-pane.c
blob4d69ae083fb3192062fd01c8cd1dd3b08fa36afc
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * anjuta
4 * Copyright (C) James Liggett 2010 <jrliggett@cox.net>
5 *
6 * anjuta is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * anjuta is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "git-push-pane.h"
22 struct _GitPushPanePriv
24 GtkBuilder *builder;
25 GtkWidget *repository_selector;
28 enum
30 COL_SELECTED,
31 COL_NAME
34 G_DEFINE_TYPE (GitPushPane, git_push_pane, GIT_TYPE_PANE);
36 /* Foreach function for both the selected branches and tags list. Will generate
37 * one list of both types of selected items. */
38 static gboolean
39 get_selected_items (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter,
40 GList **list)
42 gboolean selected;
43 gchar *name;
45 gtk_tree_model_get (model, iter, COL_SELECTED, &selected, -1);
47 if (selected)
49 gtk_tree_model_get (model, iter, COL_NAME, &name, -1);
50 *list = g_list_append (*list, name);
53 return FALSE;
56 static void
57 on_ok_button_clicked (GtkButton *button, GitPushPane *self)
59 Git *plugin;
60 GtkTreeModel *push_branch_model;
61 GtkTreeModel *push_tag_model;
62 GtkToggleButton *push_all_tags_check;
63 GtkToggleButton *push_all_check;
64 GtkToggleButton *force_check;
65 GList *selected_items;
66 gboolean push_all_tags;
67 gboolean push_all;
68 gchar *repository;
69 GitPushCommand *push_command;
71 plugin = ANJUTA_PLUGIN_GIT (anjuta_dock_pane_get_plugin (ANJUTA_DOCK_PANE (self)));
72 push_branch_model = GTK_TREE_MODEL (gtk_builder_get_object (self->priv->builder,
73 "push_branch_model"));
74 push_tag_model = GTK_TREE_MODEL (gtk_builder_get_object (self->priv->builder,
75 "push_tag_model"));
76 push_all_tags_check = GTK_TOGGLE_BUTTON (gtk_builder_get_object (self->priv->builder,
77 "push_all_tags_check"));
78 push_all_check = GTK_TOGGLE_BUTTON (gtk_builder_get_object (self->priv->builder,
79 "push_all_check"));
80 force_check = GTK_TOGGLE_BUTTON (gtk_builder_get_object (self->priv->builder,
81 "force_check"));
82 selected_items = NULL;
83 push_all_tags = gtk_toggle_button_get_active (push_all_tags_check);
84 push_all = gtk_toggle_button_get_active (push_all_check);
86 /* Check that the user has given a valid repository. In this case we only
87 * care about checking if the selector widget is in URL mode, because even
88 * if a remote isn't selected, it will default to origin, so we should
89 * always get something when the selector is in Remote mode. */
90 repository = git_repository_selector_get_repository (GIT_REPOSITORY_SELECTOR (self->priv->repository_selector));
92 if (!git_pane_check_input (GTK_WIDGET (ANJUTA_PLUGIN (plugin)->shell),
93 self->priv->repository_selector, repository,
94 _("Please enter a URL.")))
96 g_free (repository);
97 return;
100 if (!push_all)
102 /* Get selected branches */
103 gtk_tree_model_foreach (push_branch_model,
104 (GtkTreeModelForeachFunc) get_selected_items,
105 &selected_items);
108 /* Don't bother getting selected tags if Push all tags is checked or if
109 * Push all branches and tags is checked */
110 if (!push_all && !push_all_tags)
112 /* Get selected tags */
113 gtk_tree_model_foreach (push_tag_model,
114 (GtkTreeModelForeachFunc) get_selected_items,
115 &selected_items);
118 push_command = git_push_command_new (plugin->project_root_directory,
119 repository, selected_items,
120 push_all, push_all_tags,
121 gtk_toggle_button_get_active (force_check));
123 g_free (repository);
124 anjuta_util_glist_strings_free (selected_items);
126 git_pane_create_message_view (plugin);
128 g_signal_connect (G_OBJECT (push_command), "data-arrived",
129 G_CALLBACK (git_pane_on_command_info_arrived),
130 plugin);
132 g_signal_connect (G_OBJECT (push_command), "command-finished",
133 G_CALLBACK (git_pane_report_errors),
134 plugin);
136 g_signal_connect (G_OBJECT (push_command), "command-finished",
137 G_CALLBACK (git_plugin_status_changed_emit),
138 plugin);
140 g_signal_connect (G_OBJECT (push_command), "command-finished",
141 G_CALLBACK (g_object_unref),
142 NULL);
144 anjuta_command_start (ANJUTA_COMMAND (push_command));
146 git_pane_remove_from_dock (GIT_PANE (self));
149 static void
150 on_selected_renderer_toggled (GtkCellRendererToggle *renderer, gchar *path,
151 GtkTreeModel *model)
153 GtkTreeIter iter;
154 gboolean selected;
156 gtk_tree_model_get_iter_from_string (model, &iter, path);
158 gtk_tree_model_get (model, &iter, COL_SELECTED, &selected, -1);
160 selected = !selected;
162 gtk_list_store_set (GTK_LIST_STORE (model), &iter, COL_SELECTED, selected,
163 -1);
166 static void
167 on_branch_list_command_data_arrived (AnjutaCommand *command,
168 GtkListStore *push_branch_model)
170 GList *current_branch;
171 GitBranch *branch;
172 gchar *name;
173 GtkTreeIter iter;
175 current_branch = git_branch_list_command_get_output (GIT_BRANCH_LIST_COMMAND (command));
177 while (current_branch)
179 branch = current_branch->data;
180 name = git_branch_get_name (branch);
182 gtk_list_store_append (push_branch_model, &iter);
183 gtk_list_store_set (push_branch_model, &iter,
184 COL_SELECTED, FALSE,
185 COL_NAME, name,
186 -1);
188 g_free (name);
190 current_branch = g_list_next (current_branch);
194 static void
195 on_tag_list_command_data_arrived (AnjutaCommand *command,
196 GtkListStore *push_tag_model)
198 GQueue *output;
199 gchar *name;
200 GtkTreeIter iter;
202 output = git_raw_output_command_get_output (GIT_RAW_OUTPUT_COMMAND (command));
204 while (g_queue_peek_head (output))
206 name = g_queue_pop_head (output);
208 gtk_list_store_append (push_tag_model, &iter);
209 gtk_list_store_set (push_tag_model, &iter,
210 COL_SELECTED, FALSE,
211 COL_NAME, name,
212 -1);
214 g_free (name);
218 static void
219 on_push_all_check_toggled (GtkToggleButton *button, GtkWidget *widget)
221 gtk_widget_set_sensitive (widget,
222 !gtk_toggle_button_get_active (button));
225 static void
226 on_remote_selected (AnjutaDockPane *pane,
227 GitRepositorySelector *repository_selector)
229 gchar *remote;
231 remote = git_remotes_pane_get_selected_remote (GIT_REMOTES_PANE (pane));
232 git_repository_selector_set_remote (repository_selector, remote);
234 g_free (remote);
237 static void
238 git_push_pane_init (GitPushPane *self)
240 gchar *objects[] = {"push_pane",
241 "push_branch_model",
242 "push_tag_model",
243 NULL};
244 GError *error = NULL;
245 GtkWidget *ok_button;
246 GtkWidget *cancel_button;
247 GtkContainer *repository_alignment;
248 GtkWidget *branches_view;
249 GtkWidget *tags_view;
250 GtkTreeModel *push_branch_model;
251 GtkTreeModel *push_tag_model;
252 GtkCellRenderer *branches_selected_renderer;
253 GtkCellRenderer *tags_selected_renderer;
254 GtkWidget *push_all_tags_check;
255 GtkWidget *push_all_check;;
257 self->priv = g_new0 (GitPushPanePriv, 1);
258 self->priv->builder = gtk_builder_new ();
260 if (!gtk_builder_add_objects_from_file (self->priv->builder, BUILDER_FILE,
261 objects,
262 &error))
264 g_warning ("Couldn't load builder file: %s", error->message);
265 g_error_free (error);
268 ok_button = GTK_WIDGET (gtk_builder_get_object (self->priv->builder,
269 "ok_button"));
270 cancel_button = GTK_WIDGET (gtk_builder_get_object (self->priv->builder,
271 "cancel_button"));
272 repository_alignment = GTK_CONTAINER (gtk_builder_get_object (self->priv->builder,
273 "repository_alignment"));
274 self->priv->repository_selector = git_repository_selector_new ();
275 branches_view = GTK_WIDGET (gtk_builder_get_object (self->priv->builder,
276 "branches_view"));
277 tags_view = GTK_WIDGET (gtk_builder_get_object (self->priv->builder,
278 "tags_view"));
279 push_branch_model = GTK_TREE_MODEL (gtk_builder_get_object (self->priv->builder,
280 "push_branch_model"));
281 push_tag_model = GTK_TREE_MODEL (gtk_builder_get_object (self->priv->builder,
282 "push_tag_model"));
283 branches_selected_renderer = GTK_CELL_RENDERER (gtk_builder_get_object (self->priv->builder,
284 "branches_selected_renderer"));
285 tags_selected_renderer = GTK_CELL_RENDERER (gtk_builder_get_object (self->priv->builder,
286 "tags_selected_renderer"));
287 push_all_tags_check = GTK_WIDGET (gtk_builder_get_object (self->priv->builder,
288 "push_all_tags_check"));
289 push_all_check = GTK_WIDGET (gtk_builder_get_object (self->priv->builder,
290 "push_all_check"));
292 gtk_container_add (repository_alignment, self->priv->repository_selector);
294 g_signal_connect (G_OBJECT (ok_button), "clicked",
295 G_CALLBACK (on_ok_button_clicked),
296 self);
298 g_signal_connect_swapped (G_OBJECT (cancel_button), "clicked",
299 G_CALLBACK (git_pane_remove_from_dock),
300 self);
302 g_signal_connect (G_OBJECT (branches_selected_renderer), "toggled",
303 G_CALLBACK (on_selected_renderer_toggled),
304 push_branch_model);
306 g_signal_connect (G_OBJECT (tags_selected_renderer), "toggled",
307 G_CALLBACK (on_selected_renderer_toggled),
308 push_tag_model);
310 /* Use the push all tags check callback to handle both the Push all tags
311 * and the Push all branches and tags check boxes. The behavior is the same
312 * for both; they just act on different widgets. */
313 g_signal_connect (G_OBJECT (push_all_tags_check), "toggled",
314 G_CALLBACK (on_push_all_check_toggled),
315 tags_view);
317 g_signal_connect (G_OBJECT (push_all_check), "toggled",
318 G_CALLBACK (on_push_all_check_toggled),
319 branches_view);
321 g_signal_connect (G_OBJECT (push_all_check), "toggled",
322 G_CALLBACK (on_push_all_check_toggled),
323 tags_view);
326 static void
327 git_push_pane_dispose (GObject *object)
329 GitPushPane *self;
330 Git *plugin;
332 self = GIT_PUSH_PANE (object);
333 plugin = ANJUTA_PLUGIN_GIT (anjuta_dock_pane_get_plugin (ANJUTA_DOCK_PANE (object)));
335 g_signal_handlers_disconnect_by_func (plugin->remotes_pane,
336 on_remote_selected,
337 self->priv->repository_selector);
339 G_OBJECT_CLASS (git_push_pane_parent_class)->dispose (object);
343 static void
344 git_push_pane_finalize (GObject *object)
346 GitPushPane *self;
348 self = GIT_PUSH_PANE (object);
350 g_object_unref (self->priv->builder);
351 g_free (self->priv);
353 G_OBJECT_CLASS (git_push_pane_parent_class)->finalize (object);
356 static GtkWidget *
357 git_push_pane_get_widget (AnjutaDockPane *pane)
359 GitPushPane *self;
361 self = GIT_PUSH_PANE (pane);
363 return GTK_WIDGET (gtk_builder_get_object (self->priv->builder,
364 "push_pane"));
367 static void
368 git_push_pane_class_init (GitPushPaneClass *klass)
370 GObjectClass* object_class = G_OBJECT_CLASS (klass);
371 AnjutaDockPaneClass* pane_class = ANJUTA_DOCK_PANE_CLASS (klass);
373 object_class->finalize = git_push_pane_finalize;
374 object_class->dispose = git_push_pane_dispose;
375 pane_class->get_widget = git_push_pane_get_widget;
376 pane_class->refresh = NULL;
379 AnjutaDockPane *
380 git_push_pane_new (Git *plugin)
382 GitPushPane *self;
383 GtkLabel *selected_remote_label;
384 GtkListStore *push_branch_model;
385 GtkListStore *push_tag_model;
386 GitBranchListCommand *branch_list_command;
387 GitTagListCommand *tag_list_command;
389 self = g_object_new (GIT_TYPE_PUSH_PANE, "plugin", plugin, NULL);
390 selected_remote_label = GTK_LABEL (gtk_builder_get_object (self->priv->builder,
391 "selected_remote_label"));
392 push_branch_model = GTK_LIST_STORE (gtk_builder_get_object (self->priv->builder,
393 "push_branch_model"));
394 push_tag_model = GTK_LIST_STORE (gtk_builder_get_object (self->priv->builder,
395 "push_tag_model"));
396 branch_list_command = git_branch_list_command_new (plugin->project_root_directory,
397 GIT_BRANCH_TYPE_LOCAL);
398 tag_list_command = git_tag_list_command_new (plugin->project_root_directory);
400 g_signal_connect (G_OBJECT (plugin->remotes_pane), "single-selection-changed",
401 G_CALLBACK (on_remote_selected),
402 self->priv->repository_selector);
404 g_signal_connect (G_OBJECT (branch_list_command), "data-arrived",
405 G_CALLBACK (on_branch_list_command_data_arrived),
406 push_branch_model);
408 g_signal_connect (G_OBJECT (tag_list_command), "data-arrived",
409 G_CALLBACK (on_tag_list_command_data_arrived),
410 push_tag_model);
412 g_signal_connect (G_OBJECT (branch_list_command), "command-finished",
413 G_CALLBACK (g_object_unref),
414 NULL);
416 g_signal_connect (G_OBJECT (tag_list_command), "command-finished",
417 G_CALLBACK (g_object_unref),
418 NULL);
420 /* Set the contents of the selected remote label */
421 on_remote_selected (plugin->remotes_pane,
422 GIT_REPOSITORY_SELECTOR (self->priv->repository_selector));
424 anjuta_command_start (ANJUTA_COMMAND (branch_list_command));
425 anjuta_command_start (ANJUTA_COMMAND (tag_list_command));
427 return ANJUTA_DOCK_PANE (self);
430 void
431 on_push_button_clicked (GtkAction *action, Git *plugin)
433 AnjutaDockPane *pane;
435 pane = git_push_pane_new (plugin);
437 anjuta_dock_replace_command_pane (ANJUTA_DOCK (plugin->dock), "Push",
438 _("Push"), NULL, pane, GDL_DOCK_BOTTOM,
439 NULL, 0, NULL);