1 /* gEDA - GPL Electronic Design Automation
2 * gschem - gEDA Schematic Capture
3 * Copyright (C) 1998-2010 Ales Hvezda
4 * Copyright (C) 1998-2010 gEDA Contributors (see ChangeLog for details)
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (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
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 #include <sys/types.h>
25 #ifdef HAVE_SYS_PARAM_H
26 #include <sys/param.h>
37 #include <gdk/gdkkeysyms.h>
39 #ifdef HAVE_LIBDMALLOC
43 #include "../include/gschem_dialog.h"
44 #include "../include/x_preview.h"
45 #include "../include/x_compselect.h"
47 /*! \def COMPSELECT_FILTER_INTERVAL
48 * \brief The time interval between request and actual filtering
50 * This constant is the time-lag between user modifications in the
51 * filter entry and the actual evaluation of the filter which
52 * ultimately update the display. It helps reduce the frequency of
53 * evaluation of the filter as user types.
55 * Unit is milliseconds.
57 #define COMPSELECT_FILTER_INTERVAL 200
60 enum compselect_view
{
66 /*! \brief Return currently active component-selector view
68 * \par Function Description
69 * This function returns which one of the possible views is active
70 * in the component selector: VIEW_INUSE for the in-use view, or
71 * VIEW_CLIB for the component library view.
73 * \todo FIXME: This function assumes the GtkNotebook pages displaying the
74 * views are in a specific order.
76 * \param [in] compselect The component selection dialog.
77 * \returns The currently active view (from the compselect_view enum).
79 static enum compselect_view
80 compselect_get_view (Compselect
*compselect
)
82 switch (gtk_notebook_get_current_page (compselect
->viewtabs
)) {
83 case 0: return VIEW_INUSE
; /* In use page */
84 case 1: return VIEW_CLIB
; /* Component library page */
86 g_critical ("compselect_get_view: Unknown tab position\n");
92 /*! \brief Process the response returned by the component selection dialog.
93 * \par Function Description
94 * This function handles the response <B>arg1</B> of the component
95 * selection dialog <B>dialog</B>.
97 * Parameter <B>user_data</B> is a pointer on the relevant toplevel
100 * \param [in] dialog The component selection dialog.
101 * \param [in] arg1 The response ID.
102 * \param [in] user_data A pointer on the GSCHEM_TOPLEVEL environment.
105 x_compselect_callback_response (GtkDialog
*dialog
,
109 Compselect
*compselect
= (Compselect
*)dialog
;
110 GSCHEM_TOPLEVEL
*w_current
= (GSCHEM_TOPLEVEL
*)user_data
;
111 TOPLEVEL
*toplevel
= w_current
->toplevel
;
114 case COMPSELECT_RESPONSE_PLACE
: {
115 CLibSymbol
*symbol
= NULL
;
116 CompselectBehavior behavior
;
118 g_object_get (compselect
,
120 "behavior", &behavior
,
123 w_current
->include_complex
= w_current
->embed_complex
= 0;
125 case COMPSELECT_BEHAVIOR_REFERENCE
:
127 case COMPSELECT_BEHAVIOR_EMBED
:
128 w_current
->embed_complex
= 1;
130 case COMPSELECT_BEHAVIOR_INCLUDE
:
131 w_current
->include_complex
= 1;
134 g_assert_not_reached ();
137 if (w_current
->event_state
== ENDCOMP
) {
138 /* Delete the component which was being placed */
139 if (w_current
->rubber_visible
)
140 o_place_invalidate_rubber (w_current
, FALSE
);
141 w_current
->rubber_visible
= 0;
142 s_delete_object_glist (toplevel
,
143 toplevel
->page_current
->place_list
);
144 toplevel
->page_current
->place_list
= NULL
;
146 /* Cancel whatever other action is currently in progress */
147 o_redraw_cleanstates (w_current
);
150 if (symbol
== NULL
) {
151 /* If there is no symbol selected, switch to SELECT mode */
152 w_current
->event_state
= SELECT
;
154 /* Otherwise set the new symbol to place */
155 o_complex_prepare_place (w_current
, symbol
);
160 case COMPSELECT_RESPONSE_HIDE
:
161 /* Response when clicking on the "hide" button */
163 /* If there is no component in the complex place list, set the current one */
164 if (toplevel
->page_current
->place_list
== NULL
) {
165 gtk_dialog_response (GTK_DIALOG (compselect
),
166 COMPSELECT_RESPONSE_PLACE
);
169 /* Hide the component selector */
170 g_object_set (G_OBJECT (compselect
), "hidden", TRUE
, NULL
);
173 case GTK_RESPONSE_CLOSE
:
174 case GTK_RESPONSE_DELETE_EVENT
:
175 g_assert (GTK_WIDGET (dialog
) == w_current
->cswindow
);
176 gtk_widget_destroy (GTK_WIDGET (dialog
));
177 w_current
->cswindow
= NULL
;
179 if (w_current
->event_state
== ENDCOMP
) {
181 /* Cancel the place operation currently in progress */
182 o_redraw_cleanstates (w_current
);
184 /* return to the default state */
185 i_set_state (w_current
, SELECT
);
186 i_update_toolbar (w_current
);
191 /* Do nothing, in case there's another handler function which
192 can handle the response ID received. */
198 /*! \brief Opens a component selection dialog.
199 * \par Function Description
200 * This function opens the component chooser dialog for
201 * <B>toplevel</B> if it is not already. In this last case, it only
204 * \param [in] w_current The GSCHEM_TOPLEVEL environment.
207 x_compselect_open (GSCHEM_TOPLEVEL
*w_current
)
209 GtkWidget
*current_tab
, *entry_filter
;
210 GtkNotebook
*compselect_notebook
;
212 if (w_current
->cswindow
== NULL
) {
213 w_current
->cswindow
= GTK_WIDGET (
214 g_object_new (TYPE_COMPSELECT
,
216 "settings-name", "compselect",
217 "gschem-toplevel", w_current
,
220 g_signal_connect (w_current
->cswindow
,
222 G_CALLBACK (x_compselect_callback_response
),
225 gtk_window_set_transient_for (GTK_WINDOW (w_current
->cswindow
),
226 GTK_WINDOW (w_current
->main_window
));
228 gtk_widget_show (w_current
->cswindow
);
231 gtk_window_present (GTK_WINDOW (w_current
->cswindow
));
233 gtk_editable_select_region (GTK_EDITABLE (COMPSELECT (w_current
->cswindow
)->entry_filter
), 0, -1);
235 /* Set the focus to the filter entry only if it is in the current
237 compselect_notebook
= GTK_NOTEBOOK (COMPSELECT (w_current
->cswindow
)->viewtabs
);
238 current_tab
= gtk_notebook_get_nth_page (compselect_notebook
,
239 gtk_notebook_get_current_page (compselect_notebook
));
240 entry_filter
= GTK_WIDGET (COMPSELECT (w_current
->cswindow
)->entry_filter
);
241 if (gtk_widget_is_ancestor (entry_filter
, current_tab
)) {
242 gtk_widget_grab_focus (entry_filter
);
246 /*! \brief Closes the component selection dialog.
247 * \par Function Description
248 * This function closes the component chooser dialog associated with
251 * \param [in] w_current The GSCHEM_TOPLEVEL environment.
254 x_compselect_close (GSCHEM_TOPLEVEL
*w_current
)
256 if (w_current
->cswindow
) {
257 g_assert (IS_COMPSELECT (w_current
->cswindow
));
258 gtk_widget_destroy (w_current
->cswindow
);
259 w_current
->cswindow
= NULL
;
265 x_compselect_deselect (GSCHEM_TOPLEVEL
*w_current
)
267 Compselect
*compselect
= COMPSELECT (w_current
->cswindow
);
269 if (compselect
== NULL
)
272 switch (compselect_get_view (compselect
)) {
274 gtk_tree_selection_unselect_all (
275 gtk_tree_view_get_selection (compselect
->inusetreeview
));
278 gtk_tree_selection_unselect_all (
279 gtk_tree_view_get_selection (compselect
->libtreeview
));
282 g_assert_not_reached ();
293 static GObjectClass
*compselect_parent_class
= NULL
;
296 static void compselect_class_init (CompselectClass
*class);
297 static GObject
*compselect_constructor (GType type
,
298 guint n_construct_properties
,
299 GObjectConstructParam
*construct_params
);
300 static void compselect_finalize (GObject
*object
);
301 static void compselect_set_property (GObject
*object
,
305 static void compselect_get_property (GObject
*object
,
312 /*! \brief Sets data for a particular cell of the in use treeview.
313 * \par Function Description
314 * This function determines what data is to be displayed in the
315 * "in use" symbol selection view.
317 * The model is a list of symbols. s_clib_symbol_get_name() is called
318 * to get the text to display.
321 inuse_treeview_set_cell_data (GtkTreeViewColumn
*tree_column
,
322 GtkCellRenderer
*cell
,
323 GtkTreeModel
*tree_model
,
329 gtk_tree_model_get (tree_model
, iter
, 0, &symbol
, -1);
330 g_object_set ((GObject
*)cell
, "text", s_clib_symbol_get_name (symbol
), NULL
);
333 /*! \brief Sets data for a particular cell of the library treeview.
334 * \par Function Description
335 * This function determines what data is to be displayed in the
336 * selection selection view.
338 * The top level of the model contains sources, and the next symbols.
339 * s_clib_source_get_name() or s_clib_symbol_get_name() as
340 * appropriate is called to get the text to display.
343 lib_treeview_set_cell_data (GtkTreeViewColumn
*tree_column
,
344 GtkCellRenderer
*cell
,
345 GtkTreeModel
*tree_model
,
354 if (!gtk_tree_model_iter_parent (tree_model
, &parent
, iter
)) {
355 /* If top level, must be a source. */
356 gtk_tree_model_get (tree_model
, iter
, 0, &source
, -1);
357 text
= s_clib_source_get_name (source
);
359 /* Otherwise, must be a symbol */
360 gtk_tree_model_get (tree_model
, iter
, 0, &symbol
, -1);
361 text
= s_clib_symbol_get_name (symbol
);
363 g_object_set ((GObject
*)cell
, "text", text
, NULL
);
366 /*! \brief Determines visibility of items of the library treeview.
367 * \par Function Description
368 * This is the function used to filter entries of the component
371 * \param [in] model The current selection in the treeview.
372 * \param [in] iter An iterator on a component or folder in the tree.
373 * \param [in] data The component selection dialog.
374 * \returns TRUE if item should be visible, FALSE otherwise.
377 lib_model_filter_visible_func (GtkTreeModel
*model
,
381 Compselect
*compselect
= (Compselect
*)data
;
383 const gchar
*compname
;
384 gchar
*compname_upper
, *text_upper
, *pattern
;
388 g_assert (IS_COMPSELECT (data
));
390 text
= gtk_entry_get_text (compselect
->entry_filter
);
391 if (g_ascii_strcasecmp (text
, "") == 0) {
395 /* If this is a source, only display it if it has children that
397 if (gtk_tree_model_iter_has_child (model
, iter
)) {
400 gtk_tree_model_iter_children (model
, &iter2
, iter
);
403 if (lib_model_filter_visible_func (model
, &iter2
, data
)) {
407 } while (gtk_tree_model_iter_next (model
, &iter2
));
409 gtk_tree_model_get (model
, iter
,
412 compname
= s_clib_symbol_get_name (sym
);
413 /* Do a case insensitive comparison, converting the strings
415 compname_upper
= g_ascii_strup (compname
, -1);
416 text_upper
= g_ascii_strup (text
, -1);
417 pattern
= g_strconcat ("*", text_upper
, "*", NULL
);
418 ret
= g_pattern_match_simple (pattern
, compname_upper
);
419 g_free (compname_upper
);
428 /*! \brief Handles activation (e.g. double-clicking) of a component row
429 * \par Function Description
430 * Component row activated handler:
431 * As a convenince to the user, expand / contract any node with children.
433 * \param [in] tree_view The component treeview.
434 * \param [in] path The GtkTreePath to the activated row.
435 * \param [in] column The GtkTreeViewColumn in which the activation occurred.
436 * \param [in] user_data The component selection dialog.
439 tree_row_activated (GtkTreeView
*tree_view
,
441 GtkTreeViewColumn
*column
,
446 Compselect
*compselect
= (Compselect
*)user_data
;
448 model
= gtk_tree_view_get_model (tree_view
);
449 gtk_tree_model_get_iter (model
, &iter
, path
);
451 if (!gtk_tree_model_iter_has_child (model
, &iter
)) {
452 gtk_dialog_response (GTK_DIALOG (compselect
),
453 COMPSELECT_RESPONSE_HIDE
);
457 if (gtk_tree_view_row_expanded (tree_view
, path
))
458 gtk_tree_view_collapse_row (tree_view
, path
);
460 gtk_tree_view_expand_row (tree_view
, path
, FALSE
);
463 /*! \brief GCompareFunc to sort an text object list by the object strings
466 sort_object_text (OBJECT
*a
, OBJECT
*b
)
468 return strcmp (a
->text
->string
, b
->text
->string
);
472 ATTRIBUTE_COLUMN_NAME
= 0,
473 ATTRIBUTE_COLUMN_VALUE
,
474 NUM_ATTRIBUTE_COLUMNS
477 /*! \brief Update the model of the attributes treeview
478 * \par Function Description
479 * This function takes the toplevel attributes from the preview widget and
480 * puts them into the model of the <b>attrtreeview</b> widget.
481 * \param [in] compselect The dialog compselect
482 * \param [in] preview_toplevel The toplevel of the preview widget
485 update_attributes_model (Compselect
*compselect
, TOPLEVEL
*preview_toplevel
)
489 GtkTreeViewColumn
*column
;
490 GList
*listiter
, *o_iter
, *o_attrlist
, *filter_list
;
494 model
= (GtkListStore
*) gtk_tree_view_get_model (compselect
->attrtreeview
);
495 gtk_list_store_clear (model
);
497 /* Invalidate the column width for the attribute value column, so
498 * the column is re-sized based on the new data being shown. Symbols
499 * with long values are common, and we don't want having viewed those
500 * forcing a h-scroll-bar on symbols with short valued attributes.
502 * We might also consider invalidating the attribute name columns,
503 * however that gives an inconsistent column division when swithing
504 * between symbols, which doesn't look nice. For now, assume that
505 * the name column can keep the max width gained whilst previewing.
507 column
= gtk_tree_view_get_column (compselect
->attrtreeview
,
508 ATTRIBUTE_COLUMN_VALUE
);
509 gtk_tree_view_column_queue_resize (column
);
511 if (preview_toplevel
->page_current
== NULL
) {
515 o_attrlist
= o_attrib_find_floating_attribs (
516 s_page_objects (preview_toplevel
->page_current
));
518 filter_list
= GSCHEM_DIALOG (compselect
)->w_current
->component_select_attrlist
;
520 if (filter_list
!= NULL
521 && strcmp (filter_list
->data
, "*") == 0) {
522 /* display all attributes in alphabetical order */
523 o_attrlist
= g_list_sort (o_attrlist
, (GCompareFunc
) sort_object_text
);
524 for (o_iter
= o_attrlist
; o_iter
!= NULL
; o_iter
= g_list_next (o_iter
)) {
525 o_current
= o_iter
->data
;
526 o_attrib_get_name_value (o_current
, &name
, &value
);
527 gtk_list_store_append (model
, &iter
);
528 gtk_list_store_set (model
, &iter
, 0, name
, 1, value
, -1);
533 /* display only attribute that are in the filter list */
534 for (listiter
= filter_list
;
536 listiter
= g_list_next (listiter
)) {
537 for (o_iter
= o_attrlist
; o_iter
!= NULL
; o_iter
= g_list_next (o_iter
)) {
538 o_current
= o_iter
->data
;
539 if (o_attrib_get_name_value (o_current
, &name
, &value
)) {
540 if (strcmp (name
, listiter
->data
) == 0) {
541 gtk_list_store_append (model
, &iter
);
542 gtk_list_store_set (model
, &iter
, 0, name
, 1, value
, -1);
550 g_list_free (o_attrlist
);
553 /*! \brief Handles changes in the treeview selection.
554 * \par Function Description
555 * This is the callback function that is called every time the user
556 * select a row in either component treeview of the dialog.
558 * If the selection is not a selection of a component (a directory
559 * name), it does nothing. Otherwise it retrieves the #CLibSymbol
562 * It then emits the dialog's <B>apply</B> signal to let its parent
563 * know that a component has been selected.
565 * \param [in] selection The current selection in the treeview.
566 * \param [in] user_data The component selection dialog.
569 compselect_callback_tree_selection_changed (GtkTreeSelection
*selection
,
574 GtkTreeIter iter
, parent
;
575 Compselect
*compselect
= (Compselect
*)user_data
;
576 const CLibSymbol
*sym
= NULL
;
577 gchar
*buffer
= NULL
;
579 if (gtk_tree_selection_get_selected (selection
, &model
, &iter
)) {
581 view
= gtk_tree_selection_get_tree_view (selection
);
582 if (view
== compselect
->inusetreeview
||
583 /* No special handling required */
584 (view
== compselect
->libtreeview
&&
585 gtk_tree_model_iter_parent (model
, &parent
, &iter
))) {
586 /* Tree view needs to check that we're at a leaf node */
588 gtk_tree_model_get (model
, &iter
, 0, &sym
, -1);
589 buffer
= s_clib_symbol_get_data (sym
);
593 /* update the preview with new symbol data */
594 g_object_set (compselect
->preview
,
596 "active", (buffer
!= NULL
),
599 /* update the attributes with the toplevel of the preview widget*/
600 if (compselect
->attrtreeview
!= NULL
)
601 update_attributes_model (compselect
,
602 compselect
->preview
->preview_w_current
->toplevel
);
604 /* signal a component has been selected to parent of dialog */
605 g_signal_emit_by_name (compselect
,
607 COMPSELECT_RESPONSE_PLACE
,
613 /*! \brief Requests re-evaluation of the filter.
614 * \par Function Description
615 * This is the timeout function for the filtering of component in the
616 * tree of the dialog.
618 * The timeout this callback is attached to is removed after the
621 * \param [in] data The component selection dialog.
622 * \returns FALSE to remove the timeout.
625 compselect_filter_timeout (gpointer data
)
627 Compselect
*compselect
= COMPSELECT (data
);
630 /* resets the source id in compselect */
631 compselect
->filter_timeout
= 0;
633 model
= gtk_tree_view_get_model (compselect
->libtreeview
);
636 const gchar
*text
= gtk_entry_get_text (compselect
->entry_filter
);
637 gtk_tree_model_filter_refilter ((GtkTreeModelFilter
*)model
);
638 if (strcmp (text
, "") != 0) {
639 /* filter text not-empty */
640 gtk_tree_view_expand_all (compselect
->libtreeview
);
642 /* filter text is empty, collapse expanded tree */
643 gtk_tree_view_collapse_all (compselect
->libtreeview
);
647 /* return FALSE to remove the source */
651 /*! \brief Callback function for the changed signal of the filter entry.
652 * \par Function Description
653 * This function monitors changes in the entry filter of the dialog.
655 * It specifically manages the sensitivity of the clear button of the
656 * entry depending on its contents. It also requests an update of the
657 * component list by re-evaluating filter at every changes.
659 * \param [in] editable The filter text entry.
660 * \param [in] user_data The component selection dialog.
663 compselect_callback_filter_entry_changed (GtkEditable
*editable
,
666 Compselect
*compselect
= COMPSELECT (user_data
);
670 /* turns button off if filter entry is empty */
671 /* turns it on otherwise */
672 button
= GTK_WIDGET (compselect
->button_clear
);
674 (g_ascii_strcasecmp (gtk_entry_get_text (compselect
->entry_filter
),
676 if (GTK_WIDGET_IS_SENSITIVE (button
) != sensitive
) {
677 gtk_widget_set_sensitive (button
, sensitive
);
680 /* Cancel any pending update of the component list filter */
681 if (compselect
->filter_timeout
!= 0)
682 g_source_remove (compselect
->filter_timeout
);
684 /* Schedule an update of the component list filter in
685 * COMPSELECT_FILTER_INTERVAL milliseconds */
686 compselect
->filter_timeout
= g_timeout_add (COMPSELECT_FILTER_INTERVAL
,
687 compselect_filter_timeout
,
692 /*! \brief Handles a click on the clear button.
693 * \par Function Description
694 * This is the callback function called every time the user press the
695 * clear button associated with the filter.
697 * It resets the filter entry, indirectly causing re-evaluation
698 * of the filter on the list of symbols to update the display.
700 * \param [in] button The clear button
701 * \param [in] user_data The component selection dialog.
704 compselect_callback_filter_button_clicked (GtkButton
*button
,
707 Compselect
*compselect
= COMPSELECT (user_data
);
709 /* clears text in text entry for filter */
710 gtk_entry_set_text (compselect
->entry_filter
, "");
714 /*! \brief Handles changes of behavior.
715 * \par Function Description
716 * This function is called every time the value of the option menu
717 * for behaviors is modified.
719 * It emits the dialog's <B>apply</B> signal to let the parent know
720 * that the requested behavior for the next adding of a component has
723 * \param [in] optionmenu The behavior option menu.
724 * \param [in] user_data The component selection dialog.
727 compselect_callback_behavior_changed (GtkOptionMenu
*optionmenu
,
730 Compselect
*compselect
= (Compselect
*)user_data
;
732 g_signal_emit_by_name (compselect
,
734 COMPSELECT_RESPONSE_PLACE
,
738 /* \brief Create the tree model for the "In Use" view.
739 * \par Function Description
740 * Creates a straightforward list of symbols which are currently in
741 * use, using s_toplevel_get_symbols().
744 create_inuse_tree_model (Compselect
*compselect
)
747 GList
*symhead
, *symlist
;
750 store
= (GtkListStore
*) gtk_list_store_new (1, G_TYPE_POINTER
);
752 symhead
= s_toplevel_get_symbols (GSCHEM_DIALOG (compselect
)->w_current
->toplevel
);
754 for (symlist
= symhead
;
756 symlist
= g_list_next (symlist
)) {
758 gtk_list_store_append (store
, &iter
);
760 gtk_list_store_set (store
, &iter
,
765 g_list_free (symhead
);
767 return (GtkTreeModel
*)store
;
770 /* \brief Create the tree model for the "Library" view.
771 * \par Function Description
772 * Creates a tree where the branches are the available component
773 * sources and the leaves are the symbols.
776 create_lib_tree_model (Compselect
*compselect
)
779 GList
*srchead
, *srclist
;
780 GList
*symhead
, *symlist
;
782 store
= (GtkTreeStore
*)gtk_tree_store_new (1, G_TYPE_POINTER
);
784 /* populate component store */
785 srchead
= s_clib_get_sources (GSCHEM_DIALOG (compselect
)->w_current
->sort_component_library
!= 0);
786 for (srclist
= srchead
;
788 srclist
= g_list_next (srclist
)) {
790 GtkTreeIter iter
, iter2
;
792 gtk_tree_store_append (store
, &iter
, NULL
);
793 gtk_tree_store_set (store
, &iter
,
797 symhead
= s_clib_source_get_symbols ((CLibSource
*)srclist
->data
);
798 for (symlist
= symhead
;
800 symlist
= g_list_next (symlist
)) {
802 gtk_tree_store_append (store
, &iter2
, &iter
);
803 gtk_tree_store_set (store
, &iter2
,
808 g_list_free (symhead
);
810 g_list_free (srchead
);
812 return (GtkTreeModel
*)store
;
815 /* \brief On-demand refresh of the component library.
816 * \par Function Description
817 * Requests a rescan of the component library in order to pick up any
818 * new signals, and then updates the component selector.
821 compselect_callback_refresh_library (GtkButton
*button
, gpointer user_data
)
823 Compselect
*compselect
= COMPSELECT (user_data
);
825 GtkTreeSelection
*selection
;
827 /* Rescan the libraries for symbols */
830 /* Refresh the "Library" view */
831 model
= (GtkTreeModel
*)
832 g_object_new (GTK_TYPE_TREE_MODEL_FILTER
,
833 "child-model", create_lib_tree_model (compselect
),
834 "virtual-root", NULL
,
837 gtk_tree_model_filter_set_visible_func ((GtkTreeModelFilter
*)model
,
838 lib_model_filter_visible_func
,
842 /* Block handling selection updated for duration of model changes */
843 selection
= gtk_tree_view_get_selection (compselect
->libtreeview
);
844 g_signal_handlers_block_by_func (selection
,
845 compselect_callback_tree_selection_changed
,
848 /* Update the view model with signals blocked */
849 gtk_tree_view_set_model (compselect
->libtreeview
, model
);
851 /* Refresh the "In Use" view */
852 model
= create_inuse_tree_model (compselect
);
854 /* Here we can update the model without blocking signals
855 * as this is the second (final) tree view we are updating */
856 gtk_tree_view_set_model (compselect
->inusetreeview
, model
);
858 /* Unblock & fire handler for libtreeview selection */
859 g_signal_handlers_unblock_by_func (selection
,
860 compselect_callback_tree_selection_changed
,
864 /*! \brief Creates the treeview for the "In Use" view. */
866 create_inuse_treeview (Compselect
*compselect
)
868 GtkWidget
*scrolled_win
, *treeview
, *vbox
, *hbox
, *button
;
870 GtkTreeSelection
*selection
;
871 GtkCellRenderer
*renderer
;
872 GtkTreeViewColumn
*column
;
874 model
= create_inuse_tree_model (compselect
);
876 vbox
= GTK_WIDGET (g_object_new (GTK_TYPE_VBOX
,
880 "homogeneous", FALSE
,
884 /* Create a scrolled window to accomodate the treeview */
885 scrolled_win
= GTK_WIDGET (
886 g_object_new (GTK_TYPE_SCROLLED_WINDOW
,
889 /* GtkScrolledWindow */
890 "hscrollbar-policy", GTK_POLICY_AUTOMATIC
,
891 "vscrollbar-policy", GTK_POLICY_ALWAYS
,
892 "shadow-type", GTK_SHADOW_ETCHED_IN
,
895 /* Create the treeview */
896 treeview
= GTK_WIDGET (g_object_new (GTK_TYPE_TREE_VIEW
,
900 "headers-visible", FALSE
,
903 /* Connect callback to selection */
904 selection
= gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview
));
905 gtk_tree_selection_set_mode (selection
, GTK_SELECTION_SINGLE
);
906 g_signal_connect (selection
,
908 G_CALLBACK (compselect_callback_tree_selection_changed
),
911 /* Insert a column for symbol name */
912 renderer
= GTK_CELL_RENDERER (
913 g_object_new (GTK_TYPE_CELL_RENDERER_TEXT
,
914 /* GtkCellRendererText */
917 column
= GTK_TREE_VIEW_COLUMN (
918 g_object_new (GTK_TYPE_TREE_VIEW_COLUMN
,
919 /* GtkTreeViewColumn */
920 "title", _("Components"),
922 gtk_tree_view_column_pack_start (column
, renderer
, TRUE
);
923 gtk_tree_view_column_set_cell_data_func (column
, renderer
,
924 inuse_treeview_set_cell_data
,
926 gtk_tree_view_append_column (GTK_TREE_VIEW (treeview
), column
);
928 /* Add the treeview to the scrolled window */
929 gtk_container_add (GTK_CONTAINER (scrolled_win
), treeview
);
930 /* set the inuse treeview of compselect */
931 compselect
->inusetreeview
= GTK_TREE_VIEW (treeview
);
933 /* add the scrolled window for directories to the vertical box */
934 gtk_box_pack_start (GTK_BOX (vbox
), scrolled_win
,
937 /* -- refresh button area -- */
938 hbox
= GTK_WIDGET (g_object_new (GTK_TYPE_HBOX
,
940 "homogeneous", FALSE
,
943 /* create the refresh button */
944 button
= GTK_WIDGET (g_object_new (GTK_TYPE_BUTTON
,
948 "relief", GTK_RELIEF_NONE
,
950 gtk_container_add (GTK_CONTAINER (button
),
951 gtk_image_new_from_stock (GTK_STOCK_REFRESH
,
952 GTK_ICON_SIZE_SMALL_TOOLBAR
));
953 /* add the refresh button to the horizontal box at the end */
954 gtk_box_pack_end (GTK_BOX (hbox
), button
, FALSE
, FALSE
, 0);
955 g_signal_connect (button
,
957 G_CALLBACK (compselect_callback_refresh_library
),
960 /* add the refresh button area to the vertical box */
961 gtk_box_pack_start (GTK_BOX (vbox
), hbox
,
967 /*! \brief Creates the treeview for the "Library" view */
969 create_lib_treeview (Compselect
*compselect
)
971 GtkWidget
*libtreeview
, *vbox
, *scrolled_win
, *label
,
972 *hbox
, *entry
, *button
;
973 GtkTreeModel
*child_model
, *model
;
974 GtkTreeSelection
*selection
;
975 GtkCellRenderer
*renderer
;
976 GtkTreeViewColumn
*column
;
978 /* -- library selection view -- */
980 /* vertical box for component selection and search entry */
981 vbox
= GTK_WIDGET (g_object_new (GTK_TYPE_VBOX
,
985 "homogeneous", FALSE
,
989 child_model
= create_lib_tree_model (compselect
);
990 model
= (GtkTreeModel
*)g_object_new (GTK_TYPE_TREE_MODEL_FILTER
,
991 "child-model", child_model
,
992 "virtual-root", NULL
,
995 scrolled_win
= GTK_WIDGET (
996 g_object_new (GTK_TYPE_SCROLLED_WINDOW
,
999 /* GtkScrolledWindow */
1000 "hscrollbar-policy", GTK_POLICY_AUTOMATIC
,
1001 "vscrollbar-policy", GTK_POLICY_ALWAYS
,
1002 "shadow-type", GTK_SHADOW_ETCHED_IN
,
1004 /* create the treeview */
1005 libtreeview
= GTK_WIDGET (g_object_new (GTK_TYPE_TREE_VIEW
,
1009 "headers-visible", FALSE
,
1012 g_signal_connect (libtreeview
,
1014 G_CALLBACK (tree_row_activated
),
1017 /* connect callback to selection */
1018 selection
= gtk_tree_view_get_selection (GTK_TREE_VIEW (libtreeview
));
1019 gtk_tree_selection_set_mode (selection
, GTK_SELECTION_SINGLE
);
1020 g_signal_connect (selection
,
1022 G_CALLBACK (compselect_callback_tree_selection_changed
),
1025 /* insert a column to treeview for library/symbol name */
1026 renderer
= GTK_CELL_RENDERER (
1027 g_object_new (GTK_TYPE_CELL_RENDERER_TEXT
,
1028 /* GtkCellRendererText */
1031 column
= GTK_TREE_VIEW_COLUMN (
1032 g_object_new (GTK_TYPE_TREE_VIEW_COLUMN
,
1033 /* GtkTreeViewColumn */
1034 "title", _("Components"),
1036 gtk_tree_view_column_pack_start (column
, renderer
, TRUE
);
1037 gtk_tree_view_column_set_cell_data_func (column
, renderer
,
1038 lib_treeview_set_cell_data
,
1040 gtk_tree_view_append_column (GTK_TREE_VIEW (libtreeview
), column
);
1042 /* add the treeview to the scrolled window */
1043 gtk_container_add (GTK_CONTAINER (scrolled_win
), libtreeview
);
1044 /* set directory/component treeview of compselect */
1045 compselect
->libtreeview
= GTK_TREE_VIEW (libtreeview
);
1047 /* add the scrolled window for directories to the vertical box */
1048 gtk_box_pack_start (GTK_BOX (vbox
), scrolled_win
,
1052 /* -- filter area -- */
1053 hbox
= GTK_WIDGET (g_object_new (GTK_TYPE_HBOX
,
1055 "homogeneous", FALSE
,
1059 /* create the entry label */
1060 label
= GTK_WIDGET (g_object_new (GTK_TYPE_LABEL
,
1064 "label", _("Filter:"),
1066 /* add the search label to the filter area */
1067 gtk_box_pack_start (GTK_BOX (hbox
), label
,
1070 /* create the text entry for filter in components */
1071 entry
= GTK_WIDGET (g_object_new (GTK_TYPE_ENTRY
,
1075 g_signal_connect (entry
,
1077 G_CALLBACK (compselect_callback_filter_entry_changed
),
1080 /* now that that we have an entry, set the filter func of model */
1081 gtk_tree_model_filter_set_visible_func ((GtkTreeModelFilter
*)model
,
1082 lib_model_filter_visible_func
,
1086 /* add the filter entry to the filter area */
1087 gtk_box_pack_start (GTK_BOX (hbox
), entry
,
1089 /* set filter entry of compselect */
1090 compselect
->entry_filter
= GTK_ENTRY (entry
);
1091 /* and init the event source for component filter */
1092 compselect
->filter_timeout
= 0;
1094 /* create the erase button for filter entry */
1095 button
= GTK_WIDGET (g_object_new (GTK_TYPE_BUTTON
,
1099 "relief", GTK_RELIEF_NONE
,
1102 gtk_container_add (GTK_CONTAINER (button
),
1103 gtk_image_new_from_stock (GTK_STOCK_CLEAR
,
1104 GTK_ICON_SIZE_SMALL_TOOLBAR
));
1105 g_signal_connect (button
,
1107 G_CALLBACK (compselect_callback_filter_button_clicked
),
1109 /* add the clear button to the filter area */
1110 gtk_box_pack_start (GTK_BOX (hbox
), button
,
1112 /* set clear button of compselect */
1113 compselect
->button_clear
= GTK_BUTTON (button
);
1115 /* create the refresh button */
1116 button
= GTK_WIDGET (g_object_new (GTK_TYPE_BUTTON
,
1120 "relief", GTK_RELIEF_NONE
,
1122 gtk_container_add (GTK_CONTAINER (button
),
1123 gtk_image_new_from_stock (GTK_STOCK_REFRESH
,
1124 GTK_ICON_SIZE_SMALL_TOOLBAR
));
1125 /* add the refresh button to the filter area */
1126 gtk_box_pack_start (GTK_BOX (hbox
), button
, FALSE
, FALSE
, 0);
1127 g_signal_connect (button
,
1129 G_CALLBACK (compselect_callback_refresh_library
),
1132 /* add the filter area to the vertical box */
1133 gtk_box_pack_start (GTK_BOX (vbox
), hbox
,
1136 compselect
->libtreeview
= GTK_TREE_VIEW (libtreeview
);
1141 /*! \brief Creates the treeview widget for the attributes
1144 create_attributes_treeview (Compselect
*compselect
)
1146 GtkWidget
*attrtreeview
, *scrolled_win
;
1147 GtkListStore
*model
;
1148 GtkCellRenderer
*renderer
;
1149 GtkTreeViewColumn
*column
;
1151 model
= gtk_list_store_new (NUM_ATTRIBUTE_COLUMNS
,
1152 G_TYPE_STRING
, G_TYPE_STRING
);
1154 attrtreeview
= GTK_WIDGET (g_object_new (GTK_TYPE_TREE_VIEW
,
1157 "headers-visible", FALSE
,
1161 /* two columns for name and value of the attributes */
1162 renderer
= GTK_CELL_RENDERER (g_object_new (GTK_TYPE_CELL_RENDERER_TEXT
,
1166 column
= GTK_TREE_VIEW_COLUMN (g_object_new (GTK_TYPE_TREE_VIEW_COLUMN
,
1170 gtk_tree_view_column_pack_start (column
, renderer
, TRUE
);
1171 gtk_tree_view_column_add_attribute (column
, renderer
, "text",
1172 ATTRIBUTE_COLUMN_NAME
);
1173 gtk_tree_view_append_column (GTK_TREE_VIEW (attrtreeview
), column
);
1175 column
= GTK_TREE_VIEW_COLUMN (g_object_new (GTK_TYPE_TREE_VIEW_COLUMN
,
1176 "title", _("Value"),
1179 gtk_tree_view_column_pack_start (column
, renderer
, TRUE
);
1180 gtk_tree_view_column_add_attribute (column
, renderer
, "text",
1181 ATTRIBUTE_COLUMN_VALUE
);
1182 gtk_tree_view_append_column (GTK_TREE_VIEW (attrtreeview
), column
);
1184 scrolled_win
= GTK_WIDGET (g_object_new (GTK_TYPE_SCROLLED_WINDOW
,
1187 /* GtkScrolledWindow */
1188 "hscrollbar-policy", GTK_POLICY_AUTOMATIC
,
1189 "vscrollbar-policy", GTK_POLICY_AUTOMATIC
,
1190 "shadow-type", GTK_SHADOW_ETCHED_IN
,
1193 gtk_container_add (GTK_CONTAINER (scrolled_win
), attrtreeview
);
1195 compselect
->attrtreeview
= GTK_TREE_VIEW (attrtreeview
);
1197 return scrolled_win
;
1200 /*! \brief Create the combo box for behaviors.
1201 * \par Function Description
1202 * This function creates and returns a <B>GtkComboBox</B> for
1203 * selecting the behavior when a component is added to the sheet.
1206 create_behaviors_combo_box (void)
1208 GtkWidget
*combobox
;
1210 combobox
= gtk_combo_box_new_text ();
1212 /* Note: order of items in menu is important */
1213 /* COMPSEL_BEHAVIOR_REFERENCE */
1214 gtk_combo_box_append_text (GTK_COMBO_BOX (combobox
),
1215 _("Default behavior - reference component"));
1216 /* COMPSEL_BEHAVIOR_EMBED */
1217 gtk_combo_box_append_text (GTK_COMBO_BOX (combobox
),
1218 _("Embed component in schematic"));
1219 /* COMPSEL_BEHAVIOR_INCLUDE */
1220 gtk_combo_box_append_text (GTK_COMBO_BOX (combobox
),
1221 _("Include component as individual objects"));
1223 gtk_combo_box_set_active (GTK_COMBO_BOX (combobox
), 0);
1229 compselect_get_type ()
1231 static GType compselect_type
= 0;
1233 if (!compselect_type
) {
1234 static const GTypeInfo compselect_info
= {
1235 sizeof (CompselectClass
),
1236 NULL
, /* base_init */
1237 NULL
, /* base_finalize */
1238 (GClassInitFunc
) compselect_class_init
,
1239 NULL
, /* class_finalize */
1240 NULL
, /* class_data */
1241 sizeof (Compselect
),
1242 0, /* n_preallocs */
1243 NULL
/* instance_init */
1246 compselect_type
= g_type_register_static (GSCHEM_TYPE_DIALOG
,
1248 &compselect_info
, 0);
1251 return compselect_type
;
1255 /*! \brief GschemDialog "geometry_save" class method handler
1257 * \par Function Description
1258 * Chain up to our parent's method to save the dialog's size and
1259 * position, then save the dialog's current internal geometry.
1261 * \param [in] dialog The GschemDialog to save the geometry of.
1262 * \param [in] key_file The GKeyFile to save the geometry data to.
1263 * \param [in] group_name The group name in the key file to store the data under.
1266 compselect_geometry_save (GschemDialog
*dialog
, GKeyFile
*key_file
, gchar
*group_name
)
1270 /* Call the parent's geometry_save method */
1271 GSCHEM_DIALOG_CLASS (compselect_parent_class
)->
1272 geometry_save (dialog
, key_file
, group_name
);
1274 position
= gtk_paned_get_position (GTK_PANED (COMPSELECT (dialog
)->hpaned
));
1275 g_key_file_set_integer (key_file
, group_name
, "hpaned", position
);
1277 position
= gtk_paned_get_position (GTK_PANED (COMPSELECT (dialog
)->vpaned
));
1278 g_key_file_set_integer (key_file
, group_name
, "vpaned", position
);
1280 position
= gtk_notebook_get_current_page (COMPSELECT (dialog
)->viewtabs
);
1281 g_key_file_set_integer (key_file
, group_name
, "source-tab", position
);
1285 /*! \brief GschemDialog "geometry_restore" class method handler
1287 * \par Function Description
1288 * Chain up to our parent's method to restore the dialog's size and
1289 * position, then restore the dialog's current internal geometry.
1291 * \param [in] dialog The GschemDialog to restore the geometry of.
1292 * \param [in] key_file The GKeyFile to save the geometry data to.
1293 * \param [in] group_name The group name in the key file to store the data under.
1296 compselect_geometry_restore (GschemDialog
*dialog
, GKeyFile
*key_file
, gchar
*group_name
)
1300 /* Call the parent's geometry_restore method */
1301 GSCHEM_DIALOG_CLASS (compselect_parent_class
)->
1302 geometry_restore (dialog
, key_file
, group_name
);
1304 position
= g_key_file_get_integer (key_file
, group_name
, "hpaned", NULL
);
1306 gtk_paned_set_position (GTK_PANED (COMPSELECT (dialog
)->hpaned
), position
);
1308 position
= g_key_file_get_integer (key_file
, group_name
, "vpaned", NULL
);
1310 gtk_paned_set_position (GTK_PANED (COMPSELECT (dialog
)->vpaned
), position
);
1312 position
= g_key_file_get_integer (key_file
, group_name
, "source-tab", NULL
);
1313 gtk_notebook_set_current_page (COMPSELECT (dialog
)->viewtabs
, position
);
1318 compselect_class_init (CompselectClass
*klass
)
1320 GObjectClass
*gobject_class
= G_OBJECT_CLASS (klass
);
1321 GschemDialogClass
*gschem_dialog_class
= GSCHEM_DIALOG_CLASS (klass
);
1323 gschem_dialog_class
->geometry_save
= compselect_geometry_save
;
1324 gschem_dialog_class
->geometry_restore
= compselect_geometry_restore
;
1326 gobject_class
->constructor
= compselect_constructor
;
1327 gobject_class
->finalize
= compselect_finalize
;
1328 gobject_class
->set_property
= compselect_set_property
;
1329 gobject_class
->get_property
= compselect_get_property
;
1331 compselect_parent_class
= g_type_class_peek_parent (klass
);
1333 g_object_class_install_property (
1334 gobject_class
, PROP_SYMBOL
,
1335 g_param_spec_pointer ("symbol",
1339 g_object_class_install_property (
1340 gobject_class
, PROP_BEHAVIOR
,
1341 g_param_spec_enum ("behavior",
1344 COMPSELECT_TYPE_BEHAVIOR
,
1345 COMPSELECT_BEHAVIOR_REFERENCE
,
1346 G_PARAM_READWRITE
));
1347 g_object_class_install_property (
1348 gobject_class
, PROP_HIDDEN
,
1349 g_param_spec_boolean ("hidden",
1353 G_PARAM_READWRITE
));
1358 compselect_constructor (GType type
,
1359 guint n_construct_properties
,
1360 GObjectConstructParam
*construct_params
)
1363 Compselect
*compselect
;
1365 GtkWidget
*hpaned
, *vpaned
, *notebook
, *attributes
;
1366 GtkWidget
*libview
, *inuseview
;
1367 GtkWidget
*preview
, *combobox
;
1368 GtkWidget
*alignment
, *frame
;
1370 /* chain up to constructor of parent class */
1371 object
= G_OBJECT_CLASS (compselect_parent_class
)->
1372 constructor (type
, n_construct_properties
, construct_params
);
1373 compselect
= COMPSELECT (object
);
1375 /* dialog initialization */
1376 g_object_set (object
,
1378 "title", _("Select Component..."),
1379 "default-height", 300,
1380 "default-width", 400,
1383 /* vertical pane containing preview and attributes */
1384 vpaned
= GTK_WIDGET (g_object_new (GTK_TYPE_VPANED
, NULL
));
1385 compselect
->vpaned
= vpaned
;
1387 /* horizontal pane containing selection and preview */
1388 hpaned
= GTK_WIDGET (g_object_new (GTK_TYPE_HPANED
,
1392 compselect
->hpaned
= hpaned
;
1394 /* notebook for library and inuse views */
1395 notebook
= GTK_WIDGET (g_object_new (GTK_TYPE_NOTEBOOK
,
1397 compselect
->viewtabs
= GTK_NOTEBOOK (notebook
);
1399 inuseview
= create_inuse_treeview (compselect
);
1400 gtk_notebook_append_page (GTK_NOTEBOOK (notebook
), inuseview
,
1401 gtk_label_new (_("In Use")));
1403 libview
= create_lib_treeview (compselect
);
1404 gtk_notebook_append_page (GTK_NOTEBOOK (notebook
), libview
,
1405 gtk_label_new (_("Libraries")));
1407 /* include the vertical box in horizontal box */
1408 gtk_paned_pack1 (GTK_PANED (hpaned
), notebook
, TRUE
, FALSE
);
1411 /* -- preview area -- */
1412 frame
= GTK_WIDGET (g_object_new (GTK_TYPE_FRAME
,
1414 "label", _("Preview"),
1416 alignment
= GTK_WIDGET (g_object_new (GTK_TYPE_ALIGNMENT
,
1424 preview
= GTK_WIDGET (g_object_new (TYPE_PREVIEW
,
1428 gtk_container_add (GTK_CONTAINER (alignment
), preview
);
1429 gtk_container_add (GTK_CONTAINER (frame
), alignment
);
1430 /* set preview of compselect */
1431 compselect
->preview
= PREVIEW (preview
);
1433 gtk_paned_pack1 (GTK_PANED (vpaned
), frame
, FALSE
, FALSE
);
1435 /* only create the attribute treeview if there are elements in the
1436 component_select_attrlist */
1437 if (GSCHEM_DIALOG (compselect
)->w_current
->component_select_attrlist
== NULL
) {
1438 compselect
->attrtreeview
= NULL
;
1440 frame
= GTK_WIDGET (g_object_new (GTK_TYPE_FRAME
,
1442 "label", _("Attributes"),
1444 attributes
= create_attributes_treeview (compselect
);
1445 gtk_paned_pack2 (GTK_PANED (vpaned
), frame
, FALSE
, FALSE
);
1446 gtk_container_add (GTK_CONTAINER (frame
), attributes
);
1449 gtk_paned_pack2 (GTK_PANED (hpaned
), vpaned
, FALSE
, FALSE
);
1451 /* add the hpaned to the dialog vbox */
1452 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (compselect
)->vbox
), hpaned
,
1454 gtk_widget_show_all (hpaned
);
1457 /* -- behavior combo box -- */
1458 combobox
= create_behaviors_combo_box ();
1459 g_signal_connect (combobox
,
1461 G_CALLBACK (compselect_callback_behavior_changed
),
1463 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (compselect
)->vbox
), combobox
,
1465 gtk_widget_show_all (combobox
);
1466 /* set behavior combo box of compselect */
1467 compselect
->combobox_behaviors
= GTK_COMBO_BOX (combobox
);
1469 /* now add buttons in the action area */
1470 gtk_dialog_add_buttons (GTK_DIALOG (compselect
),
1471 /* - close button */
1472 GTK_STOCK_CLOSE
, GTK_RESPONSE_CLOSE
,
1473 GTK_STOCK_OK
, COMPSELECT_RESPONSE_HIDE
,
1476 /* Set the alternative button order (ok, cancel, help) for other systems */
1477 gtk_dialog_set_alternative_button_order (GTK_DIALOG (compselect
),
1478 COMPSELECT_RESPONSE_HIDE
,
1482 /* Initialize the hidden property */
1483 compselect
->hidden
= FALSE
;
1489 compselect_finalize (GObject
*object
)
1491 Compselect
*compselect
= COMPSELECT (object
);
1493 if (compselect
->filter_timeout
!= 0) {
1494 g_source_remove (compselect
->filter_timeout
);
1495 compselect
->filter_timeout
= 0;
1498 G_OBJECT_CLASS (compselect_parent_class
)->finalize (object
);
1502 compselect_set_property (GObject
*object
,
1504 const GValue
*value
,
1507 Compselect
*compselect
= COMPSELECT (object
);
1509 switch (property_id
) {
1511 gtk_combo_box_set_active (compselect
->combobox_behaviors
,
1512 g_value_get_enum (value
));
1515 compselect
->hidden
= g_value_get_boolean (value
);
1516 if (compselect
->hidden
)
1517 gtk_widget_hide (GTK_WIDGET (compselect
));
1519 gtk_window_present (GTK_WINDOW (compselect
));
1522 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
1528 compselect_get_property (GObject
*object
,
1533 Compselect
*compselect
= COMPSELECT (object
);
1535 switch (property_id
) {
1538 GtkTreeModel
*model
;
1539 GtkTreeIter iter
, parent
;
1540 CLibSymbol
*symbol
= NULL
;
1542 switch (compselect_get_view (compselect
)) {
1544 if (gtk_tree_selection_get_selected (
1545 gtk_tree_view_get_selection (compselect
->inusetreeview
),
1548 gtk_tree_model_get (model
, &iter
, 0, &symbol
, -1);
1552 if (gtk_tree_selection_get_selected (
1553 gtk_tree_view_get_selection (compselect
->libtreeview
),
1556 && gtk_tree_model_iter_parent (model
, &parent
, &iter
)) {
1557 gtk_tree_model_get (model
, &iter
, 0, &symbol
, -1);
1561 g_assert_not_reached ();
1564 g_value_set_pointer (value
, symbol
);
1568 g_value_set_enum (value
,
1569 gtk_combo_box_get_active (
1570 compselect
->combobox_behaviors
));
1573 g_value_set_boolean (value
, compselect
->hidden
);
1576 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
1584 compselect_behavior_get_type (void)
1586 static GType etype
= 0;
1589 static const GEnumValue values
[] = {
1590 { COMPSELECT_BEHAVIOR_REFERENCE
, "COMPSELECT_BEHAVIOR_REFERENCE", "reference" },
1591 { COMPSELECT_BEHAVIOR_EMBED
, "COMPSELECT_BEHAVIOR_EMBED", "embed" },
1592 { COMPSELECT_BEHAVIOR_INCLUDE
, "COMPSELECT_BEHAVIOR_INCLUDE", "include" },
1596 etype
= g_enum_register_static ("CompselectBehavior", values
);