1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 * Copyright (C) James Liggett 2007 <jrliggett@cox.net>
6 * anjuta is free software.
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)
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"
26 #include <glib/gi18n.h>
28 /* A clean way to find out if conflicted items should be selectable */
29 #define IS_SELECTABLE(status, conflicted_selectable) ((status != ANJUTA_VCS_STATUS_CONFLICTED) || \
30 (status == ANJUTA_VCS_STATUS_CONFLICTED && \
31 conflicted_selectable))
43 ANJUTA_VCS_STATUS_TREE_VIEW_CONSTRUCT_STATUS_CODES
= 1,
44 ANJUTA_VCS_STATUS_TREE_VIEW_SHOW_STATUS
,
45 ANJUTA_VCS_STATUS_TREE_VIEW_CONSTRUCT_CONFLICTED_SELECTABLE
48 struct _AnjutaVcsStatusTreeViewPriv
53 gboolean conflicted_selectable
;
56 G_DEFINE_TYPE (AnjutaVcsStatusTreeView
, anjuta_vcs_status_tree_view
,
60 on_selected_column_toggled (GtkCellRendererToggle
*renderer
,
62 AnjutaVcsStatusTreeView
*self
)
67 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (self
->priv
->store
),
70 gtk_tree_model_get (GTK_TREE_MODEL (self
->priv
->store
), &iter
,
71 COL_SELECTED
, &selected
, -1);
73 gtk_list_store_set (self
->priv
->store
, &iter
,
74 COL_SELECTED
, !selected
, -1);
79 anjuta_vcs_status_tree_view_status_function (GtkTreeViewColumn
*tree_column
,
80 GtkCellRenderer
*renderer
,
85 AnjutaVcsStatus status
;
87 gtk_tree_model_get (model
, iter
, COL_STATUS
, &status
, -1);
91 case ANJUTA_VCS_STATUS_MODIFIED
:
92 g_object_set (G_OBJECT (renderer
), "text", _("Modified"), NULL
);
94 case ANJUTA_VCS_STATUS_ADDED
:
95 g_object_set (G_OBJECT (renderer
), "text", _("Added"), NULL
);
97 case ANJUTA_VCS_STATUS_DELETED
:
98 g_object_set (G_OBJECT (renderer
), "text", _("Deleted"), NULL
);
100 case ANJUTA_VCS_STATUS_CONFLICTED
:
101 g_object_set (G_OBJECT (renderer
), "text", _("Conflicted"),
104 case ANJUTA_VCS_STATUS_UPTODATE
:
105 g_object_set (G_OBJECT (renderer
), "text", _("Up-to-date"),
108 case ANJUTA_VCS_STATUS_LOCKED
:
109 g_object_set (G_OBJECT (renderer
), "text", _("Locked"), NULL
);
111 case ANJUTA_VCS_STATUS_MISSING
:
112 g_object_set (G_OBJECT (renderer
), "text", _("Missing"), NULL
);
114 case ANJUTA_VCS_STATUS_UNVERSIONED
:
115 g_object_set (G_OBJECT (renderer
), "text", _("Unversioned"),
118 case ANJUTA_VCS_STATUS_IGNORED
:
119 g_object_set (G_OBJECT (renderer
), "text", _("Ignored"),
122 case ANJUTA_VCS_STATUS_NONE
:
129 anjuta_vcs_status_tree_view_icon_function (GtkTreeViewColumn
*tree_column
,
130 GtkCellRenderer
*renderer
,
135 AnjutaVcsStatus status
;
137 gtk_tree_model_get (model
, iter
, COL_STATUS
, &status
, -1);
141 case ANJUTA_VCS_STATUS_MODIFIED
:
142 g_object_set (G_OBJECT (renderer
), "stock-id", GTK_STOCK_EDIT
,
145 case ANJUTA_VCS_STATUS_ADDED
:
146 g_object_set (G_OBJECT (renderer
), "stock-id", GTK_STOCK_ADD
,
149 case ANJUTA_VCS_STATUS_DELETED
:
150 g_object_set (G_OBJECT (renderer
), "stock-id", GTK_STOCK_REMOVE
,
153 case ANJUTA_VCS_STATUS_CONFLICTED
:
154 g_object_set (G_OBJECT (renderer
), "stock-id",
155 GTK_STOCK_DIALOG_WARNING
, NULL
);
157 case ANJUTA_VCS_STATUS_UPTODATE
:
158 g_object_set (G_OBJECT (renderer
), "stock-id", GTK_STOCK_APPLY
,
161 case ANJUTA_VCS_STATUS_LOCKED
:
162 g_object_set (G_OBJECT (renderer
), "stock-id",
163 GTK_STOCK_DIALOG_AUTHENTICATION
, NULL
);
165 case ANJUTA_VCS_STATUS_MISSING
:
166 g_object_set (G_OBJECT (renderer
), "stock-id",
167 GTK_STOCK_MISSING_IMAGE
, NULL
);
169 case ANJUTA_VCS_STATUS_UNVERSIONED
:
170 g_object_set (G_OBJECT (renderer
), "stock-id",
171 GTK_STOCK_DIALOG_QUESTION
, NULL
);
173 case ANJUTA_VCS_STATUS_IGNORED
:
174 g_object_set (G_OBJECT (renderer
), "stock-id", GTK_STOCK_STOP
,
177 case ANJUTA_VCS_STATUS_NONE
:
184 anjuta_vcs_status_tree_view_activatable_function (GtkTreeViewColumn
*tree_column
,
185 GtkCellRenderer
*renderer
,
188 AnjutaVcsStatusTreeView
*self
)
190 AnjutaVcsStatus status
;
192 gtk_tree_model_get (model
, iter
, COL_STATUS
, &status
, -1);
194 g_object_set (G_OBJECT (renderer
), "activatable", IS_SELECTABLE (status
,
195 self
->priv
->conflicted_selectable
),
200 anjuta_vcs_status_tree_view_create_columns (AnjutaVcsStatusTreeView
*self
)
202 GtkTreeViewColumn
*column
;
203 GtkCellRenderer
*renderer
;
205 /* Selected column */
206 column
= gtk_tree_view_column_new ();
207 renderer
= gtk_cell_renderer_toggle_new ();
208 gtk_tree_view_column_pack_start (column
, renderer
, TRUE
);
209 gtk_tree_view_append_column (GTK_TREE_VIEW (self
), column
);
210 gtk_tree_view_column_add_attribute (column
, renderer
, "active",
212 gtk_tree_view_column_set_cell_data_func (column
, renderer
,
213 (GtkTreeCellDataFunc
) anjuta_vcs_status_tree_view_activatable_function
,
216 g_signal_connect (G_OBJECT (renderer
), "toggled",
217 G_CALLBACK (on_selected_column_toggled
),
221 column
= gtk_tree_view_column_new ();
224 renderer
= gtk_cell_renderer_pixbuf_new ();
225 gtk_tree_view_column_pack_start (column
, renderer
, TRUE
);
226 gtk_tree_view_column_set_cell_data_func (column
, renderer
,
227 (GtkTreeCellDataFunc
) anjuta_vcs_status_tree_view_icon_function
,
230 renderer
= gtk_cell_renderer_text_new ();
231 gtk_tree_view_column_pack_start (column
, renderer
, TRUE
);
232 gtk_tree_view_append_column (GTK_TREE_VIEW (self
), column
);
233 gtk_tree_view_column_set_cell_data_func (column
, renderer
,
234 (GtkTreeCellDataFunc
) anjuta_vcs_status_tree_view_status_function
,
238 column
= gtk_tree_view_column_new ();
239 renderer
= gtk_cell_renderer_text_new ();
240 gtk_tree_view_column_pack_start (column
, renderer
, TRUE
);
241 gtk_tree_view_append_column (GTK_TREE_VIEW (self
), column
);
242 gtk_tree_view_column_add_attribute (column
, renderer
, "text",
245 gtk_tree_view_set_model (GTK_TREE_VIEW (self
),
246 GTK_TREE_MODEL (self
->priv
->store
));
247 g_object_unref (self
->priv
->store
);
252 path_sort (GtkTreeModel
*model
, GtkTreeIter
*a
, GtkTreeIter
*b
,
259 gtk_tree_model_get (model
, a
, COL_PATH
, &path1
, -1);
260 gtk_tree_model_get (model
, b
, COL_PATH
, &path2
, -1);
262 compare_value
= strcmp (path1
, path2
);
267 return compare_value
;
271 anjuta_vcs_status_tree_view_init (AnjutaVcsStatusTreeView
*self
)
273 GtkTreeSortable
*sortable
;
275 self
->priv
= g_new0 (AnjutaVcsStatusTreeViewPriv
, 1);
276 self
->priv
->store
= gtk_list_store_new (NUM_COLS
,
278 ANJUTA_TYPE_VCS_STATUS
,
281 anjuta_vcs_status_tree_view_create_columns (self
);
282 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (self
), FALSE
);
284 sortable
= GTK_TREE_SORTABLE (self
->priv
->store
);
285 gtk_tree_sortable_set_sort_column_id (sortable
, COL_PATH
,
287 gtk_tree_sortable_set_sort_func (sortable
, COL_PATH
, path_sort
, NULL
,
292 anjuta_vcs_status_tree_view_finalize (GObject
*object
)
294 AnjutaVcsStatusTreeView
*self
;
296 self
= ANJUTA_VCS_STATUS_TREE_VIEW (object
);
300 G_OBJECT_CLASS (anjuta_vcs_status_tree_view_parent_class
)->finalize (object
);
304 anjuta_vcs_status_tree_view_set_property (GObject
*object
, guint property_id
,
306 GParamSpec
*param_spec
)
308 AnjutaVcsStatusTreeView
*self
;
309 GtkTreeView
*tree_view
;
310 GtkTreeViewColumn
*column
;
312 self
= ANJUTA_VCS_STATUS_TREE_VIEW (object
);
316 case ANJUTA_VCS_STATUS_TREE_VIEW_CONSTRUCT_STATUS_CODES
:
317 self
->priv
->status_codes
= g_value_get_flags (value
);
319 case ANJUTA_VCS_STATUS_TREE_VIEW_SHOW_STATUS
:
320 tree_view
= GTK_TREE_VIEW (object
);
321 column
= gtk_tree_view_get_column (tree_view
, COL_STATUS
);
322 self
->priv
->show_status
= g_value_get_boolean (value
);
324 gtk_tree_view_column_set_visible (column
, self
->priv
->show_status
);
326 case ANJUTA_VCS_STATUS_TREE_VIEW_CONSTRUCT_CONFLICTED_SELECTABLE
:
327 self
->priv
->conflicted_selectable
= g_value_get_boolean (value
);
330 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, param_spec
);
336 anjuta_vcs_status_tree_view_get_property (GObject
*object
, guint property_id
,
337 GValue
*value
, GParamSpec
*param_spec
)
339 AnjutaVcsStatusTreeView
*self
;
341 self
= ANJUTA_VCS_STATUS_TREE_VIEW (object
);
345 case ANJUTA_VCS_STATUS_TREE_VIEW_CONSTRUCT_STATUS_CODES
:
346 g_value_set_flags (value
, self
->priv
->status_codes
);
348 case ANJUTA_VCS_STATUS_TREE_VIEW_SHOW_STATUS
:
349 g_value_set_boolean (value
, self
->priv
->show_status
);
351 case ANJUTA_VCS_STATUS_TREE_VIEW_CONSTRUCT_CONFLICTED_SELECTABLE
:
352 g_value_set_boolean (value
, self
->priv
->conflicted_selectable
);
355 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, param_spec
);
361 anjuta_vcs_status_tree_view_class_init (AnjutaVcsStatusTreeViewClass
*klass
)
363 GObjectClass
* object_class
= G_OBJECT_CLASS (klass
);
364 GParamSpec
*param_spec
;
366 object_class
->finalize
= anjuta_vcs_status_tree_view_finalize
;
367 object_class
->get_property
= anjuta_vcs_status_tree_view_get_property
;
368 object_class
->set_property
= anjuta_vcs_status_tree_view_set_property
;
370 param_spec
= g_param_spec_flags ("status-codes", "Status codes",
371 "Control which status codes are shown in "
373 ANJUTA_TYPE_VCS_STATUS
,
374 ANJUTA_VCS_DEFAULT_STATUS_CODES
,
376 G_PARAM_CONSTRUCT_ONLY
);
377 g_object_class_install_property (object_class
,
378 ANJUTA_VCS_STATUS_TREE_VIEW_CONSTRUCT_STATUS_CODES
,
381 param_spec
= g_param_spec_boolean ("show-status", "Show status",
382 "Show or hide status description",
385 g_object_class_install_property (object_class
,
386 ANJUTA_VCS_STATUS_TREE_VIEW_SHOW_STATUS
,
389 param_spec
= g_param_spec_boolean ("conflicted-selectable",
390 "Conflicted items selectable",
391 "Allow/disallow the user to select "
392 "Conflicted status items.",
395 G_PARAM_CONSTRUCT_ONLY
);
396 g_object_class_install_property (object_class
,
397 ANJUTA_VCS_STATUS_TREE_VIEW_CONSTRUCT_CONFLICTED_SELECTABLE
,
403 anjuta_vcs_status_tree_view_new (void)
405 return g_object_new (ANJUTA_VCS_TYPE_STATUS_TREE_VIEW
, NULL
);
409 anjuta_vcs_status_tree_view_destroy (AnjutaVcsStatusTreeView
*self
)
411 g_object_unref (self
);
415 anjuta_vcs_status_tree_view_add (AnjutaVcsStatusTreeView
*self
, gchar
*path
,
416 AnjutaVcsStatus status
, gboolean selected
)
420 if (status
& self
->priv
->status_codes
)
422 gtk_list_store_append (self
->priv
->store
, &iter
);
424 gtk_list_store_set (self
->priv
->store
, &iter
,
425 COL_SELECTED
, (IS_SELECTABLE (status
,
426 self
->priv
->conflicted_selectable
) &&
435 select_all_paths (GtkTreeModel
*model
, GtkTreePath
*path
, GtkTreeIter
*iter
,
436 AnjutaVcsStatusTreeView
*self
)
438 AnjutaVcsStatus status
;
440 gtk_tree_model_get (model
, iter
, COL_STATUS
, &status
, -1);
442 if (IS_SELECTABLE (status
, self
->priv
->conflicted_selectable
))
444 gtk_list_store_set (self
->priv
->store
, iter
,
453 anjuta_vcs_status_tree_view_select_all (AnjutaVcsStatusTreeView
*self
)
455 gtk_tree_model_foreach (GTK_TREE_MODEL (self
->priv
->store
),
456 (GtkTreeModelForeachFunc
) select_all_paths
,
461 unselect_all_paths (GtkTreeModel
*model
, GtkTreePath
*path
, GtkTreeIter
*iter
,
462 AnjutaVcsStatusTreeView
*self
)
464 gtk_list_store_set (self
->priv
->store
, iter
,
472 anjuta_vcs_status_tree_view_unselect_all (AnjutaVcsStatusTreeView
*self
)
474 gtk_tree_model_foreach (GTK_TREE_MODEL (self
->priv
->store
),
475 (GtkTreeModelForeachFunc
) unselect_all_paths
,
480 create_selected_paths_list (GtkTreeModel
*model
, GtkTreePath
*path
,
481 GtkTreeIter
*iter
, GList
**list
)
486 gtk_tree_model_get (model
, iter
,
487 COL_SELECTED
, &selected
,
488 COL_PATH
, &file_path
,
492 *list
= g_list_append (*list
, g_strdup (file_path
));
500 anjuta_vcs_status_tree_view_get_selected (AnjutaVcsStatusTreeView
*self
)
506 gtk_tree_model_foreach (GTK_TREE_MODEL (self
->priv
->store
),
507 (GtkTreeModelForeachFunc
) create_selected_paths_list
,