1 /* gEDA - GPL Electronic Design Automation
2 * gschem - gEDA Schematic Capture
3 * Copyright (C) 1998-2010 Ales Hvezda
4 * Copyright (C) 1998-2020 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
21 * \file gschem_find_text_widget.c
23 * \brief A widget for finding text
39 #include <gdk/gdkkeysyms.h>
43 #include "../include/gschem_find_text_dockable.h"
47 /*! \brief The columns in the GtkListStore
61 PROP_FIND_TEXT_STRING
,
69 key_press_event (GtkWidget
*widget
, GdkEventKey
*event
, gpointer user_data
);
72 activate_entry (GtkWidget
*entry
, GschemFindTextWidget
*widget
);
75 click_cancel (GtkWidget
*button
, GschemFindTextWidget
*widget
);
78 click_find (GtkWidget
*entry
, GschemFindTextWidget
*widget
);
81 create_find_type_store ();
84 dispose (GObject
*object
);
87 finalize (GObject
*object
);
90 get_property (GObject
*object
, guint param_id
, GValue
*value
, GParamSpec
*pspec
);
93 gschem_find_text_widget_class_init (GschemFindTextWidgetClass
*klass
);
96 gschem_find_text_widget_init (GschemFindTextWidget
*view
);
99 set_property (GObject
*object
, guint param_id
, const GValue
*value
, GParamSpec
*pspec
);
102 notify_entry_text (GtkWidget
*entry
, GParamSpec
*pspec
, GschemFindTextWidget
*widget
);
106 static GObjectClass
*gschem_find_text_widget_parent_class
= NULL
;
110 /* Callback for when the user presses a key in the infobar
113 key_press_event (GtkWidget
*widget
, GdkEventKey
*event
, gpointer user_data
)
115 if (event
->keyval
== GDK_KEY_Escape
&&
116 (event
->state
& gtk_accelerator_get_default_mod_mask ()) == 0) {
117 gtk_info_bar_response (GTK_INFO_BAR (user_data
), GTK_RESPONSE_CANCEL
);
126 /* Callback for when the user presses enter in the entry widget
129 activate_entry (GtkWidget
*entry
, GschemFindTextWidget
*widget
)
131 g_return_if_fail (widget
!= NULL
);
133 if (gtk_entry_get_text_length (GTK_ENTRY (widget
->entry
)) > 0) {
134 gtk_info_bar_response (GTK_INFO_BAR (widget
), GTK_RESPONSE_OK
);
137 gtk_info_bar_response (GTK_INFO_BAR (widget
), GTK_RESPONSE_CANCEL
);
143 /* Callback for when the user clicks the cancel button
146 click_cancel (GtkWidget
*button
, GschemFindTextWidget
*widget
)
148 gtk_info_bar_response (GTK_INFO_BAR (widget
), GTK_RESPONSE_CANCEL
);
153 /* Callback for when the user clicks the find button
156 click_find (GtkWidget
*entry
, GschemFindTextWidget
*widget
)
158 g_return_if_fail (widget
!= NULL
);
160 if (gtk_entry_get_text_length (GTK_ENTRY (widget
->entry
)) > 0) {
161 gtk_info_bar_response (GTK_INFO_BAR (widget
), GTK_RESPONSE_OK
);
167 /*! \brief Dispose of the object
170 dispose (GObject
*object
)
172 /* lastly, chain up to the parent dispose */
174 g_return_if_fail (gschem_find_text_widget_parent_class
!= NULL
);
175 gschem_find_text_widget_parent_class
->dispose (object
);
180 /*! \brief Finalize object
183 finalize (GObject
*object
)
185 /* lastly, chain up to the parent finalize */
187 g_return_if_fail (gschem_find_text_widget_parent_class
!= NULL
);
188 gschem_find_text_widget_parent_class
->finalize (object
);
192 /*! \brief Create the text find dialog
193 * \par Function Description
194 * This function creates the text find dialog.
196 void find_text_dialog (GschemToplevel
*w_current
)
200 g_return_if_fail (w_current
!= NULL
);
201 g_return_if_fail (w_current
->toplevel
!= NULL
);
203 object
= o_select_return_first_object(w_current
);
205 if ((object
!= NULL
) && (object
->type
== OBJ_TEXT
)) {
206 gschem_find_text_widget_set_find_text_string(
207 GSCHEM_FIND_TEXT_WIDGET (w_current
->find_text_widget
),
208 o_text_get_string (w_current
->toplevel
, object
)
212 gtk_widget_show (GTK_WIDGET (w_current
->find_text_widget
));
213 gtk_widget_grab_focus (gschem_find_text_widget_get_entry (GSCHEM_FIND_TEXT_WIDGET (w_current
->find_text_widget
)));
214 gtk_editable_select_region (GTK_EDITABLE (gschem_find_text_widget_get_entry (GSCHEM_FIND_TEXT_WIDGET (w_current
->find_text_widget
))), 0, -1);
218 /*! \brief Get a property
221 * \param [in] param_id
222 * \param [in,out] value
226 get_property (GObject
*object
, guint param_id
, GValue
*value
, GParamSpec
*pspec
)
228 GschemFindTextWidget
*widget
= GSCHEM_FIND_TEXT_WIDGET (object
);
232 g_value_set_boolean (value
, gschem_find_text_widget_get_descend (widget
));
235 case PROP_FIND_TEXT_STRING
:
236 g_value_set_string (value
, gschem_find_text_widget_get_find_text_string (widget
));
240 g_value_set_int (value
, gschem_find_text_widget_get_find_type (widget
));
244 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, param_id
, pspec
);
250 /*! \brief Initialize GschemFindTextWidget class
252 * \param [in] klass The class for the GschemFindTextWidget
255 gschem_find_text_widget_class_init (GschemFindTextWidgetClass
*klass
)
257 gschem_find_text_widget_parent_class
= G_OBJECT_CLASS (g_type_class_peek_parent (klass
));
259 G_OBJECT_CLASS (klass
)->dispose
= dispose
;
260 G_OBJECT_CLASS (klass
)->finalize
= finalize
;
262 G_OBJECT_CLASS (klass
)->get_property
= get_property
;
263 G_OBJECT_CLASS (klass
)->set_property
= set_property
;
265 g_object_class_install_property (G_OBJECT_CLASS (klass
),
267 g_param_spec_boolean ("descend",
271 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
));
273 g_object_class_install_property (G_OBJECT_CLASS (klass
),
275 g_param_spec_int ("find-type",
281 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
));
283 g_object_class_install_property (G_OBJECT_CLASS (klass
),
284 PROP_FIND_TEXT_STRING
,
285 g_param_spec_string ("find-text-string",
289 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
));
294 /*! \brief Get the descend property
296 * \param [in] widget This GschemFindTextWidget
297 * \return The descend property
300 gschem_find_text_widget_get_descend (GschemFindTextWidget
*widget
)
302 g_return_val_if_fail (widget
!= NULL
, FALSE
);
304 return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget
->descend_button
));
309 /*! \brief Get the entry
311 * \param [in] widget This GschemFindTextWidget
315 gschem_find_text_widget_get_entry (GschemFindTextWidget
*widget
)
317 g_return_val_if_fail (widget
!= NULL
, NULL
);
319 return widget
->entry
;
324 /*! \brief Get the type of find to perform
326 * \param [in] widget This GschemFindTextWidget
327 * \return The find type
330 gschem_find_text_widget_get_find_type (GschemFindTextWidget
*widget
)
336 g_return_val_if_fail (widget
!= NULL
, 0);
338 if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget
->combo
), &iter
)) {
339 gtk_tree_model_get_value (GTK_TREE_MODEL (widget
->find_type_model
), &iter
, COLUMN_INDEX
, &value
);
340 index
= g_value_get_int (&value
);
341 g_value_unset (&value
);
349 /*! \brief Get the find text string
351 * \param [in] widget This GschemFindTextWidget
352 * \return The find text string
355 gschem_find_text_widget_get_find_text_string (GschemFindTextWidget
*widget
)
357 g_return_val_if_fail (widget
!= NULL
, NULL
);
359 return gtk_entry_get_text (GTK_ENTRY (widget
->entry
));
364 /*! \brief Get/register GschemFindTextWidget type.
367 gschem_find_text_widget_get_type ()
369 static GType type
= 0;
372 static const GTypeInfo info
= {
373 sizeof(GschemFindTextWidgetClass
),
374 NULL
, /* base_init */
375 NULL
, /* base_finalize */
376 (GClassInitFunc
) gschem_find_text_widget_class_init
,
377 NULL
, /* class_finalize */
378 NULL
, /* class_data */
379 sizeof(GschemFindTextWidget
),
381 (GInstanceInitFunc
) gschem_find_text_widget_init
,
384 type
= g_type_register_static (GTK_TYPE_INFO_BAR
, "GschemFindTextWidget", &info
, 0);
392 /*! \brief Initialize GschemFindTextWidget instance
394 * \param [in,out] view the GschemFindTextWidget
397 gschem_find_text_widget_init (GschemFindTextWidget
*widget
)
399 GtkWidget
*action
= gtk_info_bar_get_action_area (GTK_INFO_BAR (widget
));
400 GtkWidget
*button_box
;
401 GtkWidget
*cancel_button
;
402 GtkWidget
*content
= gtk_info_bar_get_content_area (GTK_INFO_BAR (widget
));
403 GtkCellRenderer
*text_cell
;
405 g_return_if_fail (widget
!= NULL
);
407 gtk_widget_set_no_show_all (GTK_WIDGET (widget
), TRUE
);
409 widget
->find_type_model
= GTK_TREE_MODEL (create_find_type_store ());
410 widget
->combo
= gtk_combo_box_new_with_model (widget
->find_type_model
);
411 gtk_widget_set_visible (widget
->combo
, TRUE
);
412 gtk_box_pack_start (GTK_BOX (content
), widget
->combo
, FALSE
, FALSE
, 0);
414 text_cell
= GTK_CELL_RENDERER (gtk_cell_renderer_text_new());
415 g_object_set (text_cell
, "xpad", 5, NULL
);
416 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (widget
->combo
), text_cell
, TRUE
);
417 gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (widget
->combo
), text_cell
, "text", COLUMN_NAME
);
419 widget
->entry
= gtk_entry_new ();
420 gtk_widget_set_visible (widget
->entry
, TRUE
);
421 gtk_box_pack_start (GTK_BOX (content
), widget
->entry
, TRUE
, TRUE
, 0);
423 widget
->descend_button
= gtk_check_button_new_with_label(_("descend into hierarchy"));
424 gtk_widget_set_visible (widget
->descend_button
, TRUE
);
425 gtk_box_pack_start (GTK_BOX (content
), widget
->descend_button
, FALSE
, FALSE
, 0);
427 button_box
= gtk_hbutton_box_new ();
428 gtk_widget_set_visible (button_box
, TRUE
);
429 gtk_box_pack_start (GTK_BOX (content
), button_box
, FALSE
, FALSE
, 0);
431 widget
->find_button
= gtk_button_new_with_label (pgettext ("actuate", "Find"));
432 gtk_widget_set_sensitive (widget
->find_button
, FALSE
);
433 gtk_widget_set_visible (widget
->find_button
, TRUE
);
434 gtk_box_pack_start (GTK_BOX (button_box
), widget
->find_button
, FALSE
, FALSE
, 0);
436 cancel_button
= gtk_button_new_from_stock (GTK_STOCK_CANCEL
);
437 gtk_widget_set_visible (cancel_button
, TRUE
);
438 gtk_box_pack_start (GTK_BOX (button_box
), cancel_button
, FALSE
, FALSE
, 0);
440 gtk_widget_set_no_show_all (action
, TRUE
);
441 gtk_widget_set_visible (action
, FALSE
);
443 g_signal_connect (G_OBJECT (widget
),
445 G_CALLBACK (key_press_event
),
448 g_signal_connect (G_OBJECT (widget
->entry
),
450 G_CALLBACK (activate_entry
),
453 g_signal_connect (G_OBJECT (cancel_button
),
455 G_CALLBACK (click_cancel
),
458 g_signal_connect (G_OBJECT (widget
->find_button
),
460 G_CALLBACK (click_find
),
463 g_signal_connect (G_OBJECT (widget
->entry
),
465 G_CALLBACK (notify_entry_text
),
471 /*! \brief Set descend
473 * \param [in,out] view This GschemFindTextWidget
474 * \param [in] text The label text
477 gschem_find_text_widget_set_descend (GschemFindTextWidget
*widget
, int descend
)
479 g_return_if_fail (widget
!= NULL
);
481 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget
->descend_button
), descend
);
483 g_object_notify (G_OBJECT (widget
), "descend");
488 /*! \brief Set the type of find to perform
490 * \param [in,out] view This GschemFindTextWidget
491 * \param [in] text The label text
494 gschem_find_text_widget_set_find_type (GschemFindTextWidget
*widget
, int type
)
496 GtkTreeIter
*active
= NULL
;
499 g_return_if_fail (widget
!= NULL
);
505 success
= gtk_tree_model_get_iter_first (GTK_TREE_MODEL (widget
->find_type_model
), &iter
);
507 gtk_tree_model_get_value (GTK_TREE_MODEL (widget
->find_type_model
), &iter
, COLUMN_INDEX
, &value
);
508 if (g_value_get_int (&value
) == type
) {
509 g_value_unset (&value
);
513 g_value_unset (&value
);
514 success
= gtk_tree_model_iter_next (GTK_TREE_MODEL(widget
->find_type_model
), &iter
);
518 gtk_combo_box_set_active_iter (GTK_COMBO_BOX(widget
->combo
), active
);
520 g_object_notify (G_OBJECT (widget
), "find-type");
525 /*! \brief Set the find text string
527 * \param [in,out] view This GschemFindTextWidget
528 * \param [in] str The find text string
531 gschem_find_text_widget_set_find_text_string (GschemFindTextWidget
*widget
, const char *str
)
533 g_return_if_fail (widget
!= NULL
);
535 gtk_entry_set_text (GTK_ENTRY (widget
->entry
), str
);
537 g_object_notify (G_OBJECT (widget
), "find-text-string");
542 create_find_type_store ()
547 store
= gtk_list_store_new (COLUMN_COUNT
,
551 gtk_list_store_append (store
, &iter
);
552 gtk_list_store_set (store
, &iter
,
553 COLUMN_NAME
, _("Find Text:"),
554 COLUMN_INDEX
, FIND_TYPE_SUBSTRING
,
558 gtk_list_store_append (store
, &iter
);
559 gtk_list_store_set (store
, &iter
,
560 COLUMN_NAME
, _("Find Pattern:"),
561 COLUMN_INDEX
, FIND_TYPE_PATTERN
,
565 gtk_list_store_append (store
, &iter
);
566 gtk_list_store_set (store
, &iter
,
567 COLUMN_NAME
, _("Find Regex:"),
568 COLUMN_INDEX
, FIND_TYPE_REGEX
,
576 /*! \brief Update the sensitivity of the find button
579 notify_entry_text (GtkWidget
*entry
, GParamSpec
*pspec
, GschemFindTextWidget
*widget
)
581 g_return_if_fail (widget
!= NULL
);
583 gtk_widget_set_sensitive (widget
->find_button
,
584 (gtk_entry_get_text_length (GTK_ENTRY (widget
->entry
)) > 0));
589 /*! \brief Set a gobject property
592 set_property (GObject
*object
, guint param_id
, const GValue
*value
, GParamSpec
*pspec
)
594 GschemFindTextWidget
*widget
= GSCHEM_FIND_TEXT_WIDGET (object
);
598 gschem_find_text_widget_set_descend (widget
, g_value_get_boolean (value
));
601 case PROP_FIND_TEXT_STRING
:
602 gschem_find_text_widget_set_find_text_string (widget
, g_value_get_string (value
));
606 gschem_find_text_widget_set_find_type (widget
, g_value_get_int (value
));
610 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, param_id
, pspec
);