message-view: bgo #727634 - Cannot copy build output
[anjuta.git] / plugins / git / git-stash-pane.c
blob6de59883b8c0dde0e56d43d16faa857130ca49e8
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-stash-pane.h"
22 enum
24 COL_NUMBER,
25 COL_MESSAGE,
26 COL_ID,
27 COL_DIFF
30 struct _GitStashPanePriv
32 GtkBuilder *builder;
35 G_DEFINE_TYPE (GitStashPane, git_stash_pane, GIT_TYPE_PANE);
37 static void
38 on_stash_list_command_started (AnjutaCommand *command, GitStashPane *self)
40 GtkTreeView *stash_view;
41 GtkTreeStore *stash_model;
43 stash_view = GTK_TREE_VIEW (gtk_builder_get_object (self->priv->builder,
44 "stash_view"));
45 stash_model = GTK_TREE_STORE (gtk_builder_get_object (self->priv->builder,
46 "stash_model"));
48 gtk_tree_view_set_model (stash_view, NULL);
49 gtk_tree_store_clear (stash_model);
52 static void
53 on_stash_list_command_finished (AnjutaCommand *command, guint return_code,
54 GitStashPane *self)
56 GtkTreeView *stash_view;
57 GtkTreeModel *stash_model;
59 stash_view = GTK_TREE_VIEW (gtk_builder_get_object (self->priv->builder,
60 "stash_view"));
61 stash_model = GTK_TREE_MODEL (gtk_builder_get_object (self->priv->builder,
62 "stash_model"));
64 gtk_tree_view_set_model (stash_view, stash_model);
67 static void
68 on_stash_diff_command_finished (AnjutaCommand *command, guint return_code,
69 GtkTreeStore *stash_model)
71 GtkTreePath *parent_path;
72 GtkTreeIter parent_iter;
73 GtkTreeIter iter;
74 GQueue *output;
75 gchar *output_line;
77 if (return_code == 0)
79 parent_path = g_object_get_data (G_OBJECT (command), "parent-path");
80 gtk_tree_model_get_iter (GTK_TREE_MODEL (stash_model), &parent_iter,
81 parent_path);
83 output = git_raw_output_command_get_output (GIT_RAW_OUTPUT_COMMAND (command));
85 while (g_queue_peek_head (output))
87 output_line = g_queue_pop_head (output);
89 gtk_tree_store_append (stash_model, &iter, &parent_iter);
90 gtk_tree_store_set (stash_model, &iter,
91 COL_DIFF, output_line,
92 -1);
94 g_free (output_line);
99 static void
100 on_stash_list_command_data_arrived (AnjutaCommand *command,
101 GtkTreeStore *stash_model)
103 GQueue *output;
104 GtkTreeIter iter;
105 GitStash *stash;
106 guint number;
107 gchar *message;
108 gchar *id;
109 gchar *working_directory;
110 GitStashShowCommand *show_command;
112 output = git_stash_list_command_get_output (GIT_STASH_LIST_COMMAND (command));
114 while (g_queue_peek_head (output))
116 stash = g_queue_pop_head (output);
117 number = git_stash_get_number (stash);
118 message = git_stash_get_message (stash);
119 id = git_stash_get_id (stash);
122 gtk_tree_store_append (stash_model, &iter, NULL);
123 gtk_tree_store_set (stash_model, &iter,
124 COL_NUMBER, number,
125 COL_MESSAGE, message,
126 COL_ID, id,
127 -1);
129 g_object_get (G_OBJECT (command), "working-directory",
130 &working_directory, NULL);
131 show_command = git_stash_show_command_new (working_directory, id);
133 g_free (working_directory);
135 g_object_set_data_full (G_OBJECT (show_command), "parent-path",
136 gtk_tree_model_get_path (GTK_TREE_MODEL (stash_model),
137 &iter),
138 (GDestroyNotify) gtk_tree_path_free);
140 g_signal_connect (G_OBJECT (show_command), "command-finished",
141 G_CALLBACK (on_stash_diff_command_finished),
142 stash_model);
144 g_signal_connect (G_OBJECT (show_command), "command-finished",
145 G_CALLBACK (g_object_unref),
146 NULL);
148 anjuta_command_start (ANJUTA_COMMAND (show_command));
150 g_object_unref (stash);
151 g_free (message);
152 g_free (id);
156 static gboolean
157 on_stash_view_button_press_event (GtkWidget *stash_view, GdkEventButton *event,
158 GitStashPane *self)
160 gboolean path_valid;
161 GtkTreePath *path;
162 gboolean ret = FALSE;
164 path_valid = gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (stash_view),
165 event->x, event->y, &path, NULL,
166 NULL, NULL);
168 if (event->type == GDK_BUTTON_PRESS && event->button == 3)
170 if (path_valid && gtk_tree_path_get_depth (path) == 1)
172 git_pane_popup_menu (GIT_PANE (self), "GitStashPopup", event->button,
173 event->time);
177 /* Don't forward button presses to diff renderers */
178 if (path_valid)
180 ret = gtk_tree_path_get_depth (path) == 2;
181 gtk_tree_path_free (path);
184 return ret;
187 static void
188 stash_message_renderer_data_func (GtkTreeViewColumn *tree_column,
189 GtkCellRenderer *renderer,
190 GtkTreeModel *model,
191 GtkTreeIter *iter,
192 gpointer user_data)
194 gboolean visible;
195 gchar *message;
197 /* Don't show this column on diffs */
198 visible = gtk_tree_store_iter_depth (GTK_TREE_STORE (model), iter) == 0;
199 gtk_cell_renderer_set_visible (renderer, visible);
201 if (visible)
203 gtk_tree_model_get (model, iter, COL_MESSAGE, &message, -1);
204 g_object_set (renderer, "text", message, NULL);
206 g_free (message);
208 else
209 g_object_set (renderer, "text", "", NULL);
212 static void
213 stash_number_renderer_data_func (GtkTreeViewColumn *tree_column,
214 GtkCellRenderer *renderer,
215 GtkTreeModel *model,
216 GtkTreeIter *iter,
217 gpointer user_data)
219 gboolean visible;
220 guint number;
221 gchar *number_string;
223 /* Don't show this column on diffs */
224 visible = gtk_tree_store_iter_depth (GTK_TREE_STORE (model), iter) == 0;
225 gtk_cell_renderer_set_visible (renderer, visible);
227 if (visible)
229 gtk_tree_model_get (model, iter, COL_NUMBER, &number, -1);
230 number_string = g_strdup_printf ("%i", number);
232 g_object_set (renderer, "text", number_string, NULL);
233 g_free (number_string);
235 else
236 g_object_set (renderer, "text", "", NULL);
239 static gboolean
240 on_stash_view_row_selected (GtkTreeSelection *selection,
241 GtkTreeModel *model,
242 GtkTreePath *path,
243 gboolean path_currently_selected,
244 gpointer user_data)
246 return gtk_tree_path_get_depth (path) == 1;
249 static void
250 git_stash_pane_init (GitStashPane *self)
252 gchar *objects[] = {"stash_pane",
253 "stash_model",
254 NULL};
255 GError *error = NULL;
256 GtkTreeView *stash_view;
257 GtkTreeViewColumn *stash_number_column;
258 GtkCellRenderer *stash_number_renderer;
259 GtkTreeViewColumn *stash_message_column;
260 GtkCellRenderer *stash_message_renderer;
261 GtkCellRenderer *diff_renderer;
262 GtkTreeSelection *selection;
264 self->priv = g_new0 (GitStashPanePriv, 1);
265 self->priv->builder = gtk_builder_new ();
267 if (!gtk_builder_add_objects_from_file (self->priv->builder, BUILDER_FILE,
268 objects,
269 &error))
271 g_warning ("Couldn't load builder file: %s", error->message);
272 g_error_free (error);
275 stash_view = GTK_TREE_VIEW (gtk_builder_get_object (self->priv->builder,
276 "stash_view"));
277 stash_number_column = GTK_TREE_VIEW_COLUMN (gtk_builder_get_object (self->priv->builder,
278 "stash_number_column"));
279 stash_number_renderer = GTK_CELL_RENDERER (gtk_builder_get_object (self->priv->builder,
280 "stash_number_renderer"));
281 stash_message_column = GTK_TREE_VIEW_COLUMN (gtk_builder_get_object (self->priv->builder,
282 "stash_message_column"));
283 stash_message_renderer = GTK_CELL_RENDERER (gtk_builder_get_object (self->priv->builder,
284 "stash_message_renderer"));
285 diff_renderer = anjuta_cell_renderer_diff_new ();
286 selection = gtk_tree_view_get_selection (stash_view);
288 gtk_tree_view_column_set_cell_data_func (stash_number_column, stash_number_renderer,
289 stash_number_renderer_data_func,
290 NULL, NULL);
291 gtk_tree_view_column_set_cell_data_func (stash_message_column, stash_message_renderer,
292 stash_message_renderer_data_func,
293 NULL, NULL);
295 gtk_tree_view_column_pack_start (stash_message_column, diff_renderer, TRUE);
296 gtk_tree_view_column_add_attribute (stash_message_column, diff_renderer,
297 "diff", COL_DIFF);
299 /* Don't allow diffs to be selected */
300 gtk_tree_selection_set_select_function (selection, on_stash_view_row_selected,
301 NULL, NULL);
303 g_signal_connect (G_OBJECT (stash_view), "button-press-event",
304 G_CALLBACK (on_stash_view_button_press_event),
305 self);
308 static void
309 git_stash_pane_finalize (GObject *object)
311 GitStashPane *self;
313 self = GIT_STASH_PANE (object);
315 g_object_unref (self->priv->builder);
316 g_free (self->priv);
318 G_OBJECT_CLASS (git_stash_pane_parent_class)->finalize (object);
321 static GtkWidget *
322 git_stash_pane_get_widget (AnjutaDockPane *pane)
324 GitStashPane *self;
326 self = GIT_STASH_PANE (pane);
328 return GTK_WIDGET (gtk_builder_get_object (self->priv->builder,
329 "stash_pane"));
332 static void
333 git_stash_pane_class_init (GitStashPaneClass *klass)
335 GObjectClass* object_class = G_OBJECT_CLASS (klass);
336 AnjutaDockPaneClass *pane_class = ANJUTA_DOCK_PANE_CLASS (klass);
338 object_class->finalize = git_stash_pane_finalize;
339 pane_class->get_widget = git_stash_pane_get_widget;
340 pane_class->refresh = NULL;
344 AnjutaDockPane *
345 git_stash_pane_new (Git *plugin)
347 GitStashPane *self;
348 GtkTreeStore *stash_model;
350 self = g_object_new (GIT_TYPE_STASH_PANE, "plugin", plugin, NULL);
351 stash_model = GTK_TREE_STORE (gtk_builder_get_object (self->priv->builder,
352 "stash_model"));
354 g_signal_connect (G_OBJECT (plugin->stash_list_command), "command-started",
355 G_CALLBACK (on_stash_list_command_started),
356 self);
358 g_signal_connect (G_OBJECT (plugin->stash_list_command), "command-finished",
359 G_CALLBACK (on_stash_list_command_finished),
360 self);
362 g_signal_connect (G_OBJECT (plugin->stash_list_command), "data-arrived",
363 G_CALLBACK (on_stash_list_command_data_arrived),
364 stash_model);
366 return ANJUTA_DOCK_PANE (self);
369 gchar *
370 git_stash_pane_get_selected_stash_id (GitStashPane *self)
372 GtkTreeView *stash_view;
373 GtkTreeSelection *selection;
374 gchar *id;
375 GtkTreeModel *stash_model;
376 GtkTreeIter iter;
378 stash_view = GTK_TREE_VIEW (gtk_builder_get_object (self->priv->builder,
379 "stash_view"));
380 selection = gtk_tree_view_get_selection (stash_view);
381 id = NULL;
383 if (gtk_tree_selection_get_selected (selection, &stash_model, &iter))
384 gtk_tree_model_get (stash_model, &iter, COL_ID, &id, -1);
386 return id;
389 gint
390 git_stash_pane_get_selected_stash_number (GitStashPane *self)
392 GtkTreeView *stash_view;
393 GtkTreeSelection *selection;
394 guint number;
395 GtkTreeModel *stash_model;
396 GtkTreeIter iter;
398 stash_view = GTK_TREE_VIEW (gtk_builder_get_object (self->priv->builder,
399 "stash_view"));
400 selection = gtk_tree_view_get_selection (stash_view);
401 number = -1;
403 if (gtk_tree_selection_get_selected (selection, &stash_model, &iter))
404 gtk_tree_model_get (stash_model, &iter, COL_NUMBER, &number, -1);
406 return number;