configure: Remove check for graphviz
[anjuta.git] / libanjuta / anjuta-pkg-config-chooser.c
blobe9159a9abc4abb3574706089e66d663812213236
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * pkg-config-chooser
4 * Copyright (C) Johannes Schmid 2010 <jhs@gnome.org>
5 *
6 * pkg-config-chooser 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 2 of the License, or
9 * (at your option) any later version.
11 * pkg-config-chooser 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 "anjuta-pkg-config-chooser.h"
21 #include <glib/gi18n.h>
22 #include <libanjuta/anjuta-launcher.h>
24 #define PKG_CONFIG_LIST_ALL "pkg-config --list-all"
26 enum
28 PACKAGE_ACTIVATED,
29 PACKAGE_DEACTIVATED,
30 LAST_SIGNAL
33 enum
35 COLUMN_ACTIVE,
36 COLUMN_NAME,
37 COLUMN_DESCRIPTION,
38 N_COLUMNS
41 struct _AnjutaPkgConfigChooserPrivate
43 AnjutaLauncher* launcher;
44 GtkTreeModel* model;
45 GtkTreeModelFilter* filter_model;
46 GtkTreeModelSort* sort_model;
48 gboolean selected_only;
49 gboolean scanning;
51 GList* selected_cache;
54 static guint pkg_config_chooser_signals[LAST_SIGNAL] = { 0 };
56 G_DEFINE_TYPE (AnjutaPkgConfigChooser, anjuta_pkg_config_chooser, GTK_TYPE_TREE_VIEW);
58 static gboolean
59 filter_visible_func (GtkTreeModel* model,
60 GtkTreeIter* iter,
61 gpointer data)
63 AnjutaPkgConfigChooser* chooser = data;
65 if (!chooser->priv->selected_only)
66 return TRUE;
67 else
69 gboolean show;
70 gtk_tree_model_get (model, iter,
71 COLUMN_ACTIVE, &show, -1);
72 return show;
76 static void
77 on_listall_output (AnjutaLauncher * launcher,
78 AnjutaLauncherOutputType output_type,
79 const gchar * chars, gpointer user_data)
81 gchar **lines;
82 const gchar *curr_line;
83 gint i = 0;
84 AnjutaPkgConfigChooser* chooser;
85 GtkListStore* store;
87 if (output_type == ANJUTA_LAUNCHER_OUTPUT_STDERR)
89 /* no way. We don't like errors on stderr... */
90 return;
93 chooser = ANJUTA_PKG_CONFIG_CHOOSER (user_data);
95 store = GTK_LIST_STORE (chooser->priv->model);
96 lines = g_strsplit (chars, "\n", -1);
98 while ((curr_line = lines[i++]) != NULL)
100 gchar **pkgs;
101 GtkTreeIter iter;
103 pkgs = g_strsplit (curr_line, " ", 2);
105 /* just take the first token as it's the package-name */
106 if (pkgs == NULL)
107 return;
109 if (pkgs[0] == NULL || pkgs[1] == NULL) {
110 g_strfreev (pkgs);
111 continue;
114 gtk_list_store_append (store, &iter);
115 gtk_list_store_set (store, &iter,
116 COLUMN_ACTIVE, FALSE,
117 COLUMN_NAME, pkgs[0],
118 COLUMN_DESCRIPTION, g_strstrip(pkgs[1]), -1);
119 g_strfreev (pkgs);
121 g_strfreev (lines);
124 static void
125 on_listall_exit (AnjutaLauncher * launcher, int child_pid,
126 int exit_status, gulong time_taken_in_seconds,
127 gpointer user_data)
129 AnjutaPkgConfigChooser* chooser = ANJUTA_PKG_CONFIG_CHOOSER (user_data);
131 g_signal_handlers_disconnect_by_func (launcher, on_listall_exit,
132 user_data);
133 chooser->priv->scanning = FALSE;
135 anjuta_pkg_config_chooser_set_active_packages (chooser, chooser->priv->selected_cache);
136 g_list_foreach (chooser->priv->selected_cache, (GFunc) g_free, NULL);
138 g_object_unref (launcher);
141 static void
142 on_package_toggled (GtkCellRenderer* renderer,
143 const gchar* path,
144 AnjutaPkgConfigChooser* chooser)
146 GtkTreeIter sort_iter;
147 GtkTreeIter filter_iter;
148 GtkTreeIter iter;
149 gboolean active;
150 gchar* package;
152 GtkTreePath* tree_path = gtk_tree_path_new_from_string (path);
154 gtk_tree_model_get_iter (GTK_TREE_MODEL (chooser->priv->sort_model),
155 &sort_iter, tree_path);
156 gtk_tree_model_sort_convert_iter_to_child_iter (chooser->priv->sort_model,
157 &filter_iter, &sort_iter);
158 gtk_tree_model_filter_convert_iter_to_child_iter (chooser->priv->filter_model,
159 &iter, &filter_iter);
160 g_object_get (renderer, "active", &active, NULL);
162 active = !active;
164 gtk_list_store_set (GTK_LIST_STORE (chooser->priv->model),
165 &iter, COLUMN_ACTIVE, active, -1);
166 gtk_tree_model_get (chooser->priv->model, &iter,
167 COLUMN_NAME, &package, -1);
169 if (active)
170 g_signal_emit_by_name (chooser, "package-activated", package, NULL);
171 else
172 g_signal_emit_by_name (chooser, "package-deactivated", package, NULL);
175 static void
176 anjuta_pkg_config_chooser_init (AnjutaPkgConfigChooser *chooser)
178 GtkTreeViewColumn* column;
179 GtkCellRenderer* renderer;
181 chooser->priv = G_TYPE_INSTANCE_GET_PRIVATE (chooser, ANJUTA_TYPE_PKG_CONFIG_CHOOSER,
182 AnjutaPkgConfigChooserPrivate);
184 /* Create model */
185 chooser->priv->model = GTK_TREE_MODEL (gtk_list_store_new (N_COLUMNS,
186 G_TYPE_BOOLEAN,
187 G_TYPE_STRING,
188 G_TYPE_STRING));
189 chooser->priv->filter_model = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (chooser->priv->model,
190 NULL));
191 gtk_tree_model_filter_set_visible_func (chooser->priv->filter_model,
192 filter_visible_func,
193 chooser, NULL);
195 chooser->priv->sort_model =
196 GTK_TREE_MODEL_SORT (gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL(chooser->priv->filter_model)));
197 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (chooser->priv->sort_model),
198 COLUMN_NAME, GTK_SORT_ASCENDING);
200 gtk_tree_view_set_model (GTK_TREE_VIEW (chooser),
201 GTK_TREE_MODEL (chooser->priv->sort_model));
203 /* Create columns */
204 renderer = gtk_cell_renderer_toggle_new ();
205 g_signal_connect (renderer, "toggled", G_CALLBACK(on_package_toggled), chooser);
206 column = gtk_tree_view_column_new_with_attributes ("",
207 renderer,
208 "active", COLUMN_ACTIVE,
209 NULL);
210 gtk_tree_view_append_column (GTK_TREE_VIEW (chooser), column);
212 renderer = gtk_cell_renderer_text_new ();
213 column = gtk_tree_view_column_new_with_attributes ("",
214 renderer,
215 "text", COLUMN_NAME,
216 NULL);
217 gtk_tree_view_append_column (GTK_TREE_VIEW (chooser), column);
218 renderer = gtk_cell_renderer_text_new ();
219 column = gtk_tree_view_column_new_with_attributes ("",
220 renderer,
221 "text", COLUMN_DESCRIPTION,
222 NULL);
223 gtk_tree_view_append_column (GTK_TREE_VIEW (chooser), column);
224 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (chooser), FALSE);
226 gtk_tree_view_set_search_column (GTK_TREE_VIEW (chooser),
227 COLUMN_NAME);
229 /* Create launcher */
230 chooser->priv->scanning = TRUE;
231 chooser->priv->launcher = anjuta_launcher_new ();
232 anjuta_launcher_set_check_passwd_prompt (chooser->priv->launcher,
233 FALSE);
235 g_signal_connect (G_OBJECT (chooser->priv->launcher), "child-exited",
236 G_CALLBACK (on_listall_exit), chooser);
238 anjuta_launcher_execute (chooser->priv->launcher,
239 PKG_CONFIG_LIST_ALL, on_listall_output,
240 chooser);
243 static void
244 anjuta_pkg_config_chooser_finalize (GObject *object)
247 G_OBJECT_CLASS (anjuta_pkg_config_chooser_parent_class)->finalize (object);
250 static void
251 anjuta_pkg_config_chooser_class_init (AnjutaPkgConfigChooserClass *klass)
253 GObjectClass* object_class = G_OBJECT_CLASS (klass);
255 object_class->finalize = anjuta_pkg_config_chooser_finalize;
258 * AnjutaPkgConfigChooser::package-activated:
259 * @widget: the AnjutaPkgConfigChooser that received the signal
260 * @package: Name of the package that was activated
262 * The ::package-activated signal is emitted when a package is activated in the list
264 pkg_config_chooser_signals[PACKAGE_ACTIVATED] =
265 g_signal_new ("package-activated",
266 G_OBJECT_CLASS_TYPE (klass),
268 G_STRUCT_OFFSET (AnjutaPkgConfigChooserClass, package_activated),
269 NULL, NULL,
270 g_cclosure_marshal_VOID__STRING,
271 G_TYPE_NONE, 1,
272 G_TYPE_STRING);
274 * AnjutaPkgConfigChooser::package-deactivated:
275 * @widget: the AnjutaPkgConfigChooser that received the signal
276 * @package: Name of the package that was deactivated
278 * The ::package-activated signal is emitted when a package is deactivated in the list
280 pkg_config_chooser_signals[PACKAGE_DEACTIVATED] =
281 g_signal_new ("package-deactivated",
282 G_OBJECT_CLASS_TYPE (klass),
284 G_STRUCT_OFFSET (AnjutaPkgConfigChooserClass, package_deactivated),
285 NULL, NULL,
286 g_cclosure_marshal_VOID__STRING,
287 G_TYPE_NONE, 1,
288 G_TYPE_STRING);
290 g_type_class_add_private (klass, sizeof(AnjutaPkgConfigChooserPrivate));
294 * anjuta_pkg_config_chooser_new:
296 * Returns: A new AnjutaPkgConfigChooser widget
298 GtkWidget*
299 anjuta_pkg_config_chooser_new (void)
301 return GTK_WIDGET (g_object_new (ANJUTA_TYPE_PKG_CONFIG_CHOOSER, NULL));
305 * anjuta_pkg_config_chooser_get_active_packages:
306 * @chooser: A AnjutaPkgConfigChooser
308 * Return value: (element-type utf8) (transfer full):
309 * List of packages that are activated
311 GList*
312 anjuta_pkg_config_chooser_get_active_packages (AnjutaPkgConfigChooser* chooser)
314 GList* packages = NULL;
315 GtkTreeIter iter;
317 g_return_val_if_fail (ANJUTA_IS_PKG_CONFIG_CHOOSER (chooser), NULL);
319 if (gtk_tree_model_get_iter_first (chooser->priv->model, &iter))
323 gchar* model_pkg;
324 gboolean active;
325 gtk_tree_model_get (chooser->priv->model, &iter,
326 COLUMN_NAME, &model_pkg,
327 COLUMN_ACTIVE, &active, -1);
328 if (active)
330 packages = g_list_append (packages, model_pkg);
333 while (gtk_tree_model_iter_next (chooser->priv->model,
334 &iter));
336 return packages;
340 * anjuta_pkg_config_chooser_get_active_packages:
341 * @chooser: A AnjutaPkgConfigChooser
342 * @packages: (element-type utf8) (transfer full): List of packages to be activated in the list
345 void
346 anjuta_pkg_config_chooser_set_active_packages (AnjutaPkgConfigChooser* chooser, GList* packages)
348 GList* pkg;
349 GtkTreeIter iter;
351 g_return_if_fail (ANJUTA_IS_PKG_CONFIG_CHOOSER (chooser));
353 /* Deselect all packages */
354 if (gtk_tree_model_get_iter_first (chooser->priv->model, &iter))
358 gtk_list_store_set (GTK_LIST_STORE (chooser->priv->model), &iter,
359 COLUMN_ACTIVE, FALSE, -1);
361 while (gtk_tree_model_iter_next (chooser->priv->model,
362 &iter));
365 for (pkg = packages; pkg != NULL; pkg = g_list_next (pkg))
367 if (chooser->priv->scanning)
369 chooser->priv->selected_cache = g_list_append (chooser->priv->selected_cache,
370 g_strdup(pkg->data));
372 else if (gtk_tree_model_get_iter_first (chooser->priv->model, &iter))
376 gchar* model_pkg;
377 gtk_tree_model_get (chooser->priv->model, &iter,
378 COLUMN_NAME, &model_pkg, -1);
379 if (g_str_equal (model_pkg, pkg->data))
381 gtk_list_store_set (GTK_LIST_STORE (chooser->priv->model), &iter,
382 COLUMN_ACTIVE, TRUE, -1);
384 g_free (model_pkg);
386 while (gtk_tree_model_iter_next (chooser->priv->model,
387 &iter));
393 * anjuta_pkg_config_chooser_show_active_only:
394 * @chooser: A AnjutaPkgConfigChooser
395 * @show_selected: whether to show only activated packages
397 * Show activated packages only, this is mainly useful when the tree is set
398 * insensitive but the user should be able to see which packages have been activated
400 void
401 anjuta_pkg_config_chooser_show_active_only (AnjutaPkgConfigChooser* chooser, gboolean show_selected)
403 g_return_if_fail (ANJUTA_IS_PKG_CONFIG_CHOOSER (chooser));
405 chooser->priv->selected_only = show_selected;
406 gtk_tree_model_filter_refilter (chooser->priv->filter_model);
410 * anjuta_pkg_config_chooser_show_active_column:
411 * @chooser: A AnjutaPkgConfigChooser
412 * @show_column: whether the active column should be shown
414 * Can be used to hide the active column in situation where you are more interested
415 * in the selection then in the activated packages.
417 void
418 anjuta_pkg_config_chooser_show_active_column (AnjutaPkgConfigChooser* chooser, gboolean show_column)
420 GtkTreeViewColumn* column;
422 g_return_if_fail (ANJUTA_IS_PKG_CONFIG_CHOOSER (chooser));
424 column = gtk_tree_view_get_column (GTK_TREE_VIEW (chooser), COLUMN_ACTIVE);
425 gtk_tree_view_column_set_visible (column, show_column);
429 * anjuta_pkg_config_chooser_get_selected_package:
430 * @chooser: A AnjutaPkgConfigChooser
432 * Return value: the currently selected packages in the list
435 gchar*
436 anjuta_pkg_config_chooser_get_selected_package (AnjutaPkgConfigChooser* chooser)
438 GtkTreeIter sort_iter;
439 GtkTreeSelection* selection;
441 g_return_val_if_fail (ANJUTA_IS_PKG_CONFIG_CHOOSER (chooser), NULL);
443 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (chooser));
445 if (gtk_tree_selection_get_selected (selection, NULL, &sort_iter))
447 gchar* package;
448 GtkTreeIter filter_iter;
449 GtkTreeIter iter;
450 gtk_tree_model_sort_convert_iter_to_child_iter (chooser->priv->sort_model,
451 &filter_iter, &sort_iter);
452 gtk_tree_model_filter_convert_iter_to_child_iter (chooser->priv->filter_model,
453 &iter, &filter_iter);
454 gtk_tree_model_get (chooser->priv->model, &iter, COLUMN_NAME, &package, -1);
456 return package;
458 return NULL;