Implement support for listing and merging branches.
[anjuta-git-plugin.git] / libanjuta / anjuta-vcs-status-tree-view.c
blobdb586a438949d6fc2f2a17b5655932e492f849d7
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * anjuta
4 * Copyright (C) James Liggett 2007 <jrliggett@cox.net>
5 *
6 * anjuta is free software.
7 *
8 * You may redistribute it and/or modify it under the terms of the
9 * GNU General Public License, as published by the Free Software
10 * Foundation; either version 2 of the License, or (at your option)
11 * any later version.
13 * anjuta is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 * See the GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with anjuta. If not, write to:
20 * The Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor
22 * Boston, MA 02110-1301, USA.
25 #include "anjuta-vcs-status-tree-view.h"
27 enum
29 COL_SELECTED,
30 COL_STATUS,
31 COL_PATH,
32 NUM_COLS
35 enum
37 ANJUTA_VCS_STATUS_TREE_VIEW_CONSTRUCT_STATUS_CODES = 1,
38 ANJUTA_VCS_STATUS_TREE_VIEW_SHOW_STATUS
41 struct _AnjutaVcsStatusTreeViewPriv
43 GtkListStore *store;
44 GHashTable *selected_paths;
45 guint status_codes;
46 gboolean show_status;
49 G_DEFINE_TYPE (AnjutaVcsStatusTreeView, anjuta_vcs_status_tree_view,
50 GTK_TYPE_TREE_VIEW);
52 static void
53 on_selected_column_toggled (GtkCellRendererToggle *renderer,
54 gchar *tree_path,
55 AnjutaVcsStatusTreeView *self)
57 GtkTreeIter iter;
58 gchar *vcs_path;
59 gboolean selected;
61 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (self->priv->store),
62 &iter, tree_path);
64 gtk_tree_model_get (GTK_TREE_MODEL (self->priv->store), &iter,
65 COL_PATH, &vcs_path,
66 COL_SELECTED, &selected, -1);
68 gtk_list_store_set (self->priv->store, &iter,
69 COL_SELECTED, !selected, -1);
71 g_free (vcs_path);
75 static void
76 anjuta_vcs_status_tree_view_create_columns (AnjutaVcsStatusTreeView *self)
78 GtkTreeViewColumn *column;
79 GtkCellRenderer *renderer;
81 /* Selected column */
82 column = gtk_tree_view_column_new ();
83 renderer = gtk_cell_renderer_toggle_new ();
84 gtk_tree_view_column_pack_start (column, renderer, TRUE);
85 gtk_tree_view_append_column (GTK_TREE_VIEW (self), column);
86 gtk_tree_view_column_add_attribute (column, renderer, "active",
87 COL_SELECTED);
89 g_signal_connect (G_OBJECT (renderer), "toggled",
90 G_CALLBACK (on_selected_column_toggled),
91 self);
93 /* Status column */
94 column = gtk_tree_view_column_new ();
95 renderer = gtk_cell_renderer_text_new ();
96 gtk_tree_view_column_pack_start (column, renderer, TRUE);
97 gtk_tree_view_append_column (GTK_TREE_VIEW (self), column);
98 gtk_tree_view_column_add_attribute (column, renderer, "text",
99 COL_STATUS);
101 /* Path column */
102 column = gtk_tree_view_column_new ();
103 renderer = gtk_cell_renderer_text_new ();
104 gtk_tree_view_column_pack_start (column, renderer, TRUE);
105 gtk_tree_view_append_column (GTK_TREE_VIEW (self), column);
106 gtk_tree_view_column_add_attribute (column, renderer, "text",
107 COL_PATH);
109 gtk_tree_view_set_model (GTK_TREE_VIEW (self),
110 GTK_TREE_MODEL (self->priv->store));
111 g_object_unref (self->priv->store);
115 static gint
116 path_sort (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b,
117 gpointer user_data)
119 gint compare_value;
120 gchar *path1;
121 gchar *path2;
123 gtk_tree_model_get (model, a, COL_PATH, &path1, -1);
124 gtk_tree_model_get (model, b, COL_PATH, &path2, -1);
126 compare_value = strcmp (path1, path2);
128 g_free (path1);
129 g_free (path2);
131 return compare_value;
134 static void
135 anjuta_vcs_status_tree_view_init (AnjutaVcsStatusTreeView *self)
137 GtkTreeSortable *sortable;
139 self->priv = g_new0 (AnjutaVcsStatusTreeViewPriv, 1);
140 self->priv->store = gtk_list_store_new (NUM_COLS,
141 G_TYPE_BOOLEAN,
142 G_TYPE_STRING,
143 G_TYPE_STRING);
144 self->priv->selected_paths = g_hash_table_new_full (g_str_hash,
145 g_str_equal,
146 g_free,
147 NULL);
149 anjuta_vcs_status_tree_view_create_columns (self);
150 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (self), FALSE);
152 sortable = GTK_TREE_SORTABLE (self->priv->store);
153 gtk_tree_sortable_set_sort_column_id (sortable, COL_PATH,
154 GTK_SORT_ASCENDING);
155 gtk_tree_sortable_set_sort_func (sortable, COL_PATH, path_sort, NULL,
156 NULL);
159 static void
160 anjuta_vcs_status_tree_view_finalize (GObject *object)
162 AnjutaVcsStatusTreeView *self;
164 self = ANJUTA_VCS_STATUS_TREE_VIEW (object);
166 g_hash_table_destroy (self->priv->selected_paths);
167 g_free (self->priv);
169 G_OBJECT_CLASS (anjuta_vcs_status_tree_view_parent_class)->finalize (object);
172 static void
173 anjuta_vcs_status_tree_view_set_property (GObject *object, guint property_id,
174 const GValue *value,
175 GParamSpec *param_spec)
177 AnjutaVcsStatusTreeView *self;
178 GtkTreeView *tree_view;
179 GtkTreeViewColumn *column;
181 self = ANJUTA_VCS_STATUS_TREE_VIEW (object);
183 switch (property_id)
185 case ANJUTA_VCS_STATUS_TREE_VIEW_CONSTRUCT_STATUS_CODES:
186 self->priv->status_codes = g_value_get_flags (value);
187 break;
188 case ANJUTA_VCS_STATUS_TREE_VIEW_SHOW_STATUS:
189 tree_view = GTK_TREE_VIEW (object);
190 column = gtk_tree_view_get_column (tree_view, COL_STATUS);
191 self->priv->show_status = g_value_get_boolean (value);
193 gtk_tree_view_column_set_visible (column, self->priv->show_status);
194 break;
195 default:
196 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, param_spec);
197 break;
201 static void
202 anjuta_vcs_status_tree_view_get_property (GObject *object, guint property_id,
203 GValue *value, GParamSpec *param_spec)
205 AnjutaVcsStatusTreeView *self;
207 self = ANJUTA_VCS_STATUS_TREE_VIEW (object);
209 switch (property_id)
211 case ANJUTA_VCS_STATUS_TREE_VIEW_CONSTRUCT_STATUS_CODES:
212 g_value_set_flags (value, self->priv->status_codes);
213 break;
214 case ANJUTA_VCS_STATUS_TREE_VIEW_SHOW_STATUS:
215 g_value_set_boolean (value, self->priv->show_status);
216 break;
217 default:
218 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, param_spec);
219 break;
223 static void
224 anjuta_vcs_status_tree_view_class_init (AnjutaVcsStatusTreeViewClass *klass)
226 GObjectClass* object_class = G_OBJECT_CLASS (klass);
227 GParamSpec *param_spec;
229 object_class->finalize = anjuta_vcs_status_tree_view_finalize;
230 object_class->get_property = anjuta_vcs_status_tree_view_get_property;
231 object_class->set_property = anjuta_vcs_status_tree_view_set_property;
233 param_spec = g_param_spec_flags ("status-codes", "Status codes",
234 "Control which status codes are shown in "
235 "the list.",
236 ANJUTA_TYPE_VCS_STATUS,
237 ANJUTA_VCS_DEFAULT_STATUS_CODES,
238 G_PARAM_READWRITE |
239 G_PARAM_CONSTRUCT_ONLY);
240 g_object_class_install_property (object_class,
241 ANJUTA_VCS_STATUS_TREE_VIEW_CONSTRUCT_STATUS_CODES,
242 param_spec);
244 param_spec = g_param_spec_boolean ("show-status", "Show status",
245 "Show or hide status description",
246 TRUE,
247 G_PARAM_READWRITE);
248 g_object_class_install_property (object_class,
249 ANJUTA_VCS_STATUS_TREE_VIEW_SHOW_STATUS,
250 param_spec);
254 GtkWidget *
255 anjuta_vcs_status_tree_view_new (void)
257 return g_object_new (ANJUTA_VCS_TYPE_STATUS_TREE_VIEW, NULL);
260 void
261 anjuta_vcs_status_tree_view_destroy (AnjutaVcsStatusTreeView *self)
263 g_object_unref (self);
266 void
267 anjuta_vcs_status_tree_view_add (AnjutaVcsStatusTreeView *self, gchar *path,
268 AnjutaVcsStatus status, gboolean selected)
270 GtkTreeIter iter;
272 if (status & self->priv->status_codes)
274 gtk_list_store_append (self->priv->store, &iter);
276 gtk_list_store_set (self->priv->store, &iter,
277 COL_SELECTED, selected,
278 COL_PATH, path,
279 -1);
281 if (selected)
283 g_hash_table_insert (self->priv->selected_paths, g_strdup (path),
284 NULL);
287 switch (status)
289 case ANJUTA_VCS_STATUS_MODIFIED:
290 gtk_list_store_set (self->priv->store, &iter, COL_STATUS,
291 "Modified", -1);
292 break;
293 case ANJUTA_VCS_STATUS_ADDED:
294 gtk_list_store_set (self->priv->store, &iter, COL_STATUS,
295 "Added", -1);
296 break;
297 case ANJUTA_VCS_STATUS_DELETED:
298 gtk_list_store_set (self->priv->store, &iter, COL_STATUS,
299 "Deleted", -1);
300 break;
301 case ANJUTA_VCS_STATUS_CONFLICTED:
302 gtk_list_store_set (self->priv->store, &iter, COL_STATUS,
303 "Conflicted", -1);
304 break;
305 case ANJUTA_VCS_STATUS_MISSING:
306 gtk_list_store_set (self->priv->store, &iter, COL_STATUS,
307 "Missing", -1);
308 break;
309 case ANJUTA_VCS_STATUS_NONE:
310 default:
311 break;
317 static gboolean
318 select_all_paths (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter,
319 AnjutaVcsStatusTreeView *self)
321 gtk_list_store_set (self->priv->store, iter,
322 COL_SELECTED, TRUE,
323 -1);
325 return FALSE;
328 void
329 anjuta_vcs_status_tree_view_select_all (AnjutaVcsStatusTreeView *self)
331 gtk_tree_model_foreach (GTK_TREE_MODEL (self->priv->store),
332 (GtkTreeModelForeachFunc) select_all_paths,
333 self);
336 static gboolean
337 unselect_all_paths (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter,
338 AnjutaVcsStatusTreeView *self)
340 gtk_list_store_set (self->priv->store, iter,
341 COL_SELECTED, FALSE,
342 -1);
344 return FALSE;
347 void
348 anjuta_vcs_status_tree_view_unselect_all (AnjutaVcsStatusTreeView *self)
350 gtk_tree_model_foreach (GTK_TREE_MODEL (self->priv->store),
351 (GtkTreeModelForeachFunc) unselect_all_paths,
352 self);
355 static gboolean
356 create_selected_paths_list (GtkTreeModel *model, GtkTreePath *path,
357 GtkTreeIter *iter, GList **list)
359 gboolean selected;
360 gchar *file_path;
362 gtk_tree_model_get (model, iter,
363 COL_SELECTED, &selected,
364 COL_PATH, &file_path,
365 -1);
367 if (selected)
368 *list = g_list_append (*list, g_strdup (file_path));
370 return FALSE;
373 GList *
374 anjuta_vcs_status_tree_view_get_selected (AnjutaVcsStatusTreeView *self)
376 GList *list;
378 list = NULL;
380 gtk_tree_model_foreach (GTK_TREE_MODEL (self->priv->store),
381 (GtkTreeModelForeachFunc) create_selected_paths_list,
382 &list);
384 return list;