code-analyzer: Fixed bgo#667903 - Code Analyzer Crashes
[anjuta.git] / plugins / git / git-tags-pane.c
blobf360f5d81eb2e6550400068ac9030b846f379284
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * git-shell-test
4 * Copyright (C) James Liggett 2010 <jrliggett@cox.net>
5 *
6 * git-shell-test 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 * git-shell-test 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-tags-pane.h"
22 enum
24 COL_SELECTED,
25 COL_NAME
28 static GtkTargetEntry drag_targets[] =
31 "STRING",
37 struct _GitTagsPanePriv
39 GtkBuilder *builder;
40 GtkListStore *tags_list_model;
42 GtkAction *delete_action;
46 G_DEFINE_TYPE (GitTagsPane, git_tags_pane, GIT_TYPE_PANE);
48 static void
49 on_tag_list_command_started (AnjutaCommand *command, GitTagsPane *self)
51 GtkTreeView *tags_view;
52 GtkListStore *tags_list_model;
54 tags_view = GTK_TREE_VIEW (gtk_builder_get_object (self->priv->builder,
55 "tags_view"));
56 tags_list_model = GTK_LIST_STORE (gtk_builder_get_object (self->priv->builder,
57 "tags_list_model"));
59 gtk_tree_view_set_model (tags_view, NULL);
60 gtk_list_store_clear (tags_list_model);
63 static void
64 on_tag_list_command_finished (AnjutaCommand *command, guint return_code,
65 GitTagsPane *self)
67 GtkTreeView *tags_view;
69 tags_view = GTK_TREE_VIEW (gtk_builder_get_object (self->priv->builder,
70 "tags_view"));
72 gtk_tree_view_set_model (tags_view, GTK_TREE_MODEL(self->priv->tags_list_model));
75 static void
76 on_tag_list_command_data_arrived (AnjutaCommand *command,
77 GtkListStore *tags_list_model)
79 GQueue *output;
80 GtkTreeIter iter;
81 gchar *name;
83 output = git_raw_output_command_get_output (GIT_RAW_OUTPUT_COMMAND (command));
85 while (g_queue_peek_head (output))
87 name = g_queue_pop_head (output);
88 gtk_list_store_append (tags_list_model, &iter);
90 gtk_list_store_set (tags_list_model, &iter,
91 COL_SELECTED, FALSE,
92 COL_NAME, name,
93 -1);
95 g_free (name);
100 static void
101 on_selected_renderer_toggled (GtkCellRendererToggle *renderer,
102 gchar *path, GitTagsPane* self)
104 GtkTreeIter iter;
105 gboolean selected;
107 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL(self->priv->tags_list_model),
108 &iter, path);
109 gtk_tree_model_get (GTK_TREE_MODEL(self->priv->tags_list_model), &iter,
110 COL_SELECTED, &selected,
111 -1);
113 selected = !selected;
115 gtk_list_store_set (GTK_LIST_STORE (self->priv->tags_list_model), &iter, 0, selected,
116 -1);
117 git_tags_pane_update_ui (self);
120 static void
121 on_tags_list_view_drag_data_get (GtkWidget *tags_list_view,
122 GdkDragContext *drag_context,
123 GtkSelectionData *data,
124 guint info, guint time,
125 gpointer user_data)
127 GtkTreeSelection *selection;
128 GtkTreeIter iter;
129 GtkTreeModel *tags_list_model;
130 gchar *name;
132 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tags_list_view));
134 if (gtk_tree_selection_count_selected_rows (selection) > 0)
136 gtk_tree_selection_get_selected (selection, &tags_list_model,
137 &iter);
139 gtk_tree_model_get (tags_list_model, &iter, COL_NAME, &name, -1);
141 gtk_selection_data_set_text (data, name, -1);
143 g_free (name);
147 static gboolean
148 get_selected_tags (GtkTreeModel *tags_list_model, gchar *path,
149 GtkTreeIter *iter, GList **list)
151 gboolean selected;
152 gchar *name;
154 gtk_tree_model_get (tags_list_model, iter, COL_SELECTED, &selected, -1);
156 if (selected)
158 gtk_tree_model_get (tags_list_model, iter, COL_NAME, &name, -1);
160 *list = g_list_append (*list, name);
163 return FALSE;
166 static void
167 git_tags_pane_init (GitTagsPane *self)
169 gchar *objects[] = {"tags_pane",
170 "tags_list_model",
171 NULL};
172 GError *error = NULL;
173 GtkTreeView *tags_view;
174 GtkCellRenderer *selected_renderer;
176 self->priv = g_new0 (GitTagsPanePriv, 1);
177 self->priv->builder = gtk_builder_new ();
180 if (!gtk_builder_add_objects_from_file (self->priv->builder, BUILDER_FILE,
181 objects,
182 &error))
184 g_warning ("Couldn't load builder file: %s", error->message);
185 g_error_free (error);
188 tags_view = GTK_TREE_VIEW (gtk_builder_get_object (self->priv->builder,
189 "tags_view"));
190 self->priv->tags_list_model =
191 GTK_LIST_STORE (gtk_builder_get_object (self->priv->builder,
192 "tags_list_model"));
193 selected_renderer = GTK_CELL_RENDERER (gtk_builder_get_object (self->priv->builder,
194 "selected_renderer"));
196 /* DND */
197 gtk_tree_view_enable_model_drag_source (tags_view,
198 GDK_BUTTON1_MASK,
199 drag_targets,
200 G_N_ELEMENTS (drag_targets),
201 GDK_ACTION_COPY);
203 g_signal_connect (G_OBJECT (tags_view), "drag-data-get",
204 G_CALLBACK (on_tags_list_view_drag_data_get),
205 NULL);
207 g_signal_connect (G_OBJECT (selected_renderer), "toggled",
208 G_CALLBACK (on_selected_renderer_toggled),
209 self);
212 static void
213 git_tags_pane_finalize (GObject *object)
215 GitTagsPane *self;
217 self = GIT_TAGS_PANE (object);
219 g_object_unref (self->priv->builder);
220 g_free (self->priv);
222 G_OBJECT_CLASS (git_tags_pane_parent_class)->finalize (object);
225 static GtkWidget *
226 git_tags_pane_get_widget (AnjutaDockPane *pane)
228 GitTagsPane *self;
230 self = GIT_TAGS_PANE (pane);
232 return GTK_WIDGET (gtk_builder_get_object (self->priv->builder,
233 "tags_pane"));
236 static void
237 git_tags_pane_class_init (GitTagsPaneClass *klass)
239 GObjectClass* object_class = G_OBJECT_CLASS (klass);
240 AnjutaDockPaneClass *pane_class = ANJUTA_DOCK_PANE_CLASS (klass);
242 object_class->finalize = git_tags_pane_finalize;
243 pane_class->get_widget = git_tags_pane_get_widget;
244 pane_class->refresh = NULL;
248 AnjutaDockPane *
249 git_tags_pane_new (Git *plugin)
251 GitTagsPane *self;
252 self = g_object_new (GIT_TYPE_TAGS_PANE, "plugin", plugin, NULL);
255 g_signal_connect (G_OBJECT (plugin->tag_list_command), "command-started",
256 G_CALLBACK (on_tag_list_command_started),
257 self);
259 g_signal_connect (G_OBJECT (plugin->tag_list_command), "command-finished",
260 G_CALLBACK (on_tag_list_command_finished),
261 self);
263 g_signal_connect (G_OBJECT (plugin->tag_list_command), "data-arrived",
264 G_CALLBACK (on_tag_list_command_data_arrived),
265 self->priv->tags_list_model);
267 return ANJUTA_DOCK_PANE (self);
270 GList *
271 git_tags_pane_get_selected_tags (GitTagsPane *self)
273 GList *list;
274 list = NULL;
276 gtk_tree_model_foreach (GTK_TREE_MODEL(self->priv->tags_list_model),
277 (GtkTreeModelForeachFunc) get_selected_tags, &list);
279 return list;
282 void git_tags_pane_update_ui (GitTagsPane *self)
284 GList* selected_tags;
286 /* Enable only actions that make sense with the selection */
287 if (!self->priv->delete_action)
289 Git* plugin =
290 ANJUTA_PLUGIN_GIT (anjuta_dock_pane_get_plugin (ANJUTA_DOCK_PANE (self)));
291 AnjutaCommandBar* bar = anjuta_dock_get_command_bar (ANJUTA_DOCK(plugin->dock));
292 self->priv->delete_action = anjuta_command_bar_get_action (bar,
293 "Tags",
294 "DeleteTags");
296 selected_tags = git_tags_pane_get_selected_tags (self);
297 gtk_action_set_sensitive (self->priv->delete_action, g_list_length (selected_tags) > 0);
298 g_list_free (selected_tags);