1 /*
2 * Copyright (C) 2009 - 2011 Vivien Malerba <malerba@gnome-db.org>
3 * Copyright (C) 2010 David King <davidk@openismus.com>
4 * Copyright (C) 2011 Murray Cumming <murrayc@murrayc.com>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library 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 GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 */
21
22 #include <glib/gi18n-lib.h>
23 #include <string.h>
24 #include "gdaui-entry-string.h"
25 #include "gdaui-entry.h"
26 #include <libgda/gda-data-handler.h>
27 #include "gdk/gdkkeysyms.h"
28 #include <libgda/gda-debug-macros.h>
29
30 /*
31 * Main static functions
32 */
33 static void gdaui_entry_string_class_init (GdauiEntryStringClass *klass);
34 static void gdaui_entry_string_init (GdauiEntryString *srv);
35 static void gdaui_entry_string_dispose (GObject *object);
36 static void gdaui_entry_string_finalize (GObject *object);
37
38 static void gdaui_entry_string_set_property (GObject *object,
39 guint param_id,
40 const GValue *value,
41 GParamSpec *pspec);
42 static void gdaui_entry_string_get_property (GObject *object,
43 guint param_id,
44 GValue *value,
45 GParamSpec *pspec);
46
47 /* properties */
48 enum
49 {
50 PROP_0,
51 PROP_MULTILINE,
52 PROP_EDITING_CANCELED,
53 PROP_OPTIONS
54 };
55
56 /* GtkCellEditable interface */
57 static void gdaui_entry_string_cell_editable_init (GtkCellEditableIface *iface);
58 static void gdaui_entry_string_start_editing (GtkCellEditable *iface, GdkEvent *event);
59 static void sync_entry_options (GdauiEntryString *mgstr);
60
61 /* virtual functions */
62 static GtkWidget *create_entry (GdauiEntryWrapper *mgwrap);
63 static void real_set_value (GdauiEntryWrapper *mgwrap, const GValue *value);
64 static GValue *real_get_value (GdauiEntryWrapper *mgwrap);
65 static void connect_signals(GdauiEntryWrapper *mgwrap, GCallback modify_cb, GCallback activate_cb);
66 static void set_editable (GdauiEntryWrapper *mgwrap, gboolean editable);
67 static void grab_focus (GdauiEntryWrapper *mgwrap);
68
69 /* options */
70 static void set_entry_options (GdauiEntryString *mgstr, const gchar *options);
71
72 /* get a pointer to the parents to be able to call their destructor */
73 static GObjectClass *parent_class = NULL;
74
75 /* private structure */
76 struct _GdauiEntryStringPrivate
77 {
78 gboolean multiline;
79 gboolean hidden;
80 GtkWidget *vbox;
81
82 GtkWidget *entry;
83 gboolean editing_canceled;
84
85 GtkTextBuffer *buffer;
86 GtkWidget *sw;
87 GtkWidget *view;
88
89 gint maxsize;
90
91 gulong entry_change_sig;
92 };
93
94 static void
gdaui_entry_string_cell_editable_init(GtkCellEditableIface * iface)95 gdaui_entry_string_cell_editable_init (GtkCellEditableIface *iface)
96 {
97 iface->start_editing = gdaui_entry_string_start_editing;
98 }
99
100 GType
gdaui_entry_string_get_type(void)101 gdaui_entry_string_get_type (void)
102 {
103 static GType type = 0;
104
105 if (G_UNLIKELY (type == 0)) {
106 static const GTypeInfo info = {
107 sizeof (GdauiEntryStringClass),
108 (GBaseInitFunc) NULL,
109 (GBaseFinalizeFunc) NULL,
110 (GClassInitFunc) gdaui_entry_string_class_init,
111 NULL,
112 NULL,
113 sizeof (GdauiEntryString),
114 0,
115 (GInstanceInitFunc) gdaui_entry_string_init,
116 0
117 };
118
119 static const GInterfaceInfo cell_editable_info = {
120 (GInterfaceInitFunc) gdaui_entry_string_cell_editable_init, /* interface_init */
121 NULL, /* interface_finalize */
122 NULL /* interface_data */
123 };
124
125 type = g_type_register_static (GDAUI_TYPE_ENTRY_WRAPPER, "GdauiEntryString", &info, 0);
126 g_type_add_interface_static (type, GTK_TYPE_CELL_EDITABLE, &cell_editable_info);
127 }
128 return type;
129 }
130
131 static void
gdaui_entry_string_class_init(GdauiEntryStringClass * klass)132 gdaui_entry_string_class_init (GdauiEntryStringClass * klass)
133 {
134 GObjectClass *object_class = G_OBJECT_CLASS (klass);
135
136 parent_class = g_type_class_peek_parent (klass);
137
138 object_class->dispose = gdaui_entry_string_dispose;
139 object_class->finalize = gdaui_entry_string_finalize;
140
141 GDAUI_ENTRY_WRAPPER_CLASS (klass)->create_entry = create_entry;
142 GDAUI_ENTRY_WRAPPER_CLASS (klass)->real_set_value = real_set_value;
143 GDAUI_ENTRY_WRAPPER_CLASS (klass)->real_get_value = real_get_value;
144 GDAUI_ENTRY_WRAPPER_CLASS (klass)->connect_signals = connect_signals;
145 GDAUI_ENTRY_WRAPPER_CLASS (klass)->set_editable = set_editable;
146 GDAUI_ENTRY_WRAPPER_CLASS (klass)->grab_focus = grab_focus;
147
148 /* Properties */
149 object_class->set_property = gdaui_entry_string_set_property;
150 object_class->get_property = gdaui_entry_string_get_property;
151
152 g_object_class_install_property (object_class, PROP_MULTILINE,
153 g_param_spec_boolean ("multiline", NULL, NULL, FALSE,
154 G_PARAM_READABLE | G_PARAM_WRITABLE));
155 g_object_class_install_property (object_class, PROP_EDITING_CANCELED,
156 g_param_spec_boolean ("editing-canceled", NULL, NULL, FALSE,
157 G_PARAM_READABLE | G_PARAM_WRITABLE));
158 g_object_class_install_property (object_class, PROP_OPTIONS,
159 g_param_spec_string ("options", NULL, NULL, NULL, G_PARAM_WRITABLE));
160 }
161
162 static gboolean
key_press_event_cb(GdauiEntryString * mgstr,GdkEventKey * key_event,G_GNUC_UNUSED gpointer data)163 key_press_event_cb (GdauiEntryString *mgstr, GdkEventKey *key_event, G_GNUC_UNUSED gpointer data)
164 {
165 if (key_event->keyval == GDK_KEY_Escape)
166 mgstr->priv->editing_canceled = TRUE;
167 return FALSE;
168 }
169
170 static void
gdaui_entry_string_init(GdauiEntryString * mgstr)171 gdaui_entry_string_init (GdauiEntryString *mgstr)
172 {
173 mgstr->priv = g_new0 (GdauiEntryStringPrivate, 1);
174 mgstr->priv->multiline = FALSE;
175 mgstr->priv->hidden = FALSE;
176 mgstr->priv->vbox = NULL;
177 mgstr->priv->entry = NULL;
178 mgstr->priv->editing_canceled = FALSE;
179 mgstr->priv->buffer = NULL;
180 mgstr->priv->view = NULL;
181 mgstr->priv->sw = NULL;
182
183 mgstr->priv->maxsize = 65535; /* eg. unlimited for GtkEntry */
184
185 mgstr->priv->entry_change_sig = 0;
186
187 g_signal_connect (mgstr, "key-press-event",
188 G_CALLBACK (key_press_event_cb), NULL);
189 }
190
191 /**
192 * gdaui_entry_string_new:
193 * @dh: the data handler to be used by the new widget
194 * @type: the requested data type (compatible with @dh)
195 *
196 * Creates a new data entry widget
197 *
198 * Returns: (transfer full): the new widget
199 */
200 GtkWidget *
gdaui_entry_string_new(GdaDataHandler * dh,GType type,const gchar * options)201 gdaui_entry_string_new (GdaDataHandler *dh, GType type, const gchar *options)
202 {
203 GObject *obj;
204 GdauiEntryString *mgstr;
205
206 g_return_val_if_fail (GDA_IS_DATA_HANDLER (dh), NULL);
207 g_return_val_if_fail (gda_data_handler_accepts_g_type (dh, type), NULL);
208 g_return_val_if_fail (type == G_TYPE_STRING, NULL);
209
210 obj = g_object_new (GDAUI_TYPE_ENTRY_STRING, "handler", dh, NULL);
211 mgstr = GDAUI_ENTRY_STRING (obj);
212 gdaui_data_entry_set_value_type (GDAUI_DATA_ENTRY (mgstr), type);
213
214 g_object_set (obj, "options", options, NULL);
215
216 return GTK_WIDGET (obj);
217 }
218
219 static void
gdaui_entry_string_dispose(GObject * object)220 gdaui_entry_string_dispose (GObject * object)
221 {
222 GdauiEntryString *mgstr;
223
224 g_return_if_fail (object != NULL);
225 g_return_if_fail (GDAUI_IS_ENTRY_STRING (object));
226
227 mgstr = GDAUI_ENTRY_STRING (object);
228 if (mgstr->priv) {
229 if (mgstr->priv->entry)
230 mgstr->priv->entry = NULL;
231
232 if (mgstr->priv->view)
233 mgstr->priv->view = NULL;
234 }
235
236 /* parent class */
237 parent_class->dispose (object);
238 }
239
240 static void
gdaui_entry_string_finalize(GObject * object)241 gdaui_entry_string_finalize (GObject * object)
242 {
243 GdauiEntryString *mgstr;
244
245 g_return_if_fail (object != NULL);
246 g_return_if_fail (GDAUI_IS_ENTRY_STRING (object));
247
248 mgstr = GDAUI_ENTRY_STRING (object);
249 if (mgstr->priv) {
250 g_free (mgstr->priv);
251 mgstr->priv = NULL;
252 }
253
254 /* parent class */
255 parent_class->finalize (object);
256 }
257
258 static void
gdaui_entry_string_set_property(GObject * object,guint param_id,const GValue * value,GParamSpec * pspec)259 gdaui_entry_string_set_property (GObject *object,
260 guint param_id,
261 const GValue *value,
262 GParamSpec *pspec)
263 {
264 GdauiEntryString *mgstr;
265
266 mgstr = GDAUI_ENTRY_STRING (object);
267 if (mgstr->priv) {
268 switch (param_id) {
269 case PROP_MULTILINE:
270 if (g_value_get_boolean (value) != mgstr->priv->multiline) {
271 mgstr->priv->multiline = g_value_get_boolean (value);
272 if (mgstr->priv->multiline) {
273 gtk_widget_hide (mgstr->priv->entry);
274 gtk_widget_show (mgstr->priv->sw);
275 gtk_widget_set_vexpand (GTK_WIDGET (mgstr), TRUE);
276 }
277 else {
278 gtk_widget_show (mgstr->priv->entry);
279 gtk_widget_hide (mgstr->priv->sw);
280 gtk_widget_set_vexpand (GTK_WIDGET (mgstr), FALSE);
281 }
282 g_signal_emit_by_name (object, "expand-changed");
283 }
284 break;
285 case PROP_OPTIONS:
286 set_entry_options (mgstr, g_value_get_string (value));
287 break;
288 case PROP_EDITING_CANCELED:
289 TO_IMPLEMENT;
290 break;
291 default:
292 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
293 break;
294 }
295 }
296 }
297
298 static void
gdaui_entry_string_get_property(GObject * object,guint param_id,GValue * value,GParamSpec * pspec)299 gdaui_entry_string_get_property (GObject *object,
300 guint param_id,
301 GValue *value,
302 GParamSpec *pspec)
303 {
304 GdauiEntryString *mgstr;
305
306 mgstr = GDAUI_ENTRY_STRING (object);
307 if (mgstr->priv) {
308 switch (param_id) {
309 case PROP_MULTILINE:
310 g_value_set_boolean (value, mgstr->priv->multiline);
311 break;
312 case PROP_EDITING_CANCELED:
313 g_value_set_boolean (value, mgstr->priv->editing_canceled);
314 break;
315 default:
316 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
317 break;
318 }
319 }
320 }
321
322 static void widget_shown_cb (GtkWidget *wid, GdauiEntryString *mgstr);
323
324 static GtkWidget *
create_entry(GdauiEntryWrapper * mgwrap)325 create_entry (GdauiEntryWrapper *mgwrap)
326 {
327 GtkWidget *vbox;
328 GdauiEntryString *mgstr;
329
330 g_return_val_if_fail (GDAUI_IS_ENTRY_STRING (mgwrap), NULL);
331 mgstr = GDAUI_ENTRY_STRING (mgwrap);
332 g_return_val_if_fail (mgstr->priv, NULL);
333
334 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
335 mgstr->priv->vbox = vbox;
336
337 /* one line entry */
338 mgstr->priv->entry = gdaui_entry_new (NULL, NULL);
339 sync_entry_options (mgstr);
340 gtk_box_pack_start (GTK_BOX (vbox), mgstr->priv->entry, FALSE, TRUE, 0);
341 g_signal_connect_after (G_OBJECT (mgstr->priv->entry), "show",
342 G_CALLBACK (widget_shown_cb), mgstr);
343
344 /* multiline entry */
345 mgstr->priv->view = gtk_text_view_new ();
346 mgstr->priv->buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (mgstr->priv->view));
347 mgstr->priv->sw = gtk_scrolled_window_new (NULL, NULL);
348 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (mgstr->priv->sw), GTK_SHADOW_IN);
349 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (mgstr->priv->sw),
350 GTK_POLICY_AUTOMATIC,
351 GTK_POLICY_AUTOMATIC);
352 gtk_container_add (GTK_CONTAINER (mgstr->priv->sw), mgstr->priv->view);
353 gtk_widget_show (mgstr->priv->view);
354 gtk_box_pack_start (GTK_BOX (vbox), mgstr->priv->sw, TRUE, TRUE, 0);
355 g_signal_connect_after (G_OBJECT (mgstr->priv->sw), "show",
356 G_CALLBACK (widget_shown_cb), mgstr);
357
358
359 /* show widgets if they need to be shown */
360 gtk_widget_show (mgstr->priv->entry);
361 gtk_widget_show (mgstr->priv->sw);
362
363 return vbox;
364 }
365
366 static void
widget_shown_cb(GtkWidget * wid,GdauiEntryString * mgstr)367 widget_shown_cb (GtkWidget *wid, GdauiEntryString *mgstr)
368 {
369 if ((wid == mgstr->priv->entry) && mgstr->priv->multiline)
370 gtk_widget_hide (mgstr->priv->entry);
371
372 if ((wid == mgstr->priv->sw) && !mgstr->priv->multiline)
373 gtk_widget_hide (mgstr->priv->sw);
374 }
375
376
377 static void
real_set_value(GdauiEntryWrapper * mgwrap,const GValue * value)378 real_set_value (GdauiEntryWrapper *mgwrap, const GValue *value)
379 {
380 GdauiEntryString *mgstr;
381 GdaDataHandler *dh;
382
383 PangoLayout *layout;
384 gchar *text;
385
386 g_return_if_fail (GDAUI_IS_ENTRY_STRING (mgwrap));
387 mgstr = GDAUI_ENTRY_STRING (mgwrap);
388 g_return_if_fail (mgstr->priv);
389
390 dh = gdaui_data_entry_get_handler (GDAUI_DATA_ENTRY (mgwrap));
391
392 /* do we need to go into multi line mode ? */
393 text = gda_data_handler_get_str_from_value (dh, value);
394 layout = gtk_widget_create_pango_layout (GTK_WIDGET (mgwrap), text);
395 if (pango_layout_get_line_count (layout) > 1)
396 g_object_set (G_OBJECT (mgwrap), "multiline", TRUE, NULL);
397 g_object_unref (G_OBJECT (layout));
398
399 /* fill the single line widget */
400 if (value) {
401 if (gda_value_is_null ((GValue *) value))
402 gdaui_entry_set_text (GDAUI_ENTRY (mgstr->priv->entry), NULL);
403 else
404 gdaui_entry_set_text (GDAUI_ENTRY (mgstr->priv->entry), text);
405 }
406 else
407 gdaui_entry_set_text (GDAUI_ENTRY (mgstr->priv->entry), NULL);
408
409 /* fill the multiline widget */
410 if (value) {
411 if (gda_value_is_null ((GValue *) value) || !text)
412 gtk_text_buffer_set_text (mgstr->priv->buffer, "", -1);
413 else
414 gtk_text_buffer_set_text (mgstr->priv->buffer, text, -1);
415 }
416 else
417 gtk_text_buffer_set_text (mgstr->priv->buffer, "", -1);
418
419 g_free (text);
420 }
421
422 static GValue *
real_get_value(GdauiEntryWrapper * mgwrap)423 real_get_value (GdauiEntryWrapper *mgwrap)
424 {
425 GValue *value;
426 GdauiEntryString *mgstr;
427 GdaDataHandler *dh;
428
429 g_return_val_if_fail (GDAUI_IS_ENTRY_STRING (mgwrap), NULL);
430 mgstr = GDAUI_ENTRY_STRING (mgwrap);
431 g_return_val_if_fail (mgstr->priv, NULL);
432
433 dh = gdaui_data_entry_get_handler (GDAUI_DATA_ENTRY (mgwrap));
434 if (! mgstr->priv->multiline) {
435 gchar *cstr;
436 cstr = gdaui_entry_get_text (GDAUI_ENTRY (mgstr->priv->entry));
437 value = gda_data_handler_get_value_from_str (dh, cstr, gdaui_data_entry_get_value_type (GDAUI_DATA_ENTRY (mgwrap)));
438 g_free (cstr);
439 }
440 else {
441 GtkTextIter start, end;
442 gchar *str;
443 gtk_text_buffer_get_start_iter (mgstr->priv->buffer, &start);
444 gtk_text_buffer_get_end_iter (mgstr->priv->buffer, &end);
445 str = gtk_text_buffer_get_text (mgstr->priv->buffer, &start, &end, FALSE);
446 value = gda_data_handler_get_value_from_str (dh, str, gdaui_data_entry_get_value_type (GDAUI_DATA_ENTRY (mgwrap)));
447 g_free (str);
448 }
449
450 if (!value) {
451 /* in case the gda_data_handler_get_value_from_str() returned an error because
452 the contents of the GtkEntry cannot be interpreted as a GValue */
453 value = gda_value_new_null ();
454 }
455
456 return value;
457 }
458
459 static void
connect_signals(GdauiEntryWrapper * mgwrap,GCallback modify_cb,GCallback activate_cb)460 connect_signals(GdauiEntryWrapper *mgwrap, GCallback modify_cb, GCallback activate_cb)
461 {
462 GdauiEntryString *mgstr;
463
464 g_return_if_fail (GDAUI_IS_ENTRY_STRING (mgwrap));
465 mgstr = GDAUI_ENTRY_STRING (mgwrap);
466 g_return_if_fail (mgstr->priv);
467
468 mgstr->priv->entry_change_sig = g_signal_connect (G_OBJECT (mgstr->priv->entry), "changed",
469 modify_cb, mgwrap);
470 g_signal_connect (G_OBJECT (mgstr->priv->entry), "activate",
471 activate_cb, mgwrap);
472
473 g_signal_connect (G_OBJECT (mgstr->priv->buffer), "changed",
474 modify_cb, mgwrap);
475 /* FIXME: how does the user "activates" the GtkTextView widget ? */
476 }
477
478 static void
set_editable(GdauiEntryWrapper * mgwrap,gboolean editable)479 set_editable (GdauiEntryWrapper *mgwrap, gboolean editable)
480 {
481 GdauiEntryString *mgstr;
482
483 g_return_if_fail (GDAUI_IS_ENTRY_STRING (mgwrap));
484 mgstr = GDAUI_ENTRY_STRING (mgwrap);
485 g_return_if_fail (mgstr->priv);
486
487 gtk_editable_set_editable (GTK_EDITABLE (mgstr->priv->entry), editable);
488 gtk_text_view_set_editable (GTK_TEXT_VIEW (mgstr->priv->view), editable);
489 }
490
491 static void
grab_focus(GdauiEntryWrapper * mgwrap)492 grab_focus (GdauiEntryWrapper *mgwrap)
493 {
494 GdauiEntryString *mgstr;
495
496 g_return_if_fail (GDAUI_IS_ENTRY_STRING (mgwrap));
497 mgstr = GDAUI_ENTRY_STRING (mgwrap);
498 g_return_if_fail (mgstr->priv);
499
500 if (mgstr->priv->multiline)
501 gtk_widget_grab_focus (mgstr->priv->view);
502 else
503 gtk_widget_grab_focus (mgstr->priv->entry);
504 }
505
506 /*
507 * GtkCellEditable interface
508 */
509 static void
gtk_cell_editable_entry_editing_done_cb(G_GNUC_UNUSED GtkEntry * entry,GdauiEntryString * mgstr)510 gtk_cell_editable_entry_editing_done_cb (G_GNUC_UNUSED GtkEntry *entry, GdauiEntryString *mgstr)
511 {
512 gtk_cell_editable_editing_done (GTK_CELL_EDITABLE (mgstr));
513 }
514
515 static void
gtk_cell_editable_entry_remove_widget_cb(G_GNUC_UNUSED GtkEntry * entry,GdauiEntryString * mgstr)516 gtk_cell_editable_entry_remove_widget_cb (G_GNUC_UNUSED GtkEntry *entry, GdauiEntryString *mgstr)
517 {
518 gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE (mgstr));
519 }
520
521 static void
gdaui_entry_string_start_editing(GtkCellEditable * iface,GdkEvent * event)522 gdaui_entry_string_start_editing (GtkCellEditable *iface, GdkEvent *event)
523 {
524 GdauiEntryString *mgstr;
525
526 g_return_if_fail (GDAUI_IS_ENTRY_STRING (iface));
527 mgstr = GDAUI_ENTRY_STRING (iface);
528 g_return_if_fail (mgstr->priv);
529
530 mgstr->priv->editing_canceled = FALSE;
531 g_object_set (G_OBJECT (mgstr->priv->entry), "has-frame", FALSE, "xalign", 0., NULL);
532 gtk_text_view_set_border_window_size (GTK_TEXT_VIEW (mgstr->priv->view), GTK_TEXT_WINDOW_LEFT, 0);
533 gtk_text_view_set_border_window_size (GTK_TEXT_VIEW (mgstr->priv->view), GTK_TEXT_WINDOW_RIGHT, 0);
534 gtk_text_view_set_border_window_size (GTK_TEXT_VIEW (mgstr->priv->view), GTK_TEXT_WINDOW_TOP, 0);
535 gtk_text_view_set_border_window_size (GTK_TEXT_VIEW (mgstr->priv->view), GTK_TEXT_WINDOW_BOTTOM, 0);
536 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (mgstr->priv->sw), GTK_SHADOW_NONE);
537 gtk_container_set_border_width (GTK_CONTAINER (mgstr->priv->sw), 0);
538
539 gtk_cell_editable_start_editing (GTK_CELL_EDITABLE (mgstr->priv->entry), event);
540 g_signal_connect (mgstr->priv->entry, "editing-done",
541 G_CALLBACK (gtk_cell_editable_entry_editing_done_cb), mgstr);
542 g_signal_connect (mgstr->priv->entry, "remove-widget",
543 G_CALLBACK (gtk_cell_editable_entry_remove_widget_cb), mgstr);
544 gdaui_entry_shell_refresh (GDAUI_ENTRY_SHELL (mgstr));
545
546 gtk_widget_grab_focus (mgstr->priv->entry);
547 gtk_widget_queue_draw (GTK_WIDGET (mgstr));
548 }
549
550 /*
551 * Options handling
552 */
553 static void
set_entry_options(GdauiEntryString * mgstr,const gchar * options)554 set_entry_options (GdauiEntryString *mgstr, const gchar *options)
555 {
556 g_assert (mgstr->priv);
557
558 if (options && *options) {
559 GdaQuarkList *params;
560 const gchar *str;
561
562 params = gda_quark_list_new_from_string (options);
563
564 str = gda_quark_list_find (params, "MAX_SIZE");
565 if (str)
566 mgstr->priv->maxsize = atoi (str);
567
568 str = gda_quark_list_find (params, "MULTILINE");
569 if (str) {
570 if ((*str == 't') || (*str == 'T'))
571 mgstr->priv->multiline = TRUE;
572 else
573 mgstr->priv->multiline = FALSE;
574
575 }
576
577 str = gda_quark_list_find (params, "HIDDEN");
578 if (str) {
579 if ((*str == 't') || (*str == 'T'))
580 mgstr->priv->hidden = TRUE;
581 else
582 mgstr->priv->hidden = FALSE;
583 }
584
585 if (mgstr->priv->entry) {
586 if (mgstr->priv->multiline) {
587 gtk_widget_hide (mgstr->priv->entry);
588 gtk_widget_show (mgstr->priv->sw);
589 }
590 else {
591 gtk_widget_show (mgstr->priv->entry);
592 gtk_widget_hide (mgstr->priv->sw);
593 gtk_entry_set_visibility (GTK_ENTRY (mgstr->priv->entry),
594 !mgstr->priv->hidden);
595 }
596 }
597 gda_quark_list_free (params);
598 sync_entry_options (mgstr);
599 }
600 }
601
602 /* sets the correct options for mgstr->priv->entry if it exists */
603 static void
sync_entry_options(GdauiEntryString * mgstr)604 sync_entry_options (GdauiEntryString *mgstr)
605 {
606 if (!mgstr->priv->entry)
607 return;
608
609 g_object_set (G_OBJECT (mgstr->priv->entry),
610 "max-length", mgstr->priv->maxsize,
611 NULL);
612 g_signal_emit_by_name (mgstr->priv->entry, "changed");
613 }
614