4 * PCB, interactive printed circuit board design
5 * Copyright (C) 1994,1995,1996 Thomas Nau
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * Contact addresses for paper mail and Email:
22 * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
23 * Thomas.Nau@rz.uni-ulm.de
27 /* This file originally from the PCB Gtk port by Bill Wilson. It has
28 * since been combined with modified code from the gEDA project:
30 * gschem/src/ghid_library_window.c, checked out by Peter Clifton
31 * from gEDA/gaf commit 72581a91da08c9d69593c24756144fc18940992e
34 * gEDA - GPL Electronic Design Automation
35 * gschem - gEDA Schematic Capture
36 * Copyright (C) 1998-2007 Ales Hvezda
37 * Copyright (C) 1998-2007 gEDA Contributors (see ChangeLog for details)
39 * This program is free software; you can redistribute it and/or modify
40 * it under the terms of the GNU General Public License as published by
41 * the Free Software Foundation; either version 2 of the License, or
42 * (at your option) any later version.
44 * This program is distributed in the hope that it will be useful,
45 * but WITHOUT ANY WARRANTY; without even the implied warranty of
46 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
47 * GNU General Public License for more details.
49 * You should have received a copy of the GNU General Public License
50 * along with this program; if not, write to the Free Software
51 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
64 #include <gdk/gdkkeysyms.h>
66 #ifdef HAVE_LIBDMALLOC
70 static GtkWidget
*library_window
;
72 #include "gui-pinout-preview.h"
73 #include "gui-library-window.h"
75 /*! \def LIBRARY_FILTER_INTERVAL
76 * \brief The time interval between request and actual filtering
78 * This constant is the time-lag between user modifications in the
79 * filter entry and the actual evaluation of the filter which
80 * ultimately update the display. It helps reduce the frequency of
81 * evaluation of the filter as user types.
83 * Unit is milliseconds.
85 #define LIBRARY_FILTER_INTERVAL 200
89 library_window_configure_event_cb (GtkWidget
* widget
, GdkEventConfigure
* ev
,
92 GtkAllocation allocation
;
94 gtk_widget_get_allocation (widget
, &allocation
);
95 ghidgui
->library_window_width
= allocation
.width
;
96 ghidgui
->library_window_height
= allocation
.height
;
97 ghidgui
->config_modified
= TRUE
;
104 MENU_NAME_COLUMN
, /* Text to display in the tree */
105 MENU_LIBRARY_COLUMN
, /* Pointer to the LibraryMenuType */
106 MENU_ENTRY_COLUMN
, /* Pointer to the LibraryEntryType */
111 /*! \brief Process the response returned by the library dialog.
112 * \par Function Description
113 * This function handles the response <B>arg1</B> of the library
114 * dialog <B>dialog</B>.
116 * Parameter <B>user_data</B> is a pointer on the relevant toplevel
119 * \param [in] dialog The library dialog.
120 * \param [in] arg1 The response ID.
121 * \param [in] user_data
124 library_window_callback_response (GtkDialog
* dialog
,
125 gint arg1
, gpointer user_data
)
129 case GTK_RESPONSE_CLOSE
:
130 case GTK_RESPONSE_DELETE_EVENT
:
131 gtk_widget_destroy (GTK_WIDGET (library_window
));
132 library_window
= NULL
;
136 /* Do nothing, in case there's another handler function which
137 can handle the response ID received. */
143 /*! \brief Creates a library dialog.
144 * \par Function Description
145 * This function create the library dialog if it is not already created.
146 * It does not show the dialog, use ghid_library_window_show for that.
150 ghid_library_window_create (GHidPort
* out
)
152 GtkWidget
*current_tab
, *entry_filter
;
153 GtkNotebook
*notebook
;
158 library_window
= (GtkWidget
*)g_object_new (GHID_TYPE_LIBRARY_WINDOW
, NULL
);
160 g_signal_connect (library_window
,
162 G_CALLBACK (library_window_callback_response
), NULL
);
163 g_signal_connect (G_OBJECT (library_window
), "configure_event",
164 G_CALLBACK (library_window_configure_event_cb
), NULL
);
165 gtk_window_set_default_size (GTK_WINDOW (library_window
),
166 ghidgui
->library_window_width
,
167 ghidgui
->library_window_height
);
169 gtk_window_set_title (GTK_WINDOW (library_window
), _("PCB Library"));
170 gtk_window_set_wmclass (GTK_WINDOW (library_window
), "PCB_Library",
173 gtk_widget_realize (library_window
);
174 if (Settings
.AutoPlace
)
175 gtk_window_move (GTK_WINDOW (library_window
), 10, 10);
177 gtk_editable_select_region (GTK_EDITABLE
178 (GHID_LIBRARY_WINDOW (library_window
)->
179 entry_filter
), 0, -1);
181 /* Set the focus to the filter entry only if it is in the current
183 notebook
= GTK_NOTEBOOK (GHID_LIBRARY_WINDOW (library_window
)->viewtabs
);
184 current_tab
= gtk_notebook_get_nth_page (notebook
,
185 gtk_notebook_get_current_page
188 GTK_WIDGET (GHID_LIBRARY_WINDOW (library_window
)->entry_filter
);
189 if (gtk_widget_is_ancestor (entry_filter
, current_tab
))
191 gtk_widget_grab_focus (entry_filter
);
195 /*! \brief Show the library dialog.
196 * \par Function Description
197 * This function show the library dialog, creating it if it is not
198 * already created, and presents it to the user (brings it to the
202 ghid_library_window_show (GHidPort
* out
, gboolean raise
)
204 ghid_library_window_create (out
);
205 gtk_widget_show_all (library_window
);
207 gtk_window_present (GTK_WINDOW(library_window
));
210 static GObjectClass
*library_window_parent_class
= NULL
;
213 /*! \brief Determines visibility of items of the library treeview.
214 * \par Function Description
215 * This is the function used to filter entries of the footprint
218 * \param [in] model The current selection in the treeview.
219 * \param [in] iter An iterator on a footprint or folder in the tree.
220 * \param [in] data The library dialog.
221 * \returns TRUE if item should be visible, FALSE otherwise.
224 lib_model_filter_visible_func (GtkTreeModel
* model
,
225 GtkTreeIter
* iter
, gpointer data
)
227 GhidLibraryWindow
*library_window
= (GhidLibraryWindow
*) data
;
228 const gchar
*compname
;
229 gchar
*compname_upper
, *text_upper
, *pattern
;
233 g_assert (GHID_IS_LIBRARY_WINDOW (data
));
235 text
= gtk_entry_get_text (library_window
->entry_filter
);
236 if (g_ascii_strcasecmp (text
, "") == 0)
241 /* If this is a source, only display it if it has children that
243 if (gtk_tree_model_iter_has_child (model
, iter
))
247 gtk_tree_model_iter_children (model
, &iter2
, iter
);
251 if (lib_model_filter_visible_func (model
, &iter2
, data
))
257 while (gtk_tree_model_iter_next (model
, &iter2
));
261 gtk_tree_model_get (model
, iter
, MENU_NAME_COLUMN
, &compname
, -1);
262 /* Do a case insensitive comparison, converting the strings
264 compname_upper
= g_ascii_strup (compname
, -1);
265 text_upper
= g_ascii_strup (text
, -1);
266 pattern
= g_strconcat ("*", text_upper
, "*", NULL
);
267 ret
= g_pattern_match_simple (pattern
, compname_upper
);
268 g_free (compname_upper
);
277 /*! \brief Handles activation (e.g. double-clicking) of a component row
278 * \par Function Description
279 * Component row activated handler:
280 * As a convenince to the user, expand / contract any node with children.
282 * \param [in] tree_view The component treeview.
283 * \param [in] path The GtkTreePath to the activated row.
284 * \param [in] column The GtkTreeViewColumn in which the activation occurre
285 * \param [in] user_data The component selection dialog.
288 tree_row_activated (GtkTreeView
*tree_view
,
290 GtkTreeViewColumn
*column
,
296 model
= gtk_tree_view_get_model (tree_view
);
297 gtk_tree_model_get_iter (model
, &iter
, path
);
299 if (!gtk_tree_model_iter_has_child (model
, &iter
))
302 if (gtk_tree_view_row_expanded (tree_view
, path
))
303 gtk_tree_view_collapse_row (tree_view
, path
);
305 gtk_tree_view_expand_row (tree_view
, path
, FALSE
);
308 /*! \brief Handles CTRL-C keypress in the TreeView
309 * \par Function Description
310 * Keypress activation handler:
311 * If CTRL-C is pressed, copy footprint name into the clipboard.
313 * \param [in] tree_view The component treeview.
314 * \param [in] event The GdkEventKey with keypress info.
315 * \param [in] user_data Not used.
316 * \return TRUE if CTRL-C event was handled, FALSE otherwise.
319 tree_row_key_pressed (GtkTreeView
*tree_view
,
323 GtkTreeSelection
*selection
;
326 GtkClipboard
*clipboard
;
327 const gchar
*compname
;
328 guint default_mod_mask
= gtk_accelerator_get_default_mod_mask();
330 /* Handle both lower- and uppercase `c' */
331 if (((event
->state
& default_mod_mask
) != GDK_CONTROL_MASK
)
332 || ((event
->keyval
!= GDK_c
) && (event
->keyval
!= GDK_C
)))
335 selection
= gtk_tree_view_get_selection (tree_view
);
336 g_return_val_if_fail (selection
!= NULL
, TRUE
);
338 if (!gtk_tree_selection_get_selected (selection
, &model
, &iter
))
341 gtk_tree_model_get (model
, &iter
, MENU_NAME_COLUMN
, &compname
, -1);
343 clipboard
= gtk_clipboard_get (GDK_SELECTION_CLIPBOARD
);
344 g_return_val_if_fail (clipboard
!= NULL
, TRUE
);
346 gtk_clipboard_set_text (clipboard
, compname
, -1);
351 /*! \brief Handles changes in the treeview selection.
352 * \par Function Description
353 * This is the callback function that is called every time the user
354 * select a row the library treeview of the dialog.
356 * If the selection is not a selection of a footprint, it does
357 * nothing. Otherwise it updates the preview and Element data.
359 * \param [in] selection The current selection in the treeview.
360 * \param [in] user_data The library dialog.
363 library_window_callback_tree_selection_changed (GtkTreeSelection
* selection
,
368 GhidLibraryWindow
*library_window
= (GhidLibraryWindow
*) user_data
;
369 LibraryEntryType
*entry
= NULL
;
372 if (!gtk_tree_selection_get_selected (selection
, &model
, &iter
))
375 gtk_tree_model_get (model
, &iter
, MENU_ENTRY_COLUMN
, &entry
, -1);
380 /* -1 flags this is an element file part and the file path is in
381 | entry->AllocateMemory.
383 if (entry
->Template
== (char *) -1)
385 if (LoadElementToBuffer (PASTEBUFFER
, entry
->AllocatedMemory
, true))
387 SetMode (PASTEBUFFER_MODE
);
393 /* Otherwise, it's a m4 element and we need to create a string of
394 | macro arguments to be passed to the library command in
395 | LoadElementToBuffer()
397 m4_args
= g_strdup_printf ("'%s' '%s' '%s'", EMPTY (entry
->Template
),
398 EMPTY (entry
->Value
), EMPTY (entry
->Package
));
400 if (LoadElementToBuffer (PASTEBUFFER
, m4_args
, false))
402 SetMode (PASTEBUFFER_MODE
);
412 /* update the preview with new symbol data */
413 g_object_set (library_window
->preview
,
414 "element-data", PASTEBUFFER
->Data
->Element
->data
, NULL
);
417 /*! \brief Requests re-evaluation of the filter.
418 * \par Function Description
419 * This is the timeout function for the filtering of footprint
420 * in the tree of the dialog.
422 * The timeout this callback is attached to is removed after the
425 * \param [in] data The library dialog.
426 * \returns FALSE to remove the timeout.
429 library_window_filter_timeout (gpointer data
)
431 GhidLibraryWindow
*library_window
= GHID_LIBRARY_WINDOW (data
);
434 /* resets the source id in library_window */
435 library_window
->filter_timeout
= 0;
437 model
= gtk_tree_view_get_model (library_window
->libtreeview
);
441 const gchar
*text
= gtk_entry_get_text (library_window
->entry_filter
);
442 gtk_tree_model_filter_refilter ((GtkTreeModelFilter
*) model
);
443 if (strcmp (text
, "") != 0)
445 /* filter text not-empty */
446 gtk_tree_view_expand_all (library_window
->libtreeview
);
448 /* filter text is empty, collapse expanded tree */
449 gtk_tree_view_collapse_all (library_window
->libtreeview
);
453 /* return FALSE to remove the source */
457 /*! \brief Callback function for the changed signal of the filter entry.
458 * \par Function Description
459 * This function monitors changes in the entry filter of the dialog.
461 * It specifically manages the sensitivity of the clear button of the
462 * entry depending on its contents. It also requests an update of the
463 * footprint list by re-evaluating filter at every changes.
465 * \param [in] editable The filter text entry.
466 * \param [in] user_data The library dialog.
469 library_window_callback_filter_entry_changed (GtkEditable
* editable
,
472 GhidLibraryWindow
*library_window
= GHID_LIBRARY_WINDOW (user_data
);
476 /* turns button off if filter entry is empty */
477 /* turns it on otherwise */
478 button
= GTK_WIDGET (library_window
->button_clear
);
480 (g_ascii_strcasecmp (gtk_entry_get_text (library_window
->entry_filter
),
482 gtk_widget_set_sensitive (button
, sensitive
);
484 /* Cancel any pending update of the footprint list filter */
485 if (library_window
->filter_timeout
!= 0)
486 g_source_remove (library_window
->filter_timeout
);
488 /* Schedule an update of the footprint list filter in
489 * LIBRARY_FILTER_INTERVAL milliseconds */
490 library_window
->filter_timeout
= g_timeout_add (LIBRARY_FILTER_INTERVAL
,
491 library_window_filter_timeout
,
496 /*! \brief Handles a click on the clear button.
497 * \par Function Description
498 * This is the callback function called every time the user press the
499 * clear button associated with the filter.
501 * It resets the filter entry, indirectly causing re-evaluation
502 * of the filter on the list of symbols to update the display.
504 * \param [in] editable The filter text entry.
505 * \param [in] user_data The library dialog.
508 library_window_callback_filter_button_clicked (GtkButton
* button
,
511 GhidLibraryWindow
*library_window
= GHID_LIBRARY_WINDOW (user_data
);
513 /* clears text in text entry for filter */
514 gtk_entry_set_text (library_window
->entry_filter
, "");
518 /* \brief Create the tree model for the "Library" view.
519 * \par Function Description
520 * Creates a tree where the branches are the available library
521 * sources and the leaves are the footprints.
523 static GtkTreeModel
*
524 create_lib_tree_model (GhidLibraryWindow
* library_window
)
527 GtkTreeIter iter
, p_iter
, e_iter
, c_iter
;
531 tree
= gtk_tree_store_new (N_MENU_COLUMNS
,
532 G_TYPE_STRING
, G_TYPE_POINTER
, G_TYPE_POINTER
);
534 MENU_LOOP (&Library
);
536 /* Watch for directory changes of library parts and create new
537 | parent iter at each change.
539 if (!menu
->directory
) /* Shouldn't happen */
540 menu
->directory
= g_strdup ("???");
543 if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (tree
), &e_iter
))
546 gtk_tree_model_get (GTK_TREE_MODEL (tree
), &e_iter
,
547 MENU_NAME_COLUMN
, &name
, -1);
548 if (!strcmp (name
, menu
->directory
))
554 while (gtk_tree_model_iter_next (GTK_TREE_MODEL (tree
), &e_iter
));
560 gtk_tree_store_append (tree
, &p_iter
, NULL
);
561 gtk_tree_store_set (tree
, &p_iter
,
562 MENU_NAME_COLUMN
, menu
->directory
,
563 MENU_LIBRARY_COLUMN
, NULL
,
564 MENU_ENTRY_COLUMN
, NULL
, -1);
566 gtk_tree_store_append (tree
, &iter
, &p_iter
);
567 gtk_tree_store_set (tree
, &iter
,
568 MENU_NAME_COLUMN
, menu
->Name
,
569 MENU_LIBRARY_COLUMN
, menu
,
570 MENU_ENTRY_COLUMN
, NULL
, -1);
573 gtk_tree_store_append (tree
, &c_iter
, &iter
);
574 gtk_tree_store_set (tree
, &c_iter
,
575 MENU_NAME_COLUMN
, entry
->ListEntry
,
576 MENU_LIBRARY_COLUMN
, menu
,
577 MENU_ENTRY_COLUMN
, entry
, -1);
584 return (GtkTreeModel
*) tree
;
589 /* \brief On-demand refresh of the footprint library.
590 * \par Function Description
591 * Requests a rescan of the footprint library in order to pick up any
592 * new signals, and then updates the library window.
595 library_window_callback_refresh_library (GtkButton
* button
,
598 GhidLibraryWindow
*library_window
= GHID_LIBRARY_WINDOW (user_data
);
601 /* Rescan the libraries for symbols */
602 /* TODO: How do we do this in PCB? */
604 /* Refresh the "Library" view */
605 model
= (GtkTreeModel
*)
606 g_object_new (GTK_TYPE_TREE_MODEL_FILTER
,
607 "child-model", create_lib_tree_model (library_window
),
608 "virtual-root", NULL
, NULL
);
610 gtk_tree_model_filter_set_visible_func ((GtkTreeModelFilter
*) model
,
611 lib_model_filter_visible_func
,
612 library_window
, NULL
);
614 gtk_tree_view_set_model (library_window
->libtreeview
, model
);
619 /*! \brief Creates the treeview for the "Library" view */
621 create_lib_treeview (GhidLibraryWindow
* library_window
)
623 GtkWidget
*libtreeview
, *vbox
, *scrolled_win
, *label
,
624 *hbox
, *entry
, *button
;
625 GtkTreeModel
*child_model
, *model
;
626 GtkTreeSelection
*selection
;
627 GtkCellRenderer
*renderer
;
628 GtkTreeViewColumn
*column
;
630 /* -- library selection view -- */
632 /* vertical box for footprint selection and search entry */
633 vbox
= GTK_WIDGET (g_object_new (GTK_TYPE_VBOX
,
637 "homogeneous", FALSE
, "spacing", 5, NULL
));
639 child_model
= create_lib_tree_model (library_window
);
640 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (child_model
),
641 MENU_NAME_COLUMN
, GTK_SORT_ASCENDING
);
642 model
= (GtkTreeModel
*) g_object_new (GTK_TYPE_TREE_MODEL_FILTER
,
643 "child-model", child_model
,
644 "virtual-root", NULL
, NULL
);
646 scrolled_win
= GTK_WIDGET (g_object_new (GTK_TYPE_SCROLLED_WINDOW
,
647 /* GtkScrolledWindow */
649 GTK_POLICY_AUTOMATIC
,
651 GTK_POLICY_ALWAYS
, "shadow-type",
652 GTK_SHADOW_ETCHED_IN
, NULL
));
653 /* create the treeview */
654 libtreeview
= GTK_WIDGET (g_object_new (GTK_TYPE_TREE_VIEW
,
658 "headers-visible", FALSE
, NULL
));
660 g_signal_connect (libtreeview
,
662 G_CALLBACK (tree_row_activated
),
665 g_signal_connect (libtreeview
,
667 G_CALLBACK (tree_row_key_pressed
),
670 /* connect callback to selection */
671 selection
= gtk_tree_view_get_selection (GTK_TREE_VIEW (libtreeview
));
672 gtk_tree_selection_set_mode (selection
, GTK_SELECTION_SINGLE
);
673 g_signal_connect (selection
,
676 (library_window_callback_tree_selection_changed
),
679 /* insert a column to treeview for library/symbol name */
680 renderer
= GTK_CELL_RENDERER (g_object_new (GTK_TYPE_CELL_RENDERER_TEXT
,
681 /* GtkCellRendererText */
682 "editable", FALSE
, NULL
));
683 column
= GTK_TREE_VIEW_COLUMN (g_object_new (GTK_TYPE_TREE_VIEW_COLUMN
,
684 /* GtkTreeViewColumn */
685 "title", _("Components"),
687 gtk_tree_view_column_pack_start (column
, renderer
, TRUE
);
688 gtk_tree_view_column_set_attributes (column
, renderer
,
689 "text", MENU_NAME_COLUMN
, NULL
);
690 gtk_tree_view_append_column (GTK_TREE_VIEW (libtreeview
), column
);
692 /* add the treeview to the scrolled window */
693 gtk_container_add (GTK_CONTAINER (scrolled_win
), libtreeview
);
694 /* set directory/footprint treeview of library_window */
695 library_window
->libtreeview
= GTK_TREE_VIEW (libtreeview
);
697 /* add the scrolled window for directories to the vertical box */
698 gtk_box_pack_start (GTK_BOX (vbox
), scrolled_win
, TRUE
, TRUE
, 0);
701 /* -- filter area -- */
702 hbox
= GTK_WIDGET (g_object_new (GTK_TYPE_HBOX
,
704 "homogeneous", FALSE
, "spacing", 3, NULL
));
706 /* create the entry label */
707 label
= GTK_WIDGET (g_object_new (GTK_TYPE_LABEL
,
711 "label", _("Filter:"), NULL
));
712 /* add the search label to the filter area */
713 gtk_box_pack_start (GTK_BOX (hbox
), label
, FALSE
, FALSE
, 0);
715 /* create the text entry for filter in footprints */
716 entry
= GTK_WIDGET (g_object_new (GTK_TYPE_ENTRY
,
719 g_signal_connect (entry
,
721 G_CALLBACK (library_window_callback_filter_entry_changed
),
724 /* now that that we have an entry, set the filter func of model */
725 gtk_tree_model_filter_set_visible_func ((GtkTreeModelFilter
*) model
,
726 lib_model_filter_visible_func
,
727 library_window
, NULL
);
729 /* add the filter entry to the filter area */
730 gtk_box_pack_start (GTK_BOX (hbox
), entry
, TRUE
, TRUE
, 0);
731 /* set filter entry of library_window */
732 library_window
->entry_filter
= GTK_ENTRY (entry
);
733 /* and init the event source for footprint filter */
734 library_window
->filter_timeout
= 0;
736 /* create the erase button for filter entry */
737 button
= GTK_WIDGET (g_object_new (GTK_TYPE_BUTTON
,
741 "relief", GTK_RELIEF_NONE
, NULL
));
743 gtk_container_add (GTK_CONTAINER (button
),
744 gtk_image_new_from_stock (GTK_STOCK_CLEAR
,
745 GTK_ICON_SIZE_SMALL_TOOLBAR
));
746 g_signal_connect (button
,
749 (library_window_callback_filter_button_clicked
),
751 /* add the clear button to the filter area */
752 gtk_box_pack_start (GTK_BOX (hbox
), button
, FALSE
, FALSE
, 0);
753 /* set clear button of library_window */
754 library_window
->button_clear
= GTK_BUTTON (button
);
757 /* create the refresh button */
758 button
= GTK_WIDGET (g_object_new (GTK_TYPE_BUTTON
,
762 "relief", GTK_RELIEF_NONE
, NULL
));
763 gtk_container_add (GTK_CONTAINER (button
),
764 gtk_image_new_from_stock (GTK_STOCK_REFRESH
,
765 GTK_ICON_SIZE_SMALL_TOOLBAR
));
766 /* add the refresh button to the filter area */
767 gtk_box_pack_start (GTK_BOX (hbox
), button
, FALSE
, FALSE
, 0);
768 g_signal_connect (button
,
770 G_CALLBACK (library_window_callback_refresh_library
),
774 /* add the filter area to the vertical box */
775 gtk_box_pack_start (GTK_BOX (vbox
), hbox
, FALSE
, FALSE
, 0);
777 library_window
->libtreeview
= GTK_TREE_VIEW (libtreeview
);
784 library_window_constructor (GType type
,
785 guint n_construct_properties
,
786 GObjectConstructParam
* construct_params
)
789 GhidLibraryWindow
*library_window
;
790 GtkWidget
*content_area
;
791 GtkWidget
*hpaned
, *notebook
;
794 GtkWidget
*alignment
, *frame
;
796 /* chain up to constructor of parent class */
797 object
= G_OBJECT_CLASS (library_window_parent_class
)->
798 constructor (type
, n_construct_properties
, construct_params
);
799 library_window
= GHID_LIBRARY_WINDOW (object
);
801 /* dialog initialization */
802 g_object_set (object
,
804 "type", GTK_WINDOW_TOPLEVEL
,
805 "title", _("Select Footprint..."),
806 "default-height", 300,
807 "default-width", 400,
808 "modal", FALSE
, "window-position", GTK_WIN_POS_NONE
,
810 "has-separator", TRUE
, NULL
);
811 g_object_set (gtk_dialog_get_content_area (GTK_DIALOG (library_window
)),
812 "homogeneous", FALSE
, NULL
);
814 /* horizontal pane containing selection and preview */
815 hpaned
= GTK_WIDGET (g_object_new (GTK_TYPE_HPANED
,
817 "border-width", 5, NULL
));
818 library_window
->hpaned
= hpaned
;
820 /* notebook for library views */
821 notebook
= GTK_WIDGET (g_object_new (GTK_TYPE_NOTEBOOK
,
822 "show-tabs", FALSE
, NULL
));
823 library_window
->viewtabs
= GTK_NOTEBOOK (notebook
);
825 libview
= create_lib_treeview (library_window
);
826 gtk_notebook_append_page (GTK_NOTEBOOK (notebook
), libview
,
827 gtk_label_new (_("Libraries")));
829 /* include the vertical box in horizontal box */
830 gtk_paned_pack1 (GTK_PANED (hpaned
), notebook
, TRUE
, FALSE
);
833 /* -- preview area -- */
834 frame
= GTK_WIDGET (g_object_new (GTK_TYPE_FRAME
,
836 "label", _("Preview"), NULL
));
837 alignment
= GTK_WIDGET (g_object_new (GTK_TYPE_ALIGNMENT
,
845 "xalign", 0.5, "yalign", 0.5, NULL
));
846 preview
= (GtkWidget
*)g_object_new (GHID_TYPE_PINOUT_PREVIEW
,
847 /* GhidPinoutPreview */
848 "element-data", NULL
,
850 "width-request", 150, "height-request", 150, NULL
);
851 gtk_container_add (GTK_CONTAINER (alignment
), preview
);
852 gtk_container_add (GTK_CONTAINER (frame
), alignment
);
853 /* set preview of library_window */
854 library_window
->preview
= preview
;
856 gtk_paned_pack2 (GTK_PANED (hpaned
), frame
, FALSE
, FALSE
);
858 /* add the hpaned to the dialog content area */
859 content_area
= gtk_dialog_get_content_area (GTK_DIALOG (library_window
));
860 gtk_box_pack_start (GTK_BOX (content_area
), hpaned
, TRUE
, TRUE
, 0);
861 gtk_widget_show_all (hpaned
);
864 /* now add buttons in the action area */
865 gtk_dialog_add_buttons (GTK_DIALOG (library_window
),
867 GTK_STOCK_CLOSE
, GTK_RESPONSE_CLOSE
, NULL
);
873 library_window_finalize (GObject
* object
)
875 GhidLibraryWindow
*library_window
= GHID_LIBRARY_WINDOW (object
);
877 if (library_window
->filter_timeout
!= 0)
879 g_source_remove (library_window
->filter_timeout
);
880 library_window
->filter_timeout
= 0;
883 G_OBJECT_CLASS (library_window_parent_class
)->finalize (object
);
888 library_window_class_init (GhidLibraryWindowClass
* klass
)
890 GObjectClass
*gobject_class
= G_OBJECT_CLASS (klass
);
892 gobject_class
->constructor
= library_window_constructor
;
893 gobject_class
->finalize
= library_window_finalize
;
895 library_window_parent_class
= (GObjectClass
*)g_type_class_peek_parent (klass
);
900 ghid_library_window_get_type ()
902 static GType library_window_type
= 0;
904 if (!library_window_type
)
906 static const GTypeInfo library_window_info
= {
907 sizeof (GhidLibraryWindowClass
),
908 NULL
, /* base_init */
909 NULL
, /* base_finalize */
910 (GClassInitFunc
) library_window_class_init
,
911 NULL
, /* class_finalize */
912 NULL
, /* class_data */
913 sizeof (GhidLibraryWindow
),
915 NULL
/* instance_init */
918 library_window_type
= g_type_register_static (GTK_TYPE_DIALOG
,
920 &library_window_info
, (GTypeFlags
)0);
923 return library_window_type
;