glade: Fix make file some files were not installed
[anjuta.git] / plugins / project-manager / project-chooser.c
blob27ae7e7fa9d885053747d7364f12efba29e4abd0
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4; coding: utf-8 -*- */
3 /* project-chooser.c
5 * Copyright (C) 2012 Sébastien Granjoux
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public
18 * License along with this program; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
26 #ifdef HAVE_CONFIG_H
27 #include <config.h>
28 #endif
30 #include "project-chooser.h"
32 #include <glib/gi18n.h>
34 #include <libanjuta/interfaces/ianjuta-project-chooser.h>
36 #include "project-model.h"
37 #include "project-view.h"
38 #include "tree-data.h"
39 #include "plugin.h"
42 /* Types
43 *---------------------------------------------------------------------------*/
45 struct _AnjutaPmChooserButtonPrivate
47 AnjutaProjectNodeType child;
50 static void ianjuta_project_chooser_init (IAnjutaProjectChooserIface *iface);
52 G_DEFINE_DYNAMIC_TYPE_EXTENDED (AnjutaPmChooserButton,
53 anjuta_pm_chooser_button,
54 ANJUTA_TYPE_TREE_COMBO_BOX,
56 G_IMPLEMENT_INTERFACE (IANJUTA_TYPE_PROJECT_CHOOSER,
57 ianjuta_project_chooser_init));
59 /* Helpers functions
60 *---------------------------------------------------------------------------*/
63 /* Private functions
64 *---------------------------------------------------------------------------*/
66 static gboolean
67 is_node_valid (GtkTreeModel *model, GtkTreeIter *iter, AnjutaPmChooserButton *button)
69 GbfTreeData *data = NULL;
70 gboolean valid = FALSE;
72 gtk_tree_model_get (model, iter, GBF_PROJECT_MODEL_COLUMN_DATA, &data, -1);
73 if ((data != NULL) && (data->node != NULL))
75 AnjutaPmChooserButtonPrivate *priv;
76 gint mask;
78 priv = G_TYPE_INSTANCE_GET_PRIVATE (button,
79 ANJUTA_TYPE_PM_CHOOSER_BUTTON,
80 AnjutaPmChooserButtonPrivate);
82 switch (priv->child)
84 case ANJUTA_PROJECT_ROOT:
85 /* Allow all nodes */
86 mask = -1;
87 break;
88 case ANJUTA_PROJECT_MODULE:
89 /* Only module parent */
90 mask = ANJUTA_PROJECT_CAN_ADD_MODULE;
91 break;
92 case ANJUTA_PROJECT_PACKAGE:
93 /* Only package parent */
94 mask = ANJUTA_PROJECT_CAN_ADD_PACKAGE;
95 break;
96 case ANJUTA_PROJECT_SOURCE:
97 /* Only package parent */
98 mask = ANJUTA_PROJECT_CAN_ADD_SOURCE;
99 break;
100 case ANJUTA_PROJECT_TARGET:
101 /* Only package parent */
102 mask = ANJUTA_PROJECT_CAN_ADD_TARGET;
103 break;
104 case ANJUTA_PROJECT_GROUP:
105 /* Only group parent */
106 mask = ANJUTA_PROJECT_CAN_ADD_GROUP;
107 break;
108 default:
109 mask = 0;
110 break;
113 valid = anjuta_project_node_get_state (ANJUTA_PROJECT_NODE (data->node)) & mask ? TRUE : FALSE;
116 return valid;
119 static void
120 setup_nodes_combo_box (AnjutaPmChooserButton *view,
121 GbfProjectModel *model,
122 GtkTreePath *root,
123 GtkTreeModelFilterVisibleFunc func,
124 gpointer data,
125 GtkTreeIter *selected)
127 GtkTreeIter iter;
129 g_return_if_fail (view != NULL);
130 g_return_if_fail (model != NULL);
132 if ((func != NULL) || (root != NULL))
134 GtkTreeModel *filter;
136 filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (model), root);
137 if (func != NULL)
139 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter), func, data, NULL);
141 anjuta_tree_combo_box_set_model (ANJUTA_TREE_COMBO_BOX (view), filter);
142 g_object_unref (filter);
143 if (pm_convert_project_iter_to_model_iter (filter, &iter, selected))
145 anjuta_tree_combo_box_set_active_iter (ANJUTA_TREE_COMBO_BOX (view), &iter);
148 else
150 anjuta_tree_combo_box_set_model (ANJUTA_TREE_COMBO_BOX (view), GTK_TREE_MODEL (model));
151 if (selected)
153 anjuta_tree_combo_box_set_active_iter (ANJUTA_TREE_COMBO_BOX (view), selected);
158 /* Callbacks functions
159 *---------------------------------------------------------------------------*/
161 static gboolean
162 is_project_node_but_shortcut (GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
164 GbfTreeData *data;
166 gtk_tree_model_get (GTK_TREE_MODEL (model), iter,
167 GBF_PROJECT_MODEL_COLUMN_DATA, &data,
168 -1);
170 return (data != NULL) && (data->shortcut == NULL) && (gbf_tree_data_get_node (data) != NULL);
173 static gboolean
174 is_project_module_node (GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
176 GbfTreeData *data;
178 gtk_tree_model_get (GTK_TREE_MODEL (model), iter,
179 GBF_PROJECT_MODEL_COLUMN_DATA, &data,
180 -1);
181 if ((data != NULL) && (data->shortcut == NULL))
183 AnjutaProjectNode *node = gbf_tree_data_get_node (data);
185 if ((node != NULL) && ((anjuta_project_node_get_node_type (node) & ANJUTA_PROJECT_TYPE_MASK) == ANJUTA_PROJECT_MODULE))
187 return TRUE;
191 return FALSE;
194 static gboolean
195 is_project_target_or_group_node (GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
197 GbfTreeData *data;
199 gtk_tree_model_get (GTK_TREE_MODEL (model), iter,
200 GBF_PROJECT_MODEL_COLUMN_DATA, &data,
201 -1);
202 if ((data != NULL) && (data->shortcut == NULL))
204 AnjutaProjectNode *node = gbf_tree_data_get_node (data);
206 if (node != NULL)
208 AnjutaProjectNodeType type = anjuta_project_node_get_node_type (node) & ANJUTA_PROJECT_TYPE_MASK;
210 return (type == ANJUTA_PROJECT_TARGET) || (type == ANJUTA_PROJECT_GROUP) || (type == ANJUTA_PROJECT_ROOT);
214 return FALSE;
217 static gboolean
218 is_project_group_node (GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
220 GbfTreeData *data;
222 gtk_tree_model_get (GTK_TREE_MODEL (model), iter,
223 GBF_PROJECT_MODEL_COLUMN_DATA, &data,
224 -1);
225 if ((data != NULL) && (data->shortcut == NULL))
227 AnjutaProjectNode *node = gbf_tree_data_get_node (data);
229 if (node != NULL)
231 AnjutaProjectNodeType type = anjuta_project_node_get_node_type (node) & ANJUTA_PROJECT_TYPE_MASK;
233 return (type == ANJUTA_PROJECT_GROUP) || (type == ANJUTA_PROJECT_ROOT);
237 return FALSE;
241 /* Public functions
242 *---------------------------------------------------------------------------*/
244 GtkWidget *
245 anjuta_pm_chooser_button_new (void)
247 return g_object_new (ANJUTA_TYPE_PM_CHOOSER_BUTTON, NULL);
251 /* Implement IAnjutaProjectChooser interface
252 *---------------------------------------------------------------------------*/
254 typedef struct
256 GtkTreeIter iter;
257 gboolean found;
258 AnjutaPmChooserButton *button;
259 } SearchPacket;
261 static gboolean
262 anjuta_pm_chooser_is_node_valid (GtkTreeModel *model,
263 GtkTreePath *path,
264 GtkTreeIter *iter,
265 gpointer data)
267 SearchPacket *packet = (SearchPacket *)data;
269 if (is_node_valid (model, iter, packet->button))
271 packet->iter = *iter;
272 packet->found = TRUE;
274 return TRUE;
277 return FALSE;
280 static gboolean
281 anjuta_pm_chooser_set_project_model (IAnjutaProjectChooser *iface, IAnjutaProjectManager *manager, AnjutaProjectNodeType child_type, GError **error)
283 GtkTreeIter selected;
284 gboolean found;
285 GtkTreeModelFilterVisibleFunc func;
286 const gchar *label;
287 GbfProjectModel *model;
289 ANJUTA_PM_CHOOSER_BUTTON (iface)->priv->child = child_type & ANJUTA_PROJECT_TYPE_MASK;
291 switch (child_type & ANJUTA_PROJECT_TYPE_MASK)
293 case ANJUTA_PROJECT_ROOT:
294 /* Display all nodes */
295 func = is_project_node_but_shortcut;
296 label = _("<Select any project node>");
297 break;
298 case ANJUTA_PROJECT_MODULE:
299 /* Display all targets */
300 func = is_project_target_or_group_node;
301 label = _("<Select a target>");
302 break;
303 case ANJUTA_PROJECT_PACKAGE:
304 /* Display all modules */
305 func = is_project_module_node;
306 label = _("<Select any module>");
307 break;
308 case ANJUTA_PROJECT_SOURCE:
309 /* Display all targets */
310 func = is_project_target_or_group_node;
311 label = _("<Select a target>");
312 break;
313 case ANJUTA_PROJECT_TARGET:
314 /* Display all targets */
315 func = is_project_target_or_group_node;
316 label = _("<Select a target or a folder>");
317 break;
318 case ANJUTA_PROJECT_GROUP:
319 /* Display all groups */
320 func = is_project_group_node;
321 label = _("<Select a folder>");
322 break;
323 default:
324 /* Invalid type */
325 return FALSE;
328 anjuta_tree_combo_box_set_invalid_text (ANJUTA_TREE_COMBO_BOX (iface), label);
329 anjuta_tree_combo_box_set_valid_function (ANJUTA_TREE_COMBO_BOX (iface), (GtkTreeModelFilterVisibleFunc)is_node_valid, iface, NULL);
331 /* Find a default node */
332 model = gbf_project_view_get_model(ANJUTA_PLUGIN_PROJECT_MANAGER (manager)->view);
333 found = gbf_project_view_get_first_selected (ANJUTA_PLUGIN_PROJECT_MANAGER (manager)->view, &selected) != NULL;
334 while (found && !is_node_valid (GTK_TREE_MODEL (model), &selected, ANJUTA_PM_CHOOSER_BUTTON (iface)))
336 GtkTreeIter iter;
338 found = gtk_tree_model_iter_parent (GTK_TREE_MODEL (model), &iter, &selected);
339 selected = iter;
341 if (!found)
343 SearchPacket packet;
345 packet.found = FALSE;
346 packet.button = ANJUTA_PM_CHOOSER_BUTTON (iface);
347 gtk_tree_model_foreach (GTK_TREE_MODEL (model), anjuta_pm_chooser_is_node_valid, &packet);
349 if (packet.found)
351 found = packet.found;
352 selected = packet.iter;
356 /* Add combo node selection */
357 setup_nodes_combo_box (ANJUTA_PM_CHOOSER_BUTTON (iface),
358 model,
359 NULL,
360 func,
361 NULL,
362 found ? &selected : NULL);
364 return TRUE;
367 static GFile *
368 anjuta_pm_chooser_get_selected (IAnjutaProjectChooser *iface, GError **error)
370 GtkTreeIter iter;
372 if (anjuta_tree_combo_box_get_active_iter (ANJUTA_TREE_COMBO_BOX (iface), &iter))
374 GtkTreeModel *model;
376 model = anjuta_tree_combo_box_get_model (ANJUTA_TREE_COMBO_BOX (iface));
378 if (is_node_valid (model, &iter, ANJUTA_PM_CHOOSER_BUTTON (iface)))
380 GbfTreeData *data;
382 gtk_tree_model_get (model, &iter, GBF_PROJECT_MODEL_COLUMN_DATA, &data, -1);
384 return anjuta_project_node_get_file (data->node);
388 return NULL;
391 static void
392 ianjuta_project_chooser_init (IAnjutaProjectChooserIface *iface)
394 iface->set_project_model = anjuta_pm_chooser_set_project_model;
395 iface->get_selected = anjuta_pm_chooser_get_selected;
398 /* Implement GObject functions
399 *---------------------------------------------------------------------------*/
401 static GObject *
402 anjuta_pm_chooser_button_constructor (GType type,
403 guint n_construct_properties,
404 GObjectConstructParam *construct_properties)
406 GObject *object;
408 object = G_OBJECT_CLASS (anjuta_pm_chooser_button_parent_class)->constructor
409 (type, n_construct_properties, construct_properties);
411 pm_setup_project_renderer (GTK_CELL_LAYOUT (object));
413 return object;
416 static void
417 anjuta_pm_chooser_button_init (AnjutaPmChooserButton *button)
419 AnjutaPmChooserButtonPrivate *priv;
421 priv = G_TYPE_INSTANCE_GET_PRIVATE (button,
422 ANJUTA_TYPE_PM_CHOOSER_BUTTON,
423 AnjutaPmChooserButtonPrivate);
424 button->priv = priv;
427 static void
428 anjuta_pm_chooser_button_class_init (AnjutaPmChooserButtonClass * klass)
430 GObjectClass *object_class;
432 object_class = (GObjectClass *)klass;
433 object_class->constructor = anjuta_pm_chooser_button_constructor;
435 g_type_class_add_private (klass, sizeof (AnjutaPmChooserButtonPrivate));
438 static void
439 anjuta_pm_chooser_button_class_finalize (AnjutaPmChooserButtonClass * klass)
443 void
444 anjuta_pm_chooser_button_register (GTypeModule *module)
446 anjuta_pm_chooser_button_register_type (module);