1 /* gEDA - GPL Electronic Design Automation
2 * gschem - gEDA Schematic Capture
3 * Copyright (C) 2013 Ales Hvezda
4 * Copyright (C) 2013-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
23 * \brief A dialog box for adding new text to a schematic.
37 #include <gdk/gdkkeysyms.h>
41 #define TYPE_NEWTEXT (newtext_get_type())
42 #define NEWTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_NEWTEXT, NewText))
43 #define NEWTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_NEWTEXT, NewTextClass))
44 #define IS_NEWTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_NEWTEXT))
46 typedef struct _NewTextClass NewTextClass
;
47 typedef struct _NewText NewText
;
49 struct _NewTextClass
{
50 GschemDialogClass parent_class
;
59 GtkWidget
*textsizecb
;
65 /*! \brief Handles the user response when apply is selected
67 * \par Function Description
68 * This function applies the text from the text entry dialog.
70 * \param [in] dialog The new text dialog
73 dialog_response_apply (NewText
*dialog
)
75 int align
= LOWER_LEFT
;
76 int color
= TEXT_COLOR
;
81 GtkTextBuffer
*textbuffer
;
82 GtkTextIter start
, end
;
85 textbuffer
= gtk_text_view_get_buffer(GTK_TEXT_VIEW(dialog
->text_view
));
86 gtk_text_buffer_get_bounds (textbuffer
, &start
, &end
);
87 string
= gtk_text_iter_get_text (&start
, &end
);
89 if (string
[0] == '\0' )
92 switch(dialog
->parent
.w_current
->text_caps
) {
94 tmp
= g_utf8_strdown (string
, -1);
98 tmp
= g_utf8_strup (string
, -1);
107 value
= x_colorcb_get_index (dialog
->colorcb
);
112 value
= gschem_alignment_combo_get_align (dialog
->aligncb
);
117 value
= gschem_integer_combo_box_get_value (dialog
->textsizecb
);
122 value
= gschem_rotation_combo_get_angle (dialog
->rotatecb
);
127 /* select the text, so you can continue immediatly writing the next text */
128 select_all_text_in_textview(GTK_TEXT_VIEW(dialog
->text_view
));
129 gtk_widget_grab_focus(dialog
->text_view
);
131 o_text_prepare_place (dialog
->parent
.w_current
,
132 tmp
== NULL
? string
: tmp
,
138 //gschem_toplevel_page_content_changed (dialog->parent.w_current,
139 // dialog->parent.w_current->toplevel->page_current);
147 /*! \brief Handles the user response when cancel is selected
151 * \param [in,out] dialog The new text dialog
153 static void dialog_response_cancel(NewText
*dialog
)
155 i_cancel(dialog
->parent
.w_current
);
156 gtk_widget_destroy(dialog
->parent
.w_current
->tiwindow
);
157 dialog
->parent
.w_current
->tiwindow
=NULL
;
162 /*! \brief Handles user responses from the new text dialog box
164 * \par Function Description
165 * Callback function for the text entry dialog.
167 * \param [in,out] widget The new text dialog
168 * \param [na] unused Unused parameter
170 static void text_input_dialog_response(NewText
*dialog
, gint response
, gpointer unused
)
173 case GTK_RESPONSE_APPLY
:
174 dialog_response_apply(dialog
);
176 case GTK_RESPONSE_CLOSE
:
177 case GTK_RESPONSE_DELETE_EVENT
:
178 dialog_response_cancel(dialog
);
181 printf("text_edit_dialog_response(): strange signal %d\n", response
);
186 /*! \brief Initialize NewText class
188 * \par Function Description
190 * GType class initialiser for Multiattrib. We override our parent
191 * virtual class methods as needed and register our GObject properties.
195 static void newtext_class_init(NewTextClass
*klass
)
201 /*! \brief Initialize NewText instance
203 * \param [in,out] dialog The new text dialog
205 static void newtext_init(NewText
*dialog
)
207 GtkWidget
*alignment
;
209 GtkWidget
*label
= NULL
;
210 GtkWidget
*viewport1
= NULL
;
211 GtkWidget
*scrolled_window
= NULL
;
212 PangoTabArray
*tab_array
;
216 gtk_dialog_add_button (GTK_DIALOG (dialog
),
220 gtk_dialog_add_button (GTK_DIALOG (dialog
),
224 /* Set the alternative button order (ok, cancel, help) for other systems */
225 gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog
),
230 gtk_window_set_position (GTK_WINDOW (dialog
), GTK_WIN_POS_NONE
);
232 g_signal_connect (G_OBJECT (dialog
), "response",
233 G_CALLBACK (text_input_dialog_response
),
236 gtk_dialog_set_default_response(GTK_DIALOG(dialog
),
237 GTK_RESPONSE_ACCEPT
);
239 vbox
= GTK_DIALOG(dialog
)->vbox
;
240 gtk_box_set_spacing(GTK_BOX(vbox
),DIALOG_V_SPACING
);
242 table
= gtk_table_new(4, 2, FALSE
);
243 gtk_table_set_row_spacings(GTK_TABLE(table
), DIALOG_V_SPACING
);
244 gtk_table_set_col_spacings(GTK_TABLE(table
), DIALOG_H_SPACING
);
246 label
= gtk_label_new(_("<b>Text Properties</b>"));
247 gtk_label_set_use_markup(GTK_LABEL(label
), TRUE
);
248 gtk_misc_set_alignment(GTK_MISC(label
),0,0);
249 gtk_box_pack_start(GTK_BOX(vbox
), label
, FALSE
, FALSE
, 0);
251 alignment
= gtk_alignment_new(0,0,1,1);
252 gtk_alignment_set_padding(GTK_ALIGNMENT(alignment
), 0, 0,
253 DIALOG_INDENTATION
, 0);
254 gtk_box_pack_start(GTK_BOX(vbox
), alignment
, FALSE
, FALSE
, 0);
256 gtk_container_add(GTK_CONTAINER(alignment
), table
);
258 label
= gtk_label_new (_("<b>Text Content</b>"));
259 gtk_label_set_use_markup (GTK_LABEL (label
), TRUE
);
260 gtk_misc_set_alignment(GTK_MISC(label
),0,0);
261 gtk_box_pack_start(GTK_BOX(vbox
), label
, FALSE
, FALSE
, 0);
264 label
= gtk_label_new (_("Color:"));
265 gtk_misc_set_alignment(GTK_MISC(label
),0,0);
266 gtk_table_attach(GTK_TABLE(table
), label
, 0,1,0,1, GTK_FILL
,0,0,0);
268 dialog
->colorcb
= x_colorcb_new ();
269 x_colorcb_set_index(dialog
->colorcb
, TEXT_COLOR
);
270 gtk_table_attach_defaults(GTK_TABLE(table
), dialog
->colorcb
, 1,2,0,1);
272 label
= gtk_label_new (_("Size:"));
273 gtk_misc_set_alignment(GTK_MISC(label
),0,0);
274 gtk_table_attach(GTK_TABLE(table
), label
, 0,1,1,2, GTK_FILL
,0,0,0);
276 dialog
->textsizecb
= gschem_integer_combo_box_new();
277 gschem_integer_combo_box_set_value(dialog
->textsizecb
, 12);
278 gtk_table_attach_defaults(GTK_TABLE(table
), dialog
->textsizecb
, 1,2,1,2);
280 label
= gtk_label_new (_("Alignment:"));
281 gtk_misc_set_alignment(GTK_MISC(label
),0,0);
282 gtk_table_attach(GTK_TABLE(table
), label
, 0,1,2,3, GTK_FILL
,0,0,0);
284 dialog
->aligncb
= gschem_alignment_combo_new ();
285 gschem_alignment_combo_set_align(dialog
->aligncb
, LOWER_LEFT
);
286 gtk_table_attach_defaults(GTK_TABLE(table
), dialog
->aligncb
, 1,2,2,3);
288 label
= gtk_label_new (_("Rotation:"));
289 gtk_misc_set_alignment(GTK_MISC(label
),0,0);
290 gtk_table_attach(GTK_TABLE(table
), label
, 0,1,3,4, GTK_FILL
,0,0,0);
292 dialog
->rotatecb
= gschem_rotation_combo_new ();
293 gschem_rotation_combo_set_angle(dialog
->rotatecb
, 0);
294 gtk_table_attach_defaults(GTK_TABLE(table
), dialog
->rotatecb
, 1,2,3,4);
297 viewport1
= gtk_viewport_new (NULL
, NULL
);
298 gtk_widget_show (viewport1
);
300 scrolled_window
= gtk_scrolled_window_new(NULL
, NULL
);
301 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window
),
302 GTK_POLICY_AUTOMATIC
,
303 GTK_POLICY_AUTOMATIC
);
304 gtk_container_add (GTK_CONTAINER (viewport1
), scrolled_window
);
305 gtk_box_pack_start( GTK_BOX(vbox
), viewport1
, TRUE
, TRUE
, 0);
307 dialog
->text_view
= gtk_text_view_new();
308 gtk_text_view_set_editable(GTK_TEXT_VIEW(dialog
->text_view
), TRUE
);
309 select_all_text_in_textview(GTK_TEXT_VIEW(dialog
->text_view
));
311 /* Set the tab width, using pango tab array */
312 /*! \bug FIXME: This doesn't work. Why? */
313 tab_array
= pango_tab_array_new (1, TRUE
);
314 real_tab_width
= text_view_calculate_real_tab_width(GTK_TEXT_VIEW(dialog
->text_view
),
316 if (real_tab_width
>= 0) {
317 pango_tab_array_set_tab (tab_array
, 0, PANGO_TAB_LEFT
, real_tab_width
);
318 /* printf("Real tab width: %i\n", real_tab_width);*/
319 gtk_text_view_set_tabs (GTK_TEXT_VIEW (dialog
->text_view
),
323 g_warning ("text_input_dialog: Impossible to set tab width.\n");
326 pango_tab_array_free (tab_array
);
327 gtk_container_add(GTK_CONTAINER(scrolled_window
), dialog
->text_view
);
332 /*! \brief Get/register NewText type.
334 GType
newtext_get_type()
336 static GType type
= 0;
339 static const GTypeInfo info
= {
340 sizeof(NewTextClass
),
341 NULL
, /* base_init */
342 NULL
, /* base_finalize */
343 (GClassInitFunc
) newtext_class_init
,
344 NULL
, /* class_finalize */
345 NULL
, /* class_data */
348 (GInstanceInitFunc
) newtext_init
,
351 type
= g_type_register_static (GSCHEM_TYPE_DIALOG
, "NewText", &info
, 0);
359 /*! \brief Open the dialog box to add new text
361 * \par Function Description
362 * This function creates or raises the modal text entry dialog
364 * \param [in] w_current The gschem toplevel
367 text_input_dialog (GschemToplevel
*w_current
)
369 if (w_current
->tiwindow
== NULL
) {
370 /* dialog not created yet */
371 w_current
->tiwindow
= g_object_new (TYPE_NEWTEXT
,
373 "border-width", DIALOG_BORDER_SPACING
,
375 "title", _("Text Entry..."),
376 "default-width", 320,
377 "default-height", 350,
378 "window-position", GTK_WIN_POS_MOUSE
,
380 "allow-shrink", FALSE
,
383 "has-separator", TRUE
,
385 "settings-name", "text-entry",
386 "gschem-toplevel", w_current
,
389 gtk_window_set_transient_for (GTK_WINDOW (w_current
->tiwindow
),
390 GTK_WINDOW (w_current
->main_window
));
392 gschem_integer_combo_box_set_model (NEWTEXT (w_current
->tiwindow
)->textsizecb
,
393 gschem_toplevel_get_text_size_list_store (w_current
));
395 gtk_widget_show_all (w_current
->tiwindow
);
398 /* dialog already created */
399 gtk_window_present (GTK_WINDOW(w_current
->tiwindow
));
402 /* always select the text in the entry */
403 select_all_text_in_textview (GTK_TEXT_VIEW (NEWTEXT (w_current
->tiwindow
)->text_view
));
404 gtk_widget_grab_focus (NEWTEXT (w_current
->tiwindow
)->text_view
);