missing NULL terminator in set_config_x
[geda-gaf.git] / gschem / src / gschem_find_text_widget.c
blob7f627f35edd4d9cd390c39e55983984e48f53e65
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
20 /*!
21 * \file gschem_find_text_widget.c
23 * \brief A widget for finding text
26 #include <config.h>
28 #include <stdio.h>
29 #ifdef HAVE_STDLIB_H
30 #include <stdlib.h>
31 #endif
32 #ifdef HAVE_STRING_H
33 #include <string.h>
34 #endif
35 #ifdef HAVE_MATH_H
36 #include <math.h>
37 #endif
39 #include <gdk/gdkkeysyms.h>
41 #include "gschem.h"
43 #include "../include/gschem_find_text_dockable.h"
47 /*! \brief The columns in the GtkListStore
49 enum
51 COLUMN_NAME,
52 COLUMN_INDEX,
53 COLUMN_COUNT
57 enum
59 PROP_0,
60 PROP_DESCEND,
61 PROP_FIND_TEXT_STRING,
62 PROP_FIND_TYPE
68 static gboolean
69 key_press_event (GtkWidget *widget, GdkEventKey *event, gpointer user_data);
71 static void
72 activate_entry (GtkWidget *entry, GschemFindTextWidget *widget);
74 static void
75 click_cancel (GtkWidget *button, GschemFindTextWidget *widget);
77 static void
78 click_find (GtkWidget *entry, GschemFindTextWidget *widget);
80 static GtkListStore*
81 create_find_type_store ();
83 static void
84 dispose (GObject *object);
86 static void
87 finalize (GObject *object);
89 static void
90 get_property (GObject *object, guint param_id, GValue *value, GParamSpec *pspec);
92 static void
93 gschem_find_text_widget_class_init (GschemFindTextWidgetClass *klass);
95 static void
96 gschem_find_text_widget_init (GschemFindTextWidget *view);
98 static void
99 set_property (GObject *object, guint param_id, const GValue *value, GParamSpec *pspec);
101 static void
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
112 static gboolean
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);
118 return TRUE;
121 return FALSE;
126 /* Callback for when the user presses enter in the entry widget
128 static void
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);
136 else {
137 gtk_info_bar_response (GTK_INFO_BAR (widget), GTK_RESPONSE_CANCEL);
143 /* Callback for when the user clicks the cancel button
145 static void
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
155 static void
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
169 static void
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
182 static void
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)
198 OBJECT *object;
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
220 * \param [in] object
221 * \param [in] param_id
222 * \param [in,out] value
223 * \param [in] pspec
225 static void
226 get_property (GObject *object, guint param_id, GValue *value, GParamSpec *pspec)
228 GschemFindTextWidget *widget = GSCHEM_FIND_TEXT_WIDGET (object);
230 switch (param_id) {
231 case PROP_DESCEND:
232 g_value_set_boolean (value, gschem_find_text_widget_get_descend (widget));
233 break;
235 case PROP_FIND_TEXT_STRING:
236 g_value_set_string (value, gschem_find_text_widget_get_find_text_string (widget));
237 break;
239 case PROP_FIND_TYPE:
240 g_value_set_int (value, gschem_find_text_widget_get_find_type (widget));
241 break;
243 default:
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
254 static void
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),
266 PROP_DESCEND,
267 g_param_spec_boolean ("descend",
268 "Descend",
269 "Descend",
270 FALSE,
271 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
273 g_object_class_install_property (G_OBJECT_CLASS (klass),
274 PROP_FIND_TYPE,
275 g_param_spec_int ("find-type",
276 "Find Type",
277 "Find Type",
280 FIND_TYPE_SUBSTRING,
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",
286 "Find Text String",
287 "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
312 * \return The entry
314 GtkWidget*
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)
332 int index = -1;
333 GtkTreeIter iter;
334 GValue value = {0};
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);
344 return index;
349 /*! \brief Get the find text string
351 * \param [in] widget This GschemFindTextWidget
352 * \return The find text string
354 const char*
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.
366 GType
367 gschem_find_text_widget_get_type ()
369 static GType type = 0;
371 if (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),
380 0, /* n_preallocs */
381 (GInstanceInitFunc) gschem_find_text_widget_init,
384 type = g_type_register_static (GTK_TYPE_INFO_BAR, "GschemFindTextWidget", &info, 0);
387 return type;
392 /*! \brief Initialize GschemFindTextWidget instance
394 * \param [in,out] view the GschemFindTextWidget
396 static void
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),
444 "key-press-event",
445 G_CALLBACK (key_press_event),
446 widget);
448 g_signal_connect (G_OBJECT (widget->entry),
449 "activate",
450 G_CALLBACK (activate_entry),
451 widget);
453 g_signal_connect (G_OBJECT (cancel_button),
454 "clicked",
455 G_CALLBACK (click_cancel),
456 widget);
458 g_signal_connect (G_OBJECT (widget->find_button),
459 "clicked",
460 G_CALLBACK (click_find),
461 widget);
463 g_signal_connect (G_OBJECT (widget->entry),
464 "notify::text",
465 G_CALLBACK (notify_entry_text),
466 widget);
471 /*! \brief Set descend
473 * \param [in,out] view This GschemFindTextWidget
474 * \param [in] text The label text
476 void
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
493 void
494 gschem_find_text_widget_set_find_type (GschemFindTextWidget *widget, int type)
496 GtkTreeIter *active = NULL;
497 GtkTreeIter iter;
499 g_return_if_fail (widget != NULL);
501 if (type >= 0) {
502 gboolean success;
503 GValue value = {0};
505 success = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (widget->find_type_model), &iter);
506 while (success) {
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);
510 active = &iter;
511 break;
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
530 void
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");
541 static GtkListStore*
542 create_find_type_store ()
544 GtkTreeIter iter;
545 GtkListStore *store;
547 store = gtk_list_store_new (COLUMN_COUNT,
548 G_TYPE_STRING,
549 G_TYPE_INT);
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,
572 return store;
576 /*! \brief Update the sensitivity of the find button
578 static void
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
591 static void
592 set_property (GObject *object, guint param_id, const GValue *value, GParamSpec *pspec)
594 GschemFindTextWidget *widget = GSCHEM_FIND_TEXT_WIDGET (object);
596 switch (param_id) {
597 case PROP_DESCEND:
598 gschem_find_text_widget_set_descend (widget, g_value_get_boolean (value));
599 break;
601 case PROP_FIND_TEXT_STRING:
602 gschem_find_text_widget_set_find_text_string (widget, g_value_get_string (value));
603 break;
605 case PROP_FIND_TYPE:
606 gschem_find_text_widget_set_find_type (widget, g_value_get_int (value));
607 break;
609 default:
610 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);