1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4; coding: utf-8 -*- */
4 * Copyright (C) 2009 Sébastien Granjoux
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public
17 * License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
27 #include <glib/gi18n.h>
31 #include "project-model.h"
32 #include "project-view.h"
34 #include <libanjuta/anjuta-debug.h>
35 #include <libanjuta/anjuta-utils.h>
36 #include <libanjuta/anjuta-pkg-config-chooser.h>
37 #include <libanjuta/anjuta-tree-combo.h>
38 #include <libanjuta/interfaces/ianjuta-project-chooser.h>
39 #include <libanjuta/interfaces/ianjuta-project-backend.h>
43 #define GLADE_FILE PACKAGE_DATA_DIR "/glade/pm_dialogs.ui"
45 #define ANJUTA_MANUAL "anjuta-manual"
46 #define ADD_SOURCE_HELP "project-manager-source-add"
47 #define ADD_TARGET_HELP "project-manager-target-add"
48 #define ADD_PACKAGE_HELP "project-manager-module-new"
49 #define ADD_MODULE_HELP "project-manager-module-add"
50 #define ADD_FOLDER_HELP "project-manager-folder-add"
54 *---------------------------------------------------------------------------*/
56 typedef struct _PropertiesTable
58 AnjutaPmProject
*project
;
59 AnjutaPluginHandle
*new_backend
;
67 GtkWidget
*scrolledwindow
;
69 AnjutaProjectNode
*node
;
70 GtkWidget
*help_button
;
75 typedef struct _PropertyEntry
78 AnjutaProjectPropertyInfo
*info
;
81 typedef struct _PropertyValue
83 AnjutaProjectProperty
*property
;
95 /* Sources list columns in new source dialog */
103 *---------------------------------------------------------------------------*/
106 load_interface (const gchar
*top_widget
)
108 GtkBuilder
*xml
= gtk_builder_new ();
109 GError
* error
= NULL
;
111 if (!gtk_builder_add_from_file (xml
, GLADE_FILE
, &error
))
113 g_warning ("Couldn't load builder file: %s", error
->message
);
114 g_error_free (error
);
122 error_dialog (GtkWindow
*parent
, const gchar
*summary
, const gchar
*msg
, ...)
129 tmp
= g_strdup_vprintf (msg
, ap
);
132 dialog
= gtk_message_dialog_new_with_markup (parent
,
133 GTK_DIALOG_DESTROY_WITH_PARENT
,
136 "<b>%s</b>\n\n%s", summary
, tmp
);
139 gtk_dialog_run (GTK_DIALOG (dialog
));
140 gtk_widget_destroy (dialog
);
144 /* Private nodes functions
145 *---------------------------------------------------------------------------*/
147 static PropertyEntry
*
148 pm_property_entry_new (GtkWidget
*entry
, AnjutaProjectPropertyInfo
*info
)
152 prop
= g_slice_new0(PropertyEntry
);
160 pm_property_entry_free (PropertyEntry
*prop
)
162 g_slice_free (PropertyEntry
, prop
);
166 parent_filter_func (GtkTreeModel
*model
, GtkTreeIter
*iter
, gpointer user_data
)
168 GbfTreeData
*data
= NULL
;
169 gboolean visible
= FALSE
;
170 AnjutaProjectNodeType type
= (AnjutaProjectNodeType
)GPOINTER_TO_INT (user_data
);
171 AnjutaProjectNode
*parent
;
172 AnjutaProjectNode
*node
;
177 case ANJUTA_PROJECT_GROUP
:
178 need
= ANJUTA_PROJECT_CAN_ADD_GROUP
;
180 case ANJUTA_PROJECT_TARGET
:
181 need
= ANJUTA_PROJECT_CAN_ADD_TARGET
;
183 case ANJUTA_PROJECT_SOURCE
:
184 /* Add node containing target too because target can contains module
185 * It would be probably better to check recursively if any children
186 * can accept a module and keep all parents then. */
187 need
= ANJUTA_PROJECT_CAN_ADD_SOURCE
| ANJUTA_PROJECT_CAN_ADD_TARGET
;
189 case ANJUTA_PROJECT_MODULE
:
190 /* Add node containing target too because target can contains module
191 * It would be probably better to check recursively if any children
192 * can accept a module and keep all parents then. */
193 need
= ANJUTA_PROJECT_CAN_ADD_MODULE
| ANJUTA_PROJECT_CAN_ADD_TARGET
;
195 case ANJUTA_PROJECT_PACKAGE
:
196 need
= ANJUTA_PROJECT_CAN_ADD_PACKAGE
;
203 gtk_tree_model_get (model
, iter
,
204 GBF_PROJECT_MODEL_COLUMN_DATA
, &data
, -1);
205 if (data
->shortcut
!= NULL
)
211 node
= data
== NULL
? NULL
: gbf_tree_data_get_node (data
);
214 if (anjuta_project_node_get_state (node
) & need
)
216 /* Current node can be used as parent */
219 else if (anjuta_project_node_get_node_type (node
) == type
)
221 /* Check if node can be used as sibling */
222 parent
= anjuta_project_node_parent (node
);
223 visible
= anjuta_project_node_get_state (parent
) & need
? TRUE
: FALSE
;
232 module_filter_func (GtkTreeModel
*model
, GtkTreeIter
*iter
, gpointer user_data
)
234 GbfTreeData
*data
= NULL
;
235 gboolean visible
= FALSE
;
236 AnjutaProjectNode
*node
;
238 gtk_tree_model_get (model
, iter
,
239 GBF_PROJECT_MODEL_COLUMN_DATA
, &data
, -1);
240 node
= data
== NULL
? NULL
: gbf_tree_data_get_node (data
);
243 AnjutaProjectNodeType type
= anjuta_project_node_get_node_type (node
);
245 visible
= (type
== ANJUTA_PROJECT_MODULE
) || (type
== ANJUTA_PROJECT_PACKAGE
);
252 setup_nodes_treeview (GbfProjectView
*view
,
253 GbfProjectView
*parent
,
255 GtkTreeModelFilterVisibleFunc func
,
257 GtkTreeIter
*selected
)
259 g_return_if_fail (view
!= NULL
&& GBF_IS_PROJECT_VIEW (view
));
260 g_return_if_fail (parent
!= NULL
);
262 gbf_project_view_set_parent_view (view
, parent
, root
);
263 gbf_project_view_set_visible_func (view
, func
, data
, NULL
);
264 gbf_project_view_set_cursor_to_iter (view
, selected
);
268 entry_changed_cb (GtkEditable
*editable
, gpointer user_data
)
270 GtkWidget
*button
= user_data
;
276 text
= gtk_editable_get_chars (editable
, 0, -1);
277 if (strlen (text
) > 0) {
278 gtk_widget_set_sensitive (button
, TRUE
);
279 gtk_widget_grab_default (button
);
281 gtk_widget_set_sensitive (button
, FALSE
);
287 on_value_edited (GtkCellRendererText
*cell
,
292 GtkTreeView
*view
= (GtkTreeView
*)user_data
;
294 GtkTreeModel
* model
;
296 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (view
));
297 if (gtk_tree_model_get_iter_from_string (model
, &iter
, path_string
))
299 gtk_list_store_set (GTK_LIST_STORE (model
), &iter
, VALUE_COLUMN
, text
, -1);
304 on_row_changed(GtkTreeModel
* model
, GtkTreePath
* path
, GtkTreeIter
* iter
, gpointer data
)
306 GtkWidget
* button
= GTK_WIDGET(data
);
307 if (gtk_list_store_iter_is_valid(GTK_LIST_STORE(model
), iter
))
308 gtk_widget_set_sensitive(button
, TRUE
);
310 gtk_widget_set_sensitive(button
, FALSE
);
314 browse_button_clicked_cb (GtkWidget
*widget
, gpointer user_data
)
316 GtkTreeView
*tree
= user_data
;
317 GtkTreeView
*treeview
;
318 GtkFileChooserDialog
* dialog
;
320 AnjutaProjectNode
*parent
;
323 g_return_if_fail (user_data
!= NULL
&& GTK_IS_TREE_VIEW (user_data
));
325 model
= gtk_tree_view_get_model(tree
);
326 /*if (gtk_tree_model_get_iter_first(model, &iter))
328 gtk_tree_model_get(model, &iter, COLUMN_URI, &file, -1);
329 uri = g_strdup(file);
332 uri = g_strdup("");*/
334 dialog
= GTK_FILE_CHOOSER_DIALOG(gtk_file_chooser_dialog_new (_("Select sources…"),
335 GTK_WINDOW (gtk_widget_get_toplevel (widget
)),
336 GTK_FILE_CHOOSER_ACTION_OPEN
,
337 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
338 GTK_STOCK_OPEN
, GTK_RESPONSE_ACCEPT
,
341 /* Get default directory */
342 treeview
= g_object_get_data (G_OBJECT (widget
), "treeview");
343 parent
= gbf_project_view_find_selected (GBF_PROJECT_VIEW (treeview
), ANJUTA_PROJECT_UNKNOWN
);
344 if (!(anjuta_project_node_get_state (parent
) & ANJUTA_PROJECT_CAN_ADD_SOURCE
))
346 parent
= anjuta_project_node_parent (parent
);
348 gtk_file_chooser_set_current_folder_file(GTK_FILE_CHOOSER(dialog
),
349 anjuta_project_node_get_file (parent
), NULL
);
351 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER(dialog
), TRUE
);
353 result
= gtk_dialog_run (GTK_DIALOG (dialog
));
356 case GTK_RESPONSE_ACCEPT
:
358 GSList
* uris
= gtk_file_chooser_get_uris (GTK_FILE_CHOOSER(dialog
));
359 GSList
* node_uri
= uris
;
361 gtk_list_store_clear (GTK_LIST_STORE (model
));
363 while (node_uri
!= NULL
)
366 gchar
* uri
= node_uri
->data
;
367 gchar
* file
= g_path_get_basename (uri
);
368 gtk_list_store_append (GTK_LIST_STORE (model
), &iter
);
369 gtk_list_store_set (GTK_LIST_STORE (model
), &iter
, COLUMN_FILE
,
370 file
, COLUMN_URI
, uri
, -1);
371 node_uri
= g_slist_next (node_uri
);
379 gtk_widget_destroy (GTK_WIDGET(dialog
));
382 /* Private properties functions
383 *---------------------------------------------------------------------------*/
386 add_entry (IAnjutaProject
*project
, AnjutaProjectNode
*node
, AnjutaProjectProperty
*prop
, GtkWidget
*table
, gint
*position
)
389 GtkWidget
*entry
= NULL
;
391 static GType column_type
[LIST_COLUMNS_NB
] = {
392 G_TYPE_STRING
, G_TYPE_STRING
, G_TYPE_BOOLEAN
, G_TYPE_POINTER
};
393 GtkCellRenderer
*renderer
;
394 GtkTreeViewColumn
*column
;
398 gchar
*tooltip
= NULL
;
399 gboolean editable
= TRUE
;
401 label
= gtk_label_new (_(prop
->info
->name
));
403 editable
= prop
->info
->flags
& ANJUTA_PROJECT_PROPERTY_READ_ONLY
? FALSE
: TRUE
;
405 if (prop
->info
->description
!= NULL
)
409 tooltip
= g_strconcat (_(prop
->info
->description
), _(" This property is not modifiable."), NULL
);
413 tooltip
= g_strdup (_(prop
->info
->description
));
419 gtk_widget_set_tooltip_markup (label
, tooltip
);
421 gtk_misc_set_alignment (GTK_MISC (label
), 0, -1);
422 gtk_widget_show (label
);
423 gtk_grid_attach (GTK_GRID (table
), label
, 0, *position
, 1, 1);
425 switch (prop
->info
->type
)
427 case ANJUTA_PROJECT_PROPERTY_STRING
:
428 case ANJUTA_PROJECT_PROPERTY_LIST
:
431 entry
= gtk_entry_new ();
432 gtk_entry_set_text (GTK_ENTRY (entry
), prop
->value
!= NULL
? prop
->value
: "");
436 entry
= gtk_label_new (prop
->value
!= NULL
? prop
->value
: "");
437 gtk_misc_set_alignment (GTK_MISC (entry
), 0, 0.5);
440 case ANJUTA_PROJECT_PROPERTY_BOOLEAN
:
441 entry
= gtk_check_button_new ();
442 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (entry
), (prop
->value
!= NULL
) && (*prop
->value
== '1'));
443 gtk_widget_set_sensitive (entry
, editable
);
445 case ANJUTA_PROJECT_PROPERTY_MAP
:
446 model
= GTK_TREE_MODEL (gtk_list_store_newv (LIST_COLUMNS_NB
, column_type
));
448 for (item
= anjuta_project_node_get_properties (node
); item
!= NULL
; item
= g_list_next (item
))
450 AnjutaProjectProperty
*cust_prop
= (AnjutaProjectProperty
*)item
->data
;
452 if (cust_prop
->info
== prop
->info
)
454 gtk_list_store_append (GTK_LIST_STORE (model
), &iter
);
455 gtk_list_store_set (GTK_LIST_STORE (model
), &iter
,
456 NAME_COLUMN
, cust_prop
->name
,
457 VALUE_COLUMN
, cust_prop
->value
,
458 EDITABLE_COLUMN
, TRUE
,
459 PROPERTY_COLUMN
, cust_prop
,
464 gtk_list_store_append (GTK_LIST_STORE (model
), &iter
);
465 gtk_list_store_set (GTK_LIST_STORE (model
), &iter
,
468 EDITABLE_COLUMN
, TRUE
,
469 PROPERTY_COLUMN
, NULL
,
472 entry
= gtk_frame_new (NULL
);
473 gtk_frame_set_shadow_type (GTK_FRAME (entry
), GTK_SHADOW_IN
);
475 view
= gtk_tree_view_new_with_model (model
);
476 gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (view
)),
477 GTK_SELECTION_SINGLE
);
478 gtk_tree_view_set_headers_clickable (GTK_TREE_VIEW (view
), TRUE
);
479 g_object_unref (G_OBJECT (model
));
481 renderer
= gtk_cell_renderer_text_new ();
482 column
= gtk_tree_view_column_new_with_attributes (_("Name"),
487 gtk_tree_view_column_set_sizing (column
, GTK_TREE_VIEW_COLUMN_AUTOSIZE
);
488 gtk_tree_view_append_column (GTK_TREE_VIEW (view
), column
);
489 renderer
= gtk_cell_renderer_text_new ();
490 column
= gtk_tree_view_column_new_with_attributes (_("Value"),
497 g_signal_connect(renderer
, "edited", (GCallback
) on_value_edited
, view
);
498 gtk_tree_view_column_set_sizing (column
, GTK_TREE_VIEW_COLUMN_AUTOSIZE
);
499 gtk_tree_view_append_column (GTK_TREE_VIEW (view
), column
);
501 gtk_container_add (GTK_CONTAINER (entry
), view
);
509 gtk_widget_set_tooltip_markup (entry
, tooltip
);
513 gtk_widget_set_hexpand (entry
, TRUE
);
514 gtk_grid_attach (GTK_GRID (table
), entry
, 1, *position
, 1, 1);
515 gtk_widget_show (entry
);
517 *position
= *position
+ 1;
523 add_label (const gchar
*display_name
, const gchar
*value
, GtkWidget
*table
, gint
*position
)
527 label
= gtk_label_new (display_name
);
528 gtk_misc_set_alignment (GTK_MISC (label
), 0, -1);
529 gtk_widget_show (label
);
530 gtk_grid_attach (GTK_GRID (table
), label
, 0, *position
, 1, 1);
532 label
= gtk_label_new (value
);
533 gtk_misc_set_alignment (GTK_MISC (label
), 0, -1);
534 gtk_widget_set_hexpand (label
, TRUE
);
535 gtk_widget_show (label
);
536 gtk_grid_attach (GTK_GRID (table
), label
, 1, *position
, 1, 1);
538 *position
= *position
+ 1;
542 add_button (const gchar
*display_name
, const gchar
*value
, GCallback on_clicked
, PropertiesTable
*properties
, GtkWidget
*table
, gint
*position
)
547 label
= gtk_label_new (display_name
);
548 gtk_misc_set_alignment (GTK_MISC (label
), 0, 0.5);
549 gtk_widget_show (label
);
550 gtk_grid_attach (GTK_GRID (table
), label
, 0, *position
, 1, 1);
552 button
= gtk_button_new_with_label (value
);
553 gtk_button_set_alignment (GTK_BUTTON (button
), 0, 0.5);
554 gtk_widget_show (button
);
555 gtk_grid_attach (GTK_GRID (table
), button
, 1, *position
, 1, 1);
556 if (on_clicked
!= NULL
)
558 g_signal_connect (G_OBJECT (button
), "clicked", on_clicked
, properties
);
561 *position
= *position
+ 1;
565 pm_project_resize_properties_dialog (PropertiesTable
*table
)
567 gint border_width
, maximum_width
, maximum_height
;
568 GtkRequisition dialog
, head
, viewport
, scrolledwindow_minimum
, vscrollbar_minimum
;
569 GtkWidget
*vscrollbar
= gtk_scrolled_window_get_vscrollbar (GTK_SCROLLED_WINDOW (table
->scrolledwindow
));
571 gtk_widget_get_preferred_size (table
->dialog
, NULL
, &dialog
);
572 gtk_widget_get_preferred_size (table
->head
, NULL
, &head
);
573 gtk_widget_get_preferred_size (table
->viewport
, NULL
, &viewport
);
574 gtk_widget_get_preferred_size (table
->scrolledwindow
, &scrolledwindow_minimum
, NULL
);
575 gtk_widget_get_preferred_size (vscrollbar
, &vscrollbar_minimum
, NULL
);
577 //auxiliary variables
578 border_width
= dialog
.width
- head
.width
;
579 maximum_width
= gdk_screen_width() * 3/4;
580 maximum_height
= gdk_screen_height() * 3/4;
582 gint height
= dialog
.height
- scrolledwindow_minimum
.height
+ viewport
.height
;
583 gint width
= (head
.width
> viewport
.width
) ? dialog
.width
: viewport
.width
+ vscrollbar_minimum
.width
+ border_width
;
585 if (height
> maximum_height
)
586 height
= maximum_height
;
588 if (width
> maximum_width
)
589 width
= maximum_width
;
591 gtk_window_resize (GTK_WINDOW (table
->dialog
), width
, height
);
595 on_change_project_backend (GtkButton
*button
,
598 PropertiesTable
*table
= (PropertiesTable
*)user_data
;
599 AnjutaPluginManager
*plugin_manager
;
600 GList
*handles
= NULL
;
602 AnjutaPluginHandle
*backend
;
604 /* Search for all valid project backend */
605 plugin_manager
= anjuta_shell_get_plugin_manager (ANJUTA_PLUGIN(table
->project
->plugin
)->shell
, NULL
);
606 handles
= anjuta_plugin_manager_query (plugin_manager
,
609 "IAnjutaProjectBackend",
611 for (node
= g_list_first (handles
); node
!= NULL
;) {
612 IAnjutaProjectBackend
*plugin
;
615 backend
= (AnjutaPluginHandle
*)node
->data
;
616 plugin
= (IAnjutaProjectBackend
*)anjuta_plugin_manager_get_plugin_by_handle (plugin_manager
, backend
);
618 next
= g_list_next (node
);
620 /* Probe the project directory to find if the backend can handle it */
621 if (ianjuta_project_backend_probe (plugin
, anjuta_project_node_get_file (table
->node
), NULL
) <= 0)
623 /* Remove invalid backend */
624 handles
= g_list_delete_link (handles
, node
);
632 /* Move the current backend at the beginning of the list */
633 backend
= anjuta_pm_project_get_backend (table
->project
);
634 for (node
= g_list_first (handles
); node
!= NULL
; node
= g_list_next (node
)) {
635 if (node
->data
== backend
)
637 handles
= g_list_remove_link (handles
, node
);
638 handles
= g_list_concat (node
, handles
);
643 /* Several backend are possible, ask the user to select one */
644 gchar
* message
= g_strdup_printf (_("Please select a project backend to use."));
646 backend
= anjuta_plugin_manager_select (plugin_manager
,
651 g_list_free (handles
);
655 gtk_button_set_label (button
, anjuta_plugin_handle_get_name (backend
));
656 table
->new_backend
= backend
;
662 update_properties (PropertiesTable
*table
)
670 AnjutaProjectNodeType type
;
671 AnjutaProjectNodeInfo
* node_info
;
679 /* Update dialog type */
680 switch (anjuta_project_node_get_node_type (table
->node
))
682 case ANJUTA_PROJECT_ROOT
:
683 title
= _("Project properties");
685 case ANJUTA_PROJECT_GROUP
:
686 if ((anjuta_project_node_get_full_type (table
->node
) & ANJUTA_PROJECT_ID_MASK
) == ANJUTA_PROJECT_ROOT_GROUP
)
688 title
= _("Project properties");
692 title
= _("Folder properties");
695 case ANJUTA_PROJECT_TARGET
:
696 title
= _("Target properties");
698 case ANJUTA_PROJECT_SOURCE
:
699 title
= _("Source properties");
701 case ANJUTA_PROJECT_MODULE
:
702 title
= _("Module properties");
704 case ANJUTA_PROJECT_PACKAGE
:
705 title
= _("Package properties");
708 title
= _("Unknown properties");
711 gtk_window_set_title (GTK_WINDOW (table
->dialog
), title
);
714 children
= gtk_container_get_children (GTK_CONTAINER (table
->head
));
715 g_list_foreach (children
, (GFunc
)gtk_widget_destroy
, NULL
);
716 g_list_free (children
);
717 children
= gtk_container_get_children (GTK_CONTAINER (table
->main
));
718 g_list_foreach (children
, (GFunc
)gtk_widget_destroy
, NULL
);
719 g_list_free (children
);
720 children
= gtk_container_get_children (GTK_CONTAINER (table
->extra
));
721 g_list_foreach (children
, (GFunc
)gtk_widget_destroy
, NULL
);
722 g_list_free (children
);
723 g_list_foreach (table
->properties
, (GFunc
)pm_property_entry_free
, NULL
);
724 g_list_free (table
->properties
);
725 table
->properties
= NULL
;
727 /* Display project backend if the root node is selected */
728 if ((anjuta_project_node_get_node_type (table
->node
) == ANJUTA_PROJECT_ROOT
) ||
729 ((anjuta_project_node_get_full_type (table
->node
) & ANJUTA_PROJECT_ID_MASK
) == ANJUTA_PROJECT_ROOT_GROUP
))
731 AnjutaPluginHandle
*backend
;
733 backend
= anjuta_pm_project_get_backend (table
->project
);
736 const gchar
*name
= anjuta_plugin_handle_get_name (backend
);
737 add_button (_("Backend:"), name
, G_CALLBACK (on_change_project_backend
), table
, table
->head
, &head_pos
);
741 /* Update node name */
742 file
= anjuta_project_node_get_file (table
->node
);
747 path
= g_file_get_path (file
);
748 add_label (_("Path:"), path
, table
->head
, &head_pos
);
753 add_label (_("Name:"), anjuta_project_node_get_name (table
->node
), table
->head
, &head_pos
);
756 /* Display node type only if several types are possible */
759 type
= anjuta_project_node_get_full_type (table
->node
);
760 for (item
= ianjuta_project_get_node_info (table
->project
->project
, NULL
); item
!= NULL
; item
= g_list_next (item
))
762 AnjutaProjectNodeInfo
* info
= (AnjutaProjectNodeInfo
*)item
->data
;
764 if (info
->type
== type
)
768 else if ((info
->type
& ANJUTA_PROJECT_TYPE_MASK
) == (type
& ANJUTA_PROJECT_TYPE_MASK
))
773 if (!single
&& (node_info
!= NULL
))
775 add_label (_("Type:"), anjuta_project_node_info_name (node_info
), table
->main
, &main_pos
);
778 /* Show help button if existing */
779 if ((node_info
!= NULL
) && (anjuta_project_node_info_property_help_id (node_info
) != NULL
))
781 table
->help_id
= anjuta_project_node_info_property_help_id (node_info
);
782 gtk_widget_show (table
->help_button
);
786 table
->help_id
= NULL
;
787 gtk_widget_hide (table
->help_button
);
790 /* Display other node properties */
793 for (item
= anjuta_project_node_get_properties_info (table
->node
); item
!= NULL
; item
= g_list_next (item
))
795 AnjutaProjectPropertyInfo
*info
= (AnjutaProjectPropertyInfo
*)item
->data
;
797 if (!(info
->flags
& ANJUTA_PROJECT_PROPERTY_HIDDEN
))
799 AnjutaProjectProperty
*prop
;
802 prop
= anjuta_project_node_get_property (table
->node
, info
->id
);
803 if (prop
!= prop
->info
->default_value
)
805 /* This property has been set, display it in the main part */
806 entry
= add_entry (table
->project
->project
, table
->node
, prop
, table
->main
, &main_pos
);
810 /* This property has not been set, hide it by default */
811 entry
= add_entry (table
->project
->project
, table
->node
, info
->default_value
, table
->extra
, &extra_pos
);
817 table
->properties
= g_list_prepend (table
->properties
,
818 pm_property_entry_new (entry
, info
));
822 table
->properties
= g_list_reverse (table
->properties
);
823 gtk_widget_show_all (table
->table
);
825 /* Hide expander if it is empty */
827 gtk_widget_show (table
->expand
);
829 gtk_widget_hide (table
->expand
);
831 pm_project_resize_properties_dialog (table
);
835 on_properties_dialog_response (GtkWidget
*dialog
,
837 PropertiesTable
*table
)
839 if (id
== GTK_RESPONSE_APPLY
)
843 /* Get all modified properties */
844 for (item
= g_list_first (table
->properties
); item
!= NULL
; item
= g_list_next (item
))
846 PropertyEntry
*entry
= (PropertyEntry
*)item
->data
;
847 AnjutaProjectProperty
*prop
;
854 /* Get property value in node */
855 prop
= anjuta_project_node_get_property (table
->node
, entry
->info
->id
);
857 switch (prop
->info
->type
)
859 case ANJUTA_PROJECT_PROPERTY_STRING
:
860 case ANJUTA_PROJECT_PROPERTY_LIST
:
861 if (GTK_IS_ENTRY (entry
->entry
))
863 text
= gtk_entry_get_text (GTK_ENTRY (entry
->entry
));
866 if ((prop
->value
!= NULL
) && (*prop
->value
!= '\0'))
869 ianjuta_project_set_property (table
->project
->project
, table
->node
, entry
->info
->id
, NULL
, NULL
, NULL
);
874 if (g_strcmp0 (prop
->value
, text
) != 0)
877 ianjuta_project_set_property (table
->project
->project
, table
->node
, entry
->info
->id
, NULL
, text
, NULL
);
882 case ANJUTA_PROJECT_PROPERTY_BOOLEAN
:
883 active
= prop
->value
== NULL
? FALSE
: (*prop
->value
== '1' ? TRUE
: FALSE
);
884 text
= gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (entry
->entry
)) ? "1" : "0";
886 if (active
!= (*text
== '1'))
889 ianjuta_project_set_property (table
->project
->project
, table
->node
, entry
->info
->id
, NULL
, text
, NULL
);
892 case ANJUTA_PROJECT_PROPERTY_MAP
:
893 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (gtk_bin_get_child (GTK_BIN (entry
->entry
))));
894 for (valid
= gtk_tree_model_get_iter_first (model
, &iter
); valid
; valid
= gtk_tree_model_iter_next (model
, &iter
))
896 AnjutaProjectProperty
*cust_prop
;
901 gtk_tree_model_get (model
, &iter
, VALUE_COLUMN
, &value
, PROPERTY_COLUMN
, &cust_prop
, -1);
902 if ((cust_prop
!= NULL
) && (g_strcmp0 (cust_prop
->value
, value
) != 0))
905 ianjuta_project_set_property (table
->project
->project
, table
->node
, entry
->info
->id
, cust_prop
->name
, value
, NULL
);
915 /* Update backend if needed */
916 if ((table
->new_backend
!= NULL
) && (table
->new_backend
!= anjuta_pm_project_get_backend (table
->project
)))
919 AnjutaStatus
*status
;
922 change_project_backend (ANJUTA_PLUGIN_PROJECT_MANAGER (table
->project
->plugin
), table
->new_backend
);
924 root
= g_object_ref (anjuta_project_node_get_file (table
->node
));
925 path
= g_file_get_path (root
);
927 status
= anjuta_shell_get_status (table
->project
->plugin
->shell
, NULL
);
928 anjuta_status_progress_add_ticks (status
, 1);
929 anjuta_status_push (status
, _("Reloading project: %s"), path
);
931 anjuta_status_busy_push (status
);
932 ANJUTA_PLUGIN_PROJECT_MANAGER (table
->project
->plugin
)->busy
= TRUE
;
933 anjuta_pm_project_unload (table
->project
, NULL
);
934 anjuta_pm_project_load_with_backend (table
->project
, root
, table
->new_backend
, NULL
);
935 g_object_unref (root
);
938 else if (id
== GTK_RESPONSE_HELP
)
940 anjuta_util_help_display (GTK_WIDGET (dialog
), ANJUTA_MANUAL
, table
->help_id
);
943 g_list_foreach (table
->properties
, (GFunc
)pm_property_entry_free
, NULL
);
945 gtk_widget_destroy (dialog
);
949 on_node_changed (AnjutaTreeComboBox
*view
,
952 PropertiesTable
*table
= (PropertiesTable
*)user_data
;
955 if (anjuta_tree_combo_box_get_active_iter (view
, &iter
))
960 model
= anjuta_tree_combo_box_get_model (view
);
961 gtk_tree_model_get (model
, &iter
, GBF_PROJECT_MODEL_COLUMN_DATA
, &data
, -1);
963 if (table
->data
->properties_dialog
!= NULL
)
965 g_object_remove_weak_pointer (G_OBJECT (table
->dialog
), (gpointer
*)&table
->data
->properties_dialog
);
966 table
->data
->properties_dialog
= NULL
;
968 if (data
->properties_dialog
!= NULL
)
970 g_object_unref (data
->properties_dialog
);
973 data
->properties_dialog
= table
->dialog
;
974 g_object_add_weak_pointer (G_OBJECT (table
->dialog
), (gpointer
*)&table
->data
->properties_dialog
);
976 table
->node
= gbf_tree_data_get_node (data
);
977 update_properties (table
);
982 on_expand_changed (GtkWidget
* widget
, gpointer user_data
)
984 PropertiesTable
*table
= (PropertiesTable
*)user_data
;
985 pm_project_resize_properties_dialog (table
);
989 pm_project_create_properties_dialog (AnjutaPmProject
*project
, GtkWindow
*parent
, GbfProjectView
*view
, GbfTreeData
*data
, GtkTreeIter
*selected
)
991 PropertiesTable
*table
;
993 GtkWidget
*node_combo
;
996 g_return_val_if_fail (data
!= NULL
, NULL
);
998 bxml
= anjuta_util_builder_new (GLADE_FILE
, NULL
);
999 if (!bxml
) return NULL
;
1001 table
= g_new0 (PropertiesTable
, 1);
1003 table
->node
= gbf_tree_data_get_node (data
);
1004 table
->project
= project
;
1005 table
->new_backend
= NULL
;
1006 anjuta_util_builder_get_objects (bxml
,
1007 "property_dialog", &table
->dialog
,
1008 "properties", &table
->table
,
1009 "nodes_combo", &node_combo
,
1010 "head_table", &table
->head
,
1011 "main_table", &table
->main
,
1012 "extra_table", &table
->extra
,
1013 "extra_expand", &table
->expand
,
1014 "viewport", &table
->viewport
,
1015 "scrolledwindow", &table
->scrolledwindow
,
1016 "property_help_button", &table
->help_button
,
1018 g_object_ref (table
->table
);
1019 g_object_unref (bxml
);
1021 /* Add combo node selection */
1022 ianjuta_project_chooser_set_project_model (IANJUTA_PROJECT_CHOOSER (node_combo
),
1023 IANJUTA_PROJECT_MANAGER (table
->project
->plugin
),
1024 ANJUTA_PROJECT_ROOT
,
1026 if (pm_convert_project_iter_to_model_iter (GTK_TREE_MODEL (anjuta_tree_combo_box_get_model (ANJUTA_TREE_COMBO_BOX (node_combo
))),
1029 anjuta_tree_combo_box_set_active_iter (ANJUTA_TREE_COMBO_BOX (node_combo
), &iter
);
1031 g_signal_connect (node_combo
, "changed",
1032 G_CALLBACK (on_node_changed
),
1035 g_signal_connect_after (table
->expand
, "activate",
1036 G_CALLBACK (on_expand_changed
),
1039 update_properties (table
);
1041 g_signal_connect (table
->dialog
, "response",
1042 G_CALLBACK (on_properties_dialog_response
),
1045 pm_project_resize_properties_dialog (table
);
1046 gtk_widget_show (table
->dialog
);
1048 return table
->dialog
;
1051 /* Properties dialog
1052 *---------------------------------------------------------------------------*/
1054 /* Display properties dialog. These dialogs are not modal, so a pointer on each
1055 * dialog is kept with in node data to be able to destroy them if the node is
1056 * removed. It is useful to put the dialog at the top if the same target is
1057 * selected while the corresponding dialog already exist instead of creating
1058 * two times the same dialog.
1059 * The project properties dialog is display if the node iterator is NULL. */
1062 anjuta_pm_project_show_properties_dialog (ProjectManagerPlugin
*plugin
, GtkTreeIter
*selected
)
1064 GtkWidget
**dialog_ptr
;
1067 if (selected
== NULL
)
1069 /* Display root properties by default */
1070 if (gbf_project_view_get_project_root (plugin
->view
, &iter
))
1080 gtk_tree_model_get (GTK_TREE_MODEL (gbf_project_view_get_model (plugin
->view
)), selected
, GBF_PROJECT_MODEL_COLUMN_DATA
, &data
, -1);
1081 dialog_ptr
= &data
->properties_dialog
;
1083 if (*dialog_ptr
!= NULL
)
1085 /* Show already existing dialog */
1086 gtk_window_present (GTK_WINDOW (*dialog_ptr
));
1090 *dialog_ptr
= pm_project_create_properties_dialog (
1092 GTK_WINDOW (plugin
->project
->plugin
->shell
),
1096 if (*dialog_ptr
!= NULL
)
1098 g_object_add_weak_pointer (G_OBJECT (*dialog_ptr
), (gpointer
*)dialog_ptr
);
1103 return selected
!= NULL
;
1109 *---------------------------------------------------------------------------*/
1112 anjuta_pm_project_new_group (ProjectManagerPlugin
*plugin
, GtkWindow
*parent
, GtkTreeIter
*selected
, const gchar
*default_name
)
1115 GtkWidget
*dialog
, *group_name_entry
, *ok_button
;
1116 GtkWidget
*groups_view
;
1118 gboolean finished
= FALSE
;
1119 AnjutaProjectNode
*new_group
= NULL
;
1121 g_return_val_if_fail (plugin
->project
!= NULL
, NULL
);
1123 gui
= load_interface ("new_group_dialog");
1124 g_return_val_if_fail (gui
!= NULL
, NULL
);
1126 /* get all needed widgets */
1127 dialog
= GTK_WIDGET (gtk_builder_get_object (gui
, "new_group_dialog"));
1128 groups_view
= GTK_WIDGET (gtk_builder_get_object (gui
, "groups_view"));
1129 group_name_entry
= GTK_WIDGET (gtk_builder_get_object (gui
, "group_name_entry"));
1130 ok_button
= GTK_WIDGET (gtk_builder_get_object (gui
, "ok_group_button"));
1134 gtk_entry_set_text (GTK_ENTRY (group_name_entry
),
1136 g_signal_connect (group_name_entry
, "changed",
1137 (GCallback
) entry_changed_cb
, ok_button
);
1139 gtk_widget_set_sensitive (ok_button
, TRUE
);
1141 gtk_widget_set_sensitive (ok_button
, FALSE
);
1143 setup_nodes_treeview (GBF_PROJECT_VIEW (groups_view
),
1147 GINT_TO_POINTER (ANJUTA_PROJECT_GROUP
),
1149 gtk_widget_show (groups_view
);
1153 gtk_window_set_transient_for (GTK_WINDOW (dialog
), parent
);
1156 /* execute dialog */
1159 response
= gtk_dialog_run (GTK_DIALOG (dialog
));
1162 case GTK_RESPONSE_OK
:
1165 AnjutaProjectNode
*group
;
1168 name
= gtk_editable_get_chars (
1169 GTK_EDITABLE (group_name_entry
), 0, -1);
1171 group
= gbf_project_view_find_selected_state (GTK_TREE_VIEW (groups_view
),
1172 ANJUTA_PROJECT_CAN_ADD_GROUP
);
1175 new_group
= anjuta_pm_project_add_group (plugin
->project
, group
, NULL
, name
, &err
);
1178 error_dialog (parent
, _("Cannot add group"), "%s",
1189 error_dialog (parent
, _("Cannot add group"),
1190 "%s", _("No parent group selected"));
1195 case GTK_RESPONSE_HELP
:
1196 anjuta_util_help_display (GTK_WIDGET (dialog
), ANJUTA_MANUAL
, ADD_FOLDER_HELP
);
1205 gtk_widget_destroy (dialog
);
1206 g_object_unref (gui
);
1212 *---------------------------------------------------------------------------*/
1215 anjuta_pm_project_new_source (ProjectManagerPlugin
*plugin
,
1217 GtkTreeIter
*default_parent
,
1218 const gchar
*default_uri
)
1226 uri
= g_strdup (default_uri
);
1227 uris
= g_list_append (NULL
, uri
);
1230 anjuta_pm_project_new_multiple_source (plugin
, parent
,
1231 default_parent
, uris
);
1235 if (new_sources
&& g_list_length (new_sources
))
1237 AnjutaProjectNode
*new_source
= new_sources
->data
;
1238 g_list_free (new_sources
);
1246 on_target_changed (GtkWidget
*chooser
, GtkWidget
*button
)
1250 file
= ianjuta_project_chooser_get_selected (IANJUTA_PROJECT_CHOOSER (chooser
), NULL
);
1251 gtk_widget_set_sensitive (button
, file
!= NULL
);
1255 anjuta_pm_add_source_dialog (ProjectManagerPlugin
*plugin
,
1256 GtkWindow
*top_window
,
1257 GtkTreeIter
*default_target
,
1258 GFile
*default_source
)
1262 GtkWidget
*ok_button
;
1263 GtkWidget
*target_chooser
;
1264 GtkWidget
*source_chooser
;
1266 gboolean finished
= FALSE
;
1267 GList
*sources
= NULL
;
1269 g_return_val_if_fail (plugin
->project
!= NULL
, NULL
);
1271 gui
= load_interface ("add_source_dialog");
1272 g_return_val_if_fail (gui
!= NULL
, NULL
);
1274 /* get all needed widgets */
1275 dialog
= GTK_WIDGET (gtk_builder_get_object (gui
, "add_source_dialog"));
1276 target_chooser
= GTK_WIDGET (gtk_builder_get_object (gui
, "target_chooser"));
1277 source_chooser
= GTK_WIDGET (gtk_builder_get_object (gui
, "source_chooser"));
1278 ok_button
= GTK_WIDGET (gtk_builder_get_object (gui
, "ok_add_source_button"));
1280 /* Fill target selection */
1281 ianjuta_project_chooser_set_project_model (IANJUTA_PROJECT_CHOOSER (target_chooser
),
1282 IANJUTA_PROJECT_MANAGER (plugin
),
1283 ANJUTA_PROJECT_SOURCE
,
1285 if (default_target
!= NULL
)
1288 if (pm_convert_project_iter_to_model_iter (GTK_TREE_MODEL (anjuta_tree_combo_box_get_model (ANJUTA_TREE_COMBO_BOX (target_chooser
))),
1289 &iter
, default_target
))
1291 anjuta_tree_combo_box_set_active_iter (ANJUTA_TREE_COMBO_BOX (target_chooser
), &iter
);
1294 g_signal_connect (target_chooser
, "changed",
1295 G_CALLBACK (on_target_changed
),
1297 on_target_changed (target_chooser
, ok_button
);
1299 /* Selected default file */
1300 if (default_source
!= NULL
) gtk_file_chooser_set_file (GTK_FILE_CHOOSER (source_chooser
), default_source
, NULL
);
1303 gtk_window_set_transient_for (GTK_WINDOW (dialog
), top_window
);
1306 /* execute dialog */
1308 response
= gtk_dialog_run (GTK_DIALOG (dialog
));
1312 case GTK_RESPONSE_OK
:
1315 AnjutaProjectNode
*target
;
1318 target_file
= ianjuta_project_chooser_get_selected (IANJUTA_PROJECT_CHOOSER (target_chooser
), NULL
);
1319 target
= gbf_project_view_get_node_from_file (plugin
->view
, ANJUTA_PROJECT_UNKNOWN
, target_file
);
1320 files
= gtk_file_chooser_get_files (GTK_FILE_CHOOSER (source_chooser
));
1321 if ((target
!= NULL
) && (files
!= NULL
))
1323 GString
*err_mesg
= g_string_new (NULL
);
1326 for (item
= files
; item
!= NULL
; item
= g_slist_next (item
))
1328 gchar
*path
= g_file_get_path ((GFile
*)item
->data
);
1330 AnjutaProjectNode
*node
;
1332 node
= anjuta_pm_project_add_source (plugin
->project
,
1337 sources
= g_list_prepend (sources
, node
);
1339 gchar
*str
= g_strdup_printf ("%s: %s\n",
1342 g_string_append (err_mesg
, str
);
1348 if (err_mesg
->str
&& strlen (err_mesg
->str
) > 0)
1350 error_dialog (top_window
, _("Cannot add source files"),
1351 "%s", err_mesg
->str
);
1356 g_string_free (err_mesg
, TRUE
);
1357 g_slist_foreach (files
, (GFunc
)g_object_unref
, NULL
);
1358 g_slist_free (files
);
1362 error_dialog (top_window
, _("Cannot add source files"),
1363 "%s", _("The selected node cannot contain source files."));
1367 case GTK_RESPONSE_HELP
:
1368 anjuta_util_help_display (GTK_WIDGET (dialog
), ANJUTA_MANUAL
, ADD_SOURCE_HELP
);
1377 gtk_widget_destroy (dialog
);
1378 g_object_unref (gui
);
1380 sources
= g_list_reverse (sources
);
1386 anjuta_pm_project_new_multiple_source (ProjectManagerPlugin
*plugin
,
1387 GtkWindow
*top_window
,
1388 GtkTreeIter
*default_parent
,
1392 GtkWidget
*dialog
, *source_file_tree
;
1393 GtkWidget
*ok_button
, *browse_button
;
1394 GtkWidget
*targets_view
;
1396 gboolean finished
= FALSE
;
1398 GtkCellRenderer
* renderer
;
1399 GtkTreeViewColumn
* column_filename
;
1400 GList
* new_sources
= NULL
;
1404 g_return_val_if_fail (plugin
->project
!= NULL
, NULL
);
1406 gui
= load_interface ("new_source_dialog");
1407 g_return_val_if_fail (gui
!= NULL
, NULL
);
1409 /* get all needed widgets */
1410 dialog
= GTK_WIDGET (gtk_builder_get_object (gui
, "new_source_dialog"));
1411 targets_view
= GTK_WIDGET (gtk_builder_get_object (gui
, "targets_view"));
1412 source_file_tree
= GTK_WIDGET (gtk_builder_get_object (gui
, "source_file_tree"));
1413 browse_button
= GTK_WIDGET (gtk_builder_get_object (gui
, "browse_button"));
1414 ok_button
= GTK_WIDGET (gtk_builder_get_object (gui
, "ok_source_button"));
1416 /* Prepare file tree */
1417 list
= gtk_list_store_new (N_COLUMNS
, G_TYPE_STRING
, G_TYPE_STRING
);
1418 gtk_tree_view_set_model (GTK_TREE_VIEW (source_file_tree
),
1419 GTK_TREE_MODEL (list
));
1420 renderer
= gtk_cell_renderer_text_new ();
1421 column_filename
= gtk_tree_view_column_new_with_attributes ("Files",
1426 gtk_tree_view_column_set_sizing (column_filename
,
1427 GTK_TREE_VIEW_COLUMN_FIXED
);
1428 gtk_tree_view_append_column (GTK_TREE_VIEW (source_file_tree
),
1432 uri_node
= uris_to_add
;
1436 gchar
* filename
= g_path_get_basename (uri_node
->data
);
1438 filename
= g_strdup (uri_node
->data
);
1439 gtk_list_store_append (list
, &iter
);
1440 gtk_list_store_set (list
, &iter
, COLUMN_FILE
, filename
,
1441 COLUMN_URI
, g_strdup(uri_node
->data
), -1);
1443 uri_node
= g_list_next (uri_node
);
1445 if (!g_list_length (uris_to_add
))
1446 gtk_widget_set_sensitive (ok_button
, FALSE
);
1448 gtk_widget_set_sensitive (ok_button
, TRUE
);
1450 g_signal_connect (G_OBJECT(list
), "row_changed",
1451 G_CALLBACK(on_row_changed
), ok_button
);
1453 g_signal_connect (browse_button
, "clicked",
1454 G_CALLBACK (browse_button_clicked_cb
), source_file_tree
);
1456 g_object_set_data_full (G_OBJECT (browse_button
), "treeview", targets_view
, NULL
);
1457 /*project_root = g_file_get_uri (anjuta_project_node_get_file (anjuta_pm_project_get_root (project)));
1458 g_object_set_data_full (G_OBJECT (browse_button), "root", project_root, g_free);*/
1460 root
= gbf_project_model_get_project_root (gbf_project_view_get_model (plugin
->view
));
1461 setup_nodes_treeview (GBF_PROJECT_VIEW (targets_view
),
1465 GINT_TO_POINTER (ANJUTA_PROJECT_SOURCE
),
1467 gtk_tree_path_free (root
);
1468 gtk_widget_show (targets_view
);
1471 gtk_window_set_transient_for (GTK_WINDOW (dialog
), top_window
);
1475 gtk_widget_grab_focus (source_file_tree
);
1477 gtk_widget_grab_focus (targets_view
);
1479 /* execute dialog */
1481 response
= gtk_dialog_run (GTK_DIALOG (dialog
));
1485 case GTK_RESPONSE_OK
:
1487 AnjutaProjectNode
*parent
= NULL
;
1488 AnjutaProjectNode
*sibling
= NULL
;
1490 parent
= gbf_project_view_find_selected (GBF_PROJECT_VIEW (targets_view
),
1491 ANJUTA_PROJECT_UNKNOWN
);
1493 /* Check that selected node can be used as a parent or a sibling */
1496 if (!(anjuta_project_node_get_state (parent
) & ANJUTA_PROJECT_CAN_ADD_SOURCE
))
1499 parent
= anjuta_project_node_parent (parent
);
1501 if (!(anjuta_project_node_get_state (parent
) & ANJUTA_PROJECT_CAN_ADD_SOURCE
))
1510 GString
*err_mesg
= g_string_new (NULL
);
1512 if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (list
),
1518 AnjutaProjectNode
* new_source
;
1521 gtk_tree_model_get (GTK_TREE_MODEL(list
), &iter
,
1522 COLUMN_URI
, &uri
, -1);
1524 new_source
= anjuta_pm_project_add_source (plugin
->project
,
1530 gchar
*str
= g_strdup_printf ("%s: %s\n",
1533 g_string_append (err_mesg
, str
);
1538 new_sources
= g_list_append (new_sources
,
1542 } while (gtk_tree_model_iter_next (GTK_TREE_MODEL(list
),
1545 if (err_mesg
->str
&& strlen (err_mesg
->str
) > 0)
1547 error_dialog (top_window
, _("Cannot add source files"),
1548 "%s", err_mesg
->str
);
1553 g_string_free (err_mesg
, TRUE
);
1557 error_dialog (top_window
, _("Cannot add source files"),
1558 "%s", _("The selected node cannot contain source files."));
1562 case GTK_RESPONSE_HELP
:
1563 anjuta_util_help_display (GTK_WIDGET (dialog
), ANJUTA_MANUAL
, ADD_SOURCE_HELP
);
1566 gtk_list_store_clear (GTK_LIST_STORE (list
));
1573 gtk_widget_destroy (dialog
);
1574 g_object_unref (gui
);
1580 *---------------------------------------------------------------------------*/
1583 TARGET_TYPE_TYPE
= 0,
1586 TARGET_TYPE_N_COLUMNS
1589 /* create a tree model with the target types */
1590 static GtkListStore
*
1591 build_types_store (AnjutaPmProject
*project
, AnjutaProjectNodeType store_type
)
1593 GtkListStore
*store
;
1598 types
= anjuta_pm_project_get_node_info (project
);
1599 store
= gtk_list_store_new (TARGET_TYPE_N_COLUMNS
,
1604 for (node
= types
; node
!= NULL
; node
= g_list_next (node
)) {
1607 AnjutaProjectNodeType type
;
1609 type
= anjuta_project_node_info_type ((AnjutaProjectNodeInfo
*)node
->data
);
1610 if (((store_type
== 0) || ((type
& ANJUTA_PROJECT_TYPE_MASK
) == store_type
)) && !(type
& ANJUTA_PROJECT_READ_ONLY
))
1612 name
= anjuta_project_node_info_name ((AnjutaProjectNodeInfo
*)node
->data
);
1613 pixbuf
= gtk_icon_theme_load_icon (gtk_icon_theme_get_default(),
1619 gtk_list_store_append (store
, &iter
);
1620 gtk_list_store_set (store
, &iter
,
1621 TARGET_TYPE_TYPE
, type
,
1622 TARGET_TYPE_NAME
, name
,
1623 TARGET_TYPE_PIXBUF
, pixbuf
,
1627 g_object_unref (pixbuf
);
1635 anjuta_pm_project_new_target (ProjectManagerPlugin
*plugin
,
1637 GtkTreeIter
*default_group
,
1638 const gchar
*default_target_name_to_add
)
1641 GtkWidget
*dialog
, *target_name_entry
, *ok_button
;
1642 GtkWidget
*target_type_combo
, *groups_view
;
1643 GtkListStore
*types_store
;
1644 GtkCellRenderer
*renderer
;
1646 gboolean finished
= FALSE
;
1647 AnjutaProjectNode
*new_target
= NULL
;
1649 g_return_val_if_fail (plugin
->project
!= NULL
, NULL
);
1651 gui
= load_interface ("new_target_dialog");
1652 g_return_val_if_fail (gui
!= NULL
, NULL
);
1654 /* get all needed widgets */
1655 dialog
= GTK_WIDGET (gtk_builder_get_object (gui
, "new_target_dialog"));
1656 groups_view
= GTK_WIDGET (gtk_builder_get_object (gui
, "target_groups_view"));
1657 target_name_entry
= GTK_WIDGET (gtk_builder_get_object (gui
, "target_name_entry"));
1658 target_type_combo
= GTK_WIDGET (gtk_builder_get_object (gui
, "target_type_combo"));
1659 ok_button
= GTK_WIDGET (gtk_builder_get_object (gui
, "ok_target_button"));
1662 if (default_target_name_to_add
)
1663 gtk_entry_set_text (GTK_ENTRY (target_name_entry
),
1664 default_target_name_to_add
);
1665 g_signal_connect (target_name_entry
, "changed",
1666 (GCallback
) entry_changed_cb
, ok_button
);
1667 if (default_target_name_to_add
)
1668 gtk_widget_set_sensitive (ok_button
, TRUE
);
1670 gtk_widget_set_sensitive (ok_button
, FALSE
);
1672 setup_nodes_treeview (GBF_PROJECT_VIEW (groups_view
),
1676 GINT_TO_POINTER (ANJUTA_PROJECT_TARGET
),
1678 gtk_widget_show (groups_view
);
1680 /* setup target types combo box */
1681 types_store
= build_types_store (plugin
->project
, ANJUTA_PROJECT_TARGET
);
1682 gtk_combo_box_set_model (GTK_COMBO_BOX (target_type_combo
),
1683 GTK_TREE_MODEL (types_store
));
1685 /* create cell renderers */
1686 renderer
= gtk_cell_renderer_pixbuf_new ();
1687 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (target_type_combo
),
1689 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (target_type_combo
),
1691 "pixbuf", TARGET_TYPE_PIXBUF
,
1694 renderer
= gtk_cell_renderer_text_new ();
1695 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (target_type_combo
),
1697 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (target_type_combo
),
1699 "text", TARGET_TYPE_NAME
,
1701 gtk_widget_show (target_type_combo
);
1704 gtk_combo_box_set_active (GTK_COMBO_BOX (target_type_combo
), 0);
1708 gtk_window_set_transient_for (GTK_WINDOW (dialog
), parent
);
1711 /* execute dialog */
1714 response
= gtk_dialog_run (GTK_DIALOG (dialog
));
1718 case GTK_RESPONSE_OK
:
1721 AnjutaProjectNode
*group
;
1724 AnjutaProjectNodeType type
;
1726 name
= gtk_editable_get_chars (
1727 GTK_EDITABLE (target_name_entry
), 0, -1);
1728 group
= gbf_project_view_find_selected (GBF_PROJECT_VIEW (groups_view
),
1729 ANJUTA_PROJECT_GROUP
);
1731 /* retrieve target type */
1732 if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (target_type_combo
), &iter
))
1734 gtk_tree_model_get (GTK_TREE_MODEL (types_store
), &iter
,
1735 TARGET_TYPE_TYPE
, &type
,
1741 new_target
= anjuta_pm_project_add_target (plugin
->project
, group
, NULL
, name
, type
, &err
);
1744 error_dialog (parent
, _("Cannot add target"), "%s",
1755 error_dialog (parent
, _("Cannot add target"), "%s",
1756 _("No group selected"));
1763 case GTK_RESPONSE_HELP
:
1764 anjuta_util_help_display (GTK_WIDGET (dialog
), ANJUTA_MANUAL
, ADD_TARGET_HELP
);
1773 g_object_unref (types_store
);
1774 gtk_widget_destroy (dialog
);
1775 g_object_unref (gui
);
1782 *---------------------------------------------------------------------------*/
1785 on_cursor_changed(GtkTreeView
* view
, gpointer data
)
1787 GtkWidget
* button
= GTK_WIDGET(data
);
1788 GtkTreeSelection
*selection
= gtk_tree_view_get_selection(view
);
1790 if (gtk_tree_selection_count_selected_rows (selection
) > 0)
1791 gtk_widget_set_sensitive(button
, TRUE
);
1793 gtk_widget_set_sensitive(button
, FALSE
);
1797 on_new_library(GtkButton
*button
, gpointer user_data
)
1799 ProjectManagerPlugin
*plugin
= ANJUTA_PLUGIN_PROJECT_MANAGER (user_data
);
1802 packages
= anjuta_pm_project_new_package (plugin
,
1803 get_plugin_parent_window (plugin
),
1806 g_list_free (packages
);
1810 anjuta_pm_project_new_module (ProjectManagerPlugin
*plugin
,
1812 GtkTreeIter
*default_target
,
1813 const gchar
*default_module
)
1817 GtkWidget
*ok_button
, *new_button
;
1818 GtkWidget
*target_chooser
;
1819 GtkWidget
*modules_view
;
1822 gboolean finished
= FALSE
;
1823 GList
* new_modules
= NULL
;
1824 GtkTreeSelection
*module_selection
;
1826 g_return_val_if_fail (plugin
->project
!= NULL
, NULL
);
1828 gui
= load_interface ("add_module_dialog");
1829 g_return_val_if_fail (gui
!= NULL
, NULL
);
1831 /* get all needed widgets */
1832 dialog
= GTK_WIDGET (gtk_builder_get_object (gui
, "add_module_dialog"));
1833 target_chooser
= GTK_WIDGET (gtk_builder_get_object (gui
, "module_targets_chooser"));
1834 modules_view
= GTK_WIDGET (gtk_builder_get_object (gui
, "modules_view"));
1835 new_button
= GTK_WIDGET (gtk_builder_get_object (gui
, "new_package_button"));
1836 ok_button
= GTK_WIDGET (gtk_builder_get_object (gui
, "ok_module_button"));
1838 /* Fill target selection */
1839 ianjuta_project_chooser_set_project_model (IANJUTA_PROJECT_CHOOSER (target_chooser
),
1840 IANJUTA_PROJECT_MANAGER (plugin
),
1841 ANJUTA_PROJECT_MODULE
,
1843 gtk_widget_show (target_chooser
);
1844 root
= gbf_project_model_get_project_root (gbf_project_view_get_model (plugin
->view
));
1845 setup_nodes_treeview (GBF_PROJECT_VIEW (modules_view
),
1851 gtk_tree_path_free (root
);
1852 gtk_widget_show (modules_view
);
1853 module_selection
= gtk_tree_view_get_selection (GTK_TREE_VIEW (modules_view
));
1854 gtk_tree_selection_set_mode (module_selection
, GTK_SELECTION_MULTIPLE
);
1856 if (gbf_project_view_find_selected (GBF_PROJECT_VIEW (modules_view
), ANJUTA_PROJECT_MODULE
))
1858 gtk_widget_set_sensitive (ok_button
, TRUE
);
1862 gtk_widget_set_sensitive (ok_button
, FALSE
);
1864 g_signal_connect (G_OBJECT(modules_view
), "cursor-changed",
1865 G_CALLBACK(on_cursor_changed
), ok_button
);
1866 g_signal_connect (G_OBJECT(new_button
), "clicked",
1867 G_CALLBACK(on_new_library
), plugin
);
1872 gtk_window_set_transient_for (GTK_WINDOW (dialog
), parent
);
1875 gtk_widget_grab_focus (modules_view
);
1877 /* execute dialog */
1880 response
= gtk_dialog_run (GTK_DIALOG (dialog
));
1883 case GTK_RESPONSE_OK
:
1886 AnjutaProjectNode
*target
;
1888 target_file
= ianjuta_project_chooser_get_selected (IANJUTA_PROJECT_CHOOSER (target_chooser
), NULL
);
1889 target
= gbf_project_view_get_node_from_file (plugin
->view
, ANJUTA_PROJECT_UNKNOWN
, target_file
);
1892 GString
*err_mesg
= g_string_new (NULL
);
1896 list
= gbf_project_view_get_all_selected (GBF_PROJECT_VIEW (modules_view
));
1897 for (node
= g_list_first (list
); node
!= NULL
; node
= g_list_next (node
))
1899 GError
*error
= NULL
;
1900 AnjutaProjectNode
* new_module
;
1903 new_module
= gbf_tree_data_get_node (node
->data
);
1904 name
= anjuta_project_node_get_name (new_module
);
1906 new_module
= ianjuta_project_add_node_after (plugin
->project
->project
, target
, NULL
, ANJUTA_PROJECT_MODULE
, NULL
, name
, &error
);
1908 gchar
*str
= g_strdup_printf ("%s: %s\n",
1911 g_string_append (err_mesg
, str
);
1912 g_error_free (error
);
1916 new_modules
= g_list_append (new_modules
, new_module
);
1920 if (err_mesg
->str
&& strlen (err_mesg
->str
) > 0)
1922 error_dialog (parent
, _("Cannot add modules"),
1923 "%s", err_mesg
->str
);
1929 g_string_free (err_mesg
, TRUE
);
1933 error_dialog (parent
, _("Cannot add modules"),
1934 "%s", _("No target has been selected"));
1939 case GTK_RESPONSE_HELP
:
1940 anjuta_util_help_display (GTK_WIDGET (dialog
), ANJUTA_MANUAL
, ADD_MODULE_HELP
);
1949 gtk_widget_destroy (dialog
);
1950 g_object_unref (gui
);
1956 *---------------------------------------------------------------------------*/
1958 static void on_changed_disconnect (GtkEditable
* entry
, gpointer data
);
1961 on_cursor_changed_set_entry(GtkTreeView
* view
, gpointer data
)
1963 GtkWidget
* entry
= GTK_WIDGET(data
);
1964 AnjutaPkgConfigChooser
* chooser
= ANJUTA_PKG_CONFIG_CHOOSER (view
);
1965 GList
* packages
= anjuta_pkg_config_chooser_get_active_packages (chooser
);
1969 gchar
* name
= packages
->data
;
1971 /* Remove numeric suffix */
1972 ptr
= name
+ strlen(name
) - 1;
1973 while (g_ascii_isdigit (*ptr
))
1975 while (g_ascii_isdigit (*ptr
)) ptr
--;
1976 if ((*ptr
!= '_') && (*ptr
!= '-') && (*ptr
!= '.')) break;
1981 /* Convert to upper case and remove invalid characters */
1982 for (ptr
= name
; *ptr
!= '\0'; ptr
++)
1984 if (g_ascii_isalnum (*ptr
))
1986 *ptr
= g_ascii_toupper (*ptr
);
1994 g_signal_handlers_block_by_func (G_OBJECT (entry
), on_changed_disconnect
, view
);
1995 gtk_entry_set_text (GTK_ENTRY (entry
), name
);
1996 g_signal_handlers_unblock_by_func (G_OBJECT (entry
), on_changed_disconnect
, view
);
1997 anjuta_util_glist_strings_free (packages
);
2002 on_changed_disconnect (GtkEditable
* entry
, gpointer data
)
2004 g_signal_handlers_block_by_func (G_OBJECT (data
), on_cursor_changed_set_entry
, entry
);
2008 on_pkg_chooser_selection_changed (AnjutaPkgConfigChooser
* chooser
,
2012 GtkWidget
* button
= GTK_WIDGET(data
);
2013 GList
* packages
= anjuta_pkg_config_chooser_get_active_packages (chooser
);
2015 if (packages
!= NULL
)
2016 gtk_widget_set_sensitive(button
, TRUE
);
2018 gtk_widget_set_sensitive(button
, FALSE
);
2020 anjuta_util_glist_strings_free (packages
);
2024 anjuta_pm_project_new_package (ProjectManagerPlugin
*plugin
,
2026 GtkTreeIter
*default_module
,
2027 GList
*packages_to_add
)
2031 GtkWidget
*ok_button
;
2032 GtkWidget
*module_entry
;
2033 GtkWidget
*packages_view
;
2034 GList
*packages
= NULL
;
2036 gboolean finished
= FALSE
;
2037 GtkListStore
*store
;
2038 AnjutaProjectNode
*root
;
2039 AnjutaProjectNode
*node
;
2040 AnjutaProjectNode
*module
= NULL
;
2041 gint default_pos
= -1;
2044 g_return_val_if_fail (plugin
->project
!= NULL
, NULL
);
2046 gui
= load_interface ("add_package_dialog");
2047 g_return_val_if_fail (gui
!= NULL
, NULL
);
2049 /* get all needed widgets */
2050 dialog
= GTK_WIDGET (gtk_builder_get_object (gui
, "add_package_dialog"));
2051 module_entry
= GTK_WIDGET (gtk_builder_get_object (gui
, "module_entry"));
2052 packages_view
= GTK_WIDGET (gtk_builder_get_object (gui
, "packages_view"));
2053 ok_button
= GTK_WIDGET (gtk_builder_get_object (gui
, "ok_package_button"));
2055 /* Get default parent */
2056 if (default_module
!= NULL
)
2059 GbfProjectModel
*model
;
2061 model
= gbf_project_view_get_model(plugin
->view
);
2062 gtk_tree_model_get (GTK_TREE_MODEL (model
), default_module
, GBF_PROJECT_MODEL_COLUMN_DATA
, &data
, -1);
2065 module
= gbf_tree_data_get_node (data
);
2069 /* Fill combo box with modules */
2070 store
= gtk_list_store_new(1, G_TYPE_STRING
);
2071 gtk_combo_box_set_entry_text_column (GTK_COMBO_BOX (module_entry
), 0);
2073 root
= ianjuta_project_get_root (plugin
->project
->project
, NULL
);
2075 for (node
= anjuta_project_node_first_child (root
); node
!= NULL
; node
= anjuta_project_node_next_sibling (node
))
2077 if (anjuta_project_node_get_node_type (node
) == ANJUTA_PROJECT_MODULE
)
2079 GtkTreeIter list_iter
;
2082 name
= anjuta_project_node_get_name (node
);
2083 gtk_list_store_append (store
, &list_iter
);
2084 gtk_list_store_set (store
, &list_iter
, 0, name
, -1);
2093 gtk_combo_box_set_model (GTK_COMBO_BOX(module_entry
), GTK_TREE_MODEL(store
));
2094 gtk_combo_box_set_entry_text_column (GTK_COMBO_BOX (module_entry
), 0);
2095 g_object_unref (store
);
2096 if (default_pos
>= 0)
2098 gtk_combo_box_set_active (GTK_COMBO_BOX (module_entry
), default_pos
);
2102 /* Create automatically a module name from the package name when missing */
2103 GtkWidget
*entry
= gtk_bin_get_child (GTK_BIN (module_entry
));
2105 g_signal_connect (G_OBJECT(packages_view
), "cursor-changed",
2106 G_CALLBACK(on_cursor_changed_set_entry
), entry
);
2107 g_signal_connect (G_OBJECT(entry
), "changed",
2108 G_CALLBACK(on_changed_disconnect
), packages_view
);
2111 /* Fill package list */
2112 anjuta_pkg_config_chooser_show_active_column (ANJUTA_PKG_CONFIG_CHOOSER (packages_view
),
2114 g_signal_connect (G_OBJECT(packages_view
), "package-activated",
2115 G_CALLBACK(on_pkg_chooser_selection_changed
), ok_button
);
2116 g_signal_connect (G_OBJECT(packages_view
), "package-deactivated",
2117 G_CALLBACK(on_pkg_chooser_selection_changed
), ok_button
);
2120 gtk_window_set_transient_for (GTK_WINDOW (dialog
), parent
);
2123 /* execute dialog */
2125 response
= gtk_dialog_run (GTK_DIALOG (dialog
));
2128 case GTK_RESPONSE_OK
:
2131 AnjutaProjectNode
*module
= NULL
;
2132 GString
*error_message
= g_string_new (NULL
);
2134 name
= g_strdup (gtk_entry_get_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (module_entry
)))));
2135 if (name
!= NULL
) name
= g_strstrip (name
);
2137 if ((name
== NULL
) || (*name
== '\0'))
2139 /* Missing module name */
2140 g_string_append (error_message
, _("Missing module name"));
2144 /* Look for already existing module */
2145 module
= anjuta_pm_project_get_module (plugin
->project
, name
);
2148 /* Create new module */
2149 AnjutaProjectNode
*root
;
2150 GError
*error
= NULL
;
2152 root
= ianjuta_project_get_root (plugin
->project
->project
, NULL
);
2154 module
= ianjuta_project_add_node_after (plugin
->project
->project
, root
, NULL
, ANJUTA_PROJECT_MODULE
, NULL
, name
, &error
);
2157 gchar
*str
= g_strdup_printf ("%s: %s\n", name
, error
->message
);
2159 g_string_append (error_message
, str
);
2160 g_error_free (error
);
2172 list
= anjuta_pkg_config_chooser_get_active_packages (ANJUTA_PKG_CONFIG_CHOOSER (packages_view
));
2173 for (node
= list
; node
!= NULL
; node
= g_list_next (node
))
2176 AnjutaProjectNode
* new_package
;
2177 GError
*error
= NULL
;
2181 new_package
= ianjuta_project_add_node_after (plugin
->project
->project
, module
, NULL
, ANJUTA_PROJECT_PACKAGE
, NULL
, name
, &error
);
2184 gchar
*str
= g_strdup_printf ("%s: %s\n",
2187 g_string_append (error_message
, str
);
2188 g_error_free (error
);
2193 packages
= g_list_append (packages
, new_package
);
2197 anjuta_util_glist_strings_free (list
);
2200 if (error_message
->len
!= 0)
2202 error_dialog (parent
, _("Cannot add packages"),
2203 "%s",error_message
->str
);
2209 g_string_free (error_message
, TRUE
);
2212 case GTK_RESPONSE_HELP
:
2213 anjuta_util_help_display (GTK_WIDGET (dialog
), ANJUTA_MANUAL
, ADD_PACKAGE_HELP
);
2222 gtk_widget_destroy (dialog
);
2223 g_object_unref (gui
);