1 /*
2 * This file is part of YAD.
3 *
4 * YAD is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * YAD is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with YAD. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Copyright (C) 2008-2020, Victor Ananjevsky <ananasik@gmail.com>
18 */
19
20 #include <ctype.h>
21 #include <stdlib.h>
22
23 #include "yad.h"
24
25 #include "calendar.xpm"
26
27 static GSList *fields = NULL;
28 static guint n_fields;
29
30 /* expand %N in command to fields values */
31 static GString *
expand_action(gchar * cmd)32 expand_action (gchar * cmd)
33 {
34 GString *xcmd;
35 guint i = 0;
36
37 xcmd = g_string_new ("");
38 while (cmd[i])
39 {
40 if (cmd[i] == '%')
41 {
42 i++;
43 if (g_ascii_isdigit (cmd[i]))
44 {
45 YadField *fld;
46 gchar *buf, *arg;
47 guint num, j = i;
48
49 /* get field num */
50 while (g_ascii_isdigit (cmd[j]))
51 j++;
52 buf = g_strndup (cmd + i, j - i);
53 num = g_ascii_strtoll (buf, NULL, 10);
54 g_free (buf);
55 if (num > 0 && num <= n_fields)
56 num--;
57 else
58 continue;
59
60 /* get field value */
61 arg = NULL;
62 fld = g_slist_nth_data (options.form_data.fields, num);
63 switch (fld->type)
64 {
65 case YAD_FIELD_SIMPLE:
66 case YAD_FIELD_HIDDEN:
67 case YAD_FIELD_READ_ONLY:
68 case YAD_FIELD_COMPLETE:
69 case YAD_FIELD_FILE_SAVE:
70 case YAD_FIELD_DIR_CREATE:
71 case YAD_FIELD_MFILE:
72 case YAD_FIELD_MDIR:
73 case YAD_FIELD_DATE:
74 buf = escape_char ((gchar *) gtk_entry_get_text (GTK_ENTRY (g_slist_nth_data (fields, num))), '"');
75 arg = g_shell_quote (buf ? buf : "");
76 g_free (buf);
77 break;
78 case YAD_FIELD_NUM:
79 {
80 guint prec = gtk_spin_button_get_digits (GTK_SPIN_BUTTON (g_slist_nth_data (fields, num)));
81 arg = g_strdup_printf ("%.*f", prec, gtk_spin_button_get_value (GTK_SPIN_BUTTON (g_slist_nth_data (fields, num))));
82 break;
83 }
84 case YAD_FIELD_CHECK:
85 arg = g_strdup (print_bool_val (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (g_slist_nth_data (fields, num)))));
86 break;
87 case YAD_FIELD_COMBO:
88 case YAD_FIELD_COMBO_ENTRY:
89 buf = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (g_slist_nth_data (fields, num)));
90 arg = g_shell_quote (buf ? buf : "");
91 g_free (buf);
92 break;
93 case YAD_FIELD_SCALE:
94 arg = g_strdup_printf ("%d", (gint) gtk_range_get_value (GTK_RANGE (g_slist_nth_data (fields, num))));
95 break;
96 case YAD_FIELD_FILE:
97 case YAD_FIELD_DIR:
98 arg = g_shell_quote (gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (g_slist_nth_data (fields, num))));
99 break;
100 case YAD_FIELD_FONT:
101 arg = g_shell_quote (gtk_font_chooser_get_font (GTK_FONT_CHOOSER (g_slist_nth_data (fields, num))));
102 break;
103 case YAD_FIELD_LINK:
104 arg = g_shell_quote (gtk_link_button_get_uri (GTK_LINK_BUTTON (g_slist_nth_data (fields, num))));
105 break;
106 case YAD_FIELD_APP:
107 {
108 GList *wl = gtk_container_get_children (GTK_CONTAINER (g_slist_nth_data (fields, num)));
109 GAppInfo *info = gtk_app_chooser_get_app_info (GTK_APP_CHOOSER (wl->data));
110 arg = g_shell_quote (g_app_info_get_executable (info));
111 g_object_unref (info);
112 break;
113 }
114 case YAD_FIELD_COLOR:
115 {
116 GdkRGBA c;
117 GtkColorChooser *cb = GTK_COLOR_CHOOSER (g_slist_nth_data (fields, num));
118 gtk_color_chooser_get_rgba (cb, &c);
119 buf = get_color (&c);
120 arg = g_shell_quote (buf ? buf : "");
121 g_free (buf);
122 break;
123 }
124 case YAD_FIELD_TEXT:
125 {
126 GtkTextBuffer *tb;
127 GtkTextIter b, e;
128 gchar *txt;
129
130 tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (g_slist_nth_data (fields, num)));
131 gtk_text_buffer_get_bounds (tb, &b, &e);
132 txt = gtk_text_buffer_get_text (tb, &b, &e, FALSE);
133
134 /* escape special chars */
135 buf = escape_str (txt);
136 g_free (txt);
137
138 /* escape quotes */
139 txt = escape_char (buf, '"');
140 g_free (buf);
141
142 arg = g_shell_quote (txt ? txt : "");
143 g_free (txt);
144 }
145 default: ;
146 }
147 if (arg)
148 {
149 g_string_append (xcmd, arg);
150 g_free (arg);
151 }
152 i = j;
153 }
154 else
155 {
156 g_string_append_c (xcmd, cmd[i]);
157 i++;
158 }
159 }
160 else
161 {
162 g_string_append_c (xcmd, cmd[i]);
163 i++;
164 }
165 }
166 g_string_append_c (xcmd, '\0');
167
168 return xcmd;
169 }
170
171 static void
set_field_value(guint num,gchar * value)172 set_field_value (guint num, gchar * value)
173 {
174 GtkWidget *w;
175 gchar **s;
176 YadField *fld = g_slist_nth_data (options.form_data.fields, num);
177
178 w = GTK_WIDGET (g_slist_nth_data (fields, num));
179 if (g_ascii_strcasecmp (value, "@disabled@") == 0)
180 {
181 gtk_widget_set_sensitive (w, FALSE);
182 return;
183 }
184 else
185 gtk_widget_set_sensitive (w, TRUE);
186
187 switch (fld->type)
188 {
189 case YAD_FIELD_READ_ONLY:
190 gtk_widget_set_sensitive (w, FALSE);
191 case YAD_FIELD_SIMPLE:
192 case YAD_FIELD_HIDDEN:
193 case YAD_FIELD_MFILE:
194 case YAD_FIELD_MDIR:
195 case YAD_FIELD_FILE_SAVE:
196 case YAD_FIELD_DIR_CREATE:
197 case YAD_FIELD_DATE:
198 gtk_entry_set_text (GTK_ENTRY (w), value);
199 break;
200
201 case YAD_FIELD_NUM:
202 s = g_strsplit (value, options.common_data.item_separator, -1);
203 if (s[0])
204 {
205 gdouble val = g_ascii_strtod (s[0], NULL);
206 w = g_slist_nth_data (fields, num);
207 if (s[1])
208 {
209 gchar **s1 = g_strsplit (s[1], "..", 2);
210 if (s1[0] && s1[1])
211 {
212 gdouble min, max;
213 min = g_ascii_strtod (s1[0], NULL);
214 max = g_ascii_strtod (s1[1], NULL);
215 if (min < max)
216 gtk_spin_button_set_range (GTK_SPIN_BUTTON (w), min, max);
217 }
218 g_strfreev (s1);
219 if (s[2])
220 {
221 gdouble step = g_ascii_strtod (s[2], NULL);
222 gtk_spin_button_set_increments (GTK_SPIN_BUTTON (w), step, step * 10);
223 if (s[3])
224 {
225 guint prec = (guint) g_ascii_strtoull (s[3], NULL, 0);
226 if (prec > 20)
227 prec = 20;
228 gtk_spin_button_set_digits (GTK_SPIN_BUTTON (w), prec);
229 }
230 }
231 }
232 /* set initial value must be after setting range and step */
233 gtk_spin_button_set_value (GTK_SPIN_BUTTON (w), val);
234 }
235 g_strfreev (s);
236 break;
237
238 case YAD_FIELD_CHECK:
239 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), get_bool_val (value));
240 break;
241
242 case YAD_FIELD_COMPLETE:
243 {
244 GtkEntryCompletion *c;
245 GtkTreeModel *m;
246 GtkTreeIter it;
247 gint i = 0, def = -1;
248
249 c = gtk_entry_get_completion (GTK_ENTRY (w));
250 m = gtk_entry_completion_get_model (GTK_ENTRY_COMPLETION (c));
251 gtk_list_store_clear (GTK_LIST_STORE (m));
252
253 s = g_strsplit (value, options.common_data.item_separator, -1);
254 while (s[i])
255 {
256 gtk_list_store_append (GTK_LIST_STORE (m), &it);
257 if (s[i][0] == '^')
258 {
259 gtk_list_store_set (GTK_LIST_STORE (m), &it, 0, g_strcompress (s[i] + 1), -1);
260 def = i;
261 }
262 else
263 gtk_list_store_set (GTK_LIST_STORE (m), &it, 0, g_strcompress (s[i]), -1);
264
265 i++;
266 }
267 if (def >= 0)
268 gtk_entry_set_text (GTK_ENTRY (w), s[def] + 1);
269 else
270 gtk_entry_set_text (GTK_ENTRY (w), "");
271 g_strfreev (s);
272 break;
273 }
274
275 case YAD_FIELD_COMBO:
276 case YAD_FIELD_COMBO_ENTRY:
277 {
278 GtkTreeModel *m;
279 gint i = 0, def = 0;
280
281 /* cleanup previous values */
282 m = gtk_combo_box_get_model (GTK_COMBO_BOX (w));
283 gtk_list_store_clear (GTK_LIST_STORE (m));
284
285 s = g_strsplit (value, options.common_data.item_separator, -1);
286 while (s[i])
287 {
288 gchar *buf;
289
290 if (s[i][0] == '^')
291 {
292 buf = g_strcompress (s[i] + 1);
293 def = i;
294 }
295 else
296 buf = g_strcompress (s[i]);
297 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (w), buf);
298 g_free (buf);
299 i++;
300 }
301 gtk_combo_box_set_active (GTK_COMBO_BOX (w), def);
302 g_strfreev (s);
303 break;
304 }
305
306 case YAD_FIELD_DIR:
307 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (w), value);
308 case YAD_FIELD_FILE:
309 gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (w), value);
310 break;
311
312 case YAD_FIELD_FONT:
313 gtk_font_chooser_set_font (GTK_FONT_CHOOSER (w), value);
314 break;
315
316 case YAD_FIELD_SCALE:
317 gtk_range_set_value (GTK_RANGE (w), atoi (value));
318 break;
319
320 case YAD_FIELD_APP:
321 {
322 GtkWidget *b;
323 GList *wl;
324
325 for (wl = gtk_container_get_children (GTK_CONTAINER (w)); wl; wl = wl->next)
326 {
327 GtkWidget *cw = GTK_WIDGET (wl->data);
328 gtk_container_remove (GTK_CONTAINER (w), cw);
329 gtk_widget_destroy (cw);
330 }
331
332 if (value && value[0])
333 b = gtk_app_chooser_button_new (value);
334 else
335 b = gtk_app_chooser_button_new ("text/plain");
336 gtk_widget_set_name (b, "yad-form-app");
337 gtk_box_pack_start (GTK_BOX (w), b, TRUE, TRUE, 0);
338 gtk_widget_show_all (w);
339 break;
340 }
341
342 case YAD_FIELD_COLOR:
343 {
344 GdkRGBA c;
345 gdk_rgba_parse (&c, value);
346 gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (w), &c);
347 break;
348 }
349
350 case YAD_FIELD_BUTTON:
351 case YAD_FIELD_FULL_BUTTON:
352 g_object_set_data_full (G_OBJECT (w), "cmd", g_strdup (value), g_free);
353 break;
354
355 case YAD_FIELD_LINK:
356 gtk_link_button_set_uri (GTK_LINK_BUTTON (w), value);
357 break;
358
359 case YAD_FIELD_TEXT:
360 {
361 GtkTextBuffer *tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (w));
362 gchar *txt = g_strcompress (value);
363 gtk_text_buffer_set_text (tb, txt, -1);
364 g_free (txt);
365 break;
366 }
367
368 default:;
369 }
370 }
371
372 static void
button_clicked_cb(GtkButton * b,gpointer data)373 button_clicked_cb (GtkButton * b, gpointer data)
374 {
375 gchar *action = (gchar *) g_object_get_data (G_OBJECT (b), "cmd");
376
377 if (action && action[0])
378 {
379 if (action[0] == '@')
380 {
381 gchar *data;
382 gint exit = 1;
383 GString *cmd = expand_action (action + 1);
384 exit = run_command_sync (cmd->str, &data);
385 if (exit == 0)
386 {
387 guint i = 0;
388 gchar **lines = g_strsplit (data, "\n", 0);
389 while (lines[i] && lines[i][0])
390 {
391 gint fn;
392 gchar *ptr = lines[i];
393
394 while (isblank (*ptr)) ptr++;
395
396 if (isdigit (*ptr))
397 {
398 gchar **ln = g_strsplit (ptr, ":", 2);
399 fn = g_ascii_strtoll (ln[0], NULL, 10);
400 if (fn && ln[1])
401 set_field_value (fn - 1, ln[1]);
402 g_strfreev (ln);
403 }
404 i++;
405 }
406 }
407 g_free (data);
408 g_string_free (cmd, TRUE);
409 }
410 else
411 {
412 GString *cmd = expand_action (action);
413 run_command_async (cmd->str);
414 g_string_free (cmd, TRUE);
415 }
416 }
417
418 /* set focus to specified field */
419 if (options.form_data.focus_field > 0 && options.form_data.focus_field <= n_fields)
420 gtk_widget_grab_focus (GTK_WIDGET (g_slist_nth_data (fields, options.form_data.focus_field - 1)));
421 }
422
423 static void
form_activate_cb(GtkEntry * entry,gpointer data)424 form_activate_cb (GtkEntry * entry, gpointer data)
425 {
426 if (options.plug == -1)
427 yad_exit (options.data.def_resp);
428 }
429
430 static void
select_files_cb(GtkEntry * entry,GtkEntryIconPosition pos,GdkEventButton * event,gpointer data)431 select_files_cb (GtkEntry * entry, GtkEntryIconPosition pos, GdkEventButton * event, gpointer data)
432 {
433 GtkWidget *dlg;
434 GList *filt;
435 static gchar *path = NULL;
436
437 if (event->button == 1)
438 {
439 YadFieldType type = GPOINTER_TO_INT (data);
440
441 if (!path)
442 {
443 const gchar *val = gtk_entry_get_text (entry);
444
445 if (g_file_test (val, G_FILE_TEST_IS_DIR))
446 path = g_strdup (val);
447 else
448 path = val ? g_path_get_dirname (val) : g_get_current_dir ();
449 }
450
451 if (type == YAD_FIELD_MFILE)
452 {
453 dlg = gtk_file_chooser_dialog_new (_("Select files"),
454 GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (entry))),
455 GTK_FILE_CHOOSER_ACTION_OPEN,
456 _("Cancel"), GTK_RESPONSE_CANCEL,
457 _("OK"), GTK_RESPONSE_ACCEPT, NULL);
458 }
459 else
460 {
461 dlg = gtk_file_chooser_dialog_new (_("Select folders"),
462 GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (entry))),
463 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
464 _("Cancel"), GTK_RESPONSE_CANCEL,
465 _("OK"), GTK_RESPONSE_ACCEPT, NULL);
466 }
467 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dlg), TRUE);
468 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dlg), path);
469
470 g_signal_connect (dlg, "map", G_CALLBACK (gtk_file_chooser_set_show_hidden), GINT_TO_POINTER (options.common_data.show_hidden));
471
472 /* add preview */
473 if (options.common_data.preview)
474 {
475 GtkWidget *p = gtk_image_new ();
476 gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (dlg), p);
477 g_signal_connect (dlg, "update-preview", G_CALLBACK (update_preview), p);
478 }
479
480 /* add filters */
481 for (filt = options.common_data.filters; filt; filt = filt->next)
482 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dlg), GTK_FILE_FILTER (filt->data));
483
484 if (gtk_dialog_run (GTK_DIALOG (dlg)) == GTK_RESPONSE_ACCEPT)
485 {
486 GSList *files, *ptr;
487 GString *str;
488
489 str = g_string_new ("");
490 files = ptr = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dlg));
491
492 while (ptr)
493 {
494 if (ptr->data)
495 {
496 gchar *fn = g_filename_from_uri ((gchar *) ptr->data, NULL, NULL);
497 g_string_append (str, fn);
498 g_string_append (str, options.common_data.item_separator);
499 g_free (fn);
500 }
501 ptr = ptr->next;
502 }
503
504 str->str[str->len - 1] = '\0'; // remove last item separator
505 gtk_entry_set_text (entry, str->str);
506
507 g_slist_free (files);
508 g_string_free (str, TRUE);
509 }
510
511 g_free (path);
512 path = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dlg));
513 gtk_widget_destroy (dlg);
514 }
515 }
516
517 static void
create_files_cb(GtkEntry * entry,GtkEntryIconPosition pos,GdkEventButton * event,gpointer data)518 create_files_cb (GtkEntry * entry, GtkEntryIconPosition pos, GdkEventButton * event, gpointer data)
519 {
520 GtkWidget *dlg;
521 GList *filt;
522 static gchar *path = NULL;
523
524 if (event->button == 1)
525 {
526 YadFieldType type = GPOINTER_TO_INT (data);
527
528 if (!path)
529 {
530 const gchar *val = gtk_entry_get_text (entry);
531
532 if (g_file_test (val, G_FILE_TEST_IS_DIR))
533 path = g_strdup (val);
534 else
535 path = val ? g_path_get_dirname (val) : g_get_current_dir ();
536 }
537
538 if (type == YAD_FIELD_FILE_SAVE)
539 {
540 dlg = gtk_file_chooser_dialog_new (_("Select or create file"),
541 GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (entry))),
542 GTK_FILE_CHOOSER_ACTION_SAVE,
543 _("Cancel"), GTK_RESPONSE_CANCEL,
544 _("OK"), GTK_RESPONSE_ACCEPT, NULL);
545 }
546 else
547 {
548 dlg = gtk_file_chooser_dialog_new (_("Select or create folder"),
549 GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (entry))),
550 GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER,
551 _("Cancel"), GTK_RESPONSE_CANCEL,
552 _("OK"), GTK_RESPONSE_ACCEPT, NULL);
553 }
554 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dlg), path);
555
556 g_signal_connect (dlg, "map", G_CALLBACK (gtk_file_chooser_set_show_hidden), GINT_TO_POINTER (options.common_data.show_hidden));
557
558 /* add preview */
559 if (options.common_data.preview)
560 {
561 GtkWidget *p = gtk_image_new ();
562 gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (dlg), p);
563 g_signal_connect (dlg, "update-preview", G_CALLBACK (update_preview), p);
564 }
565
566 /* add filters */
567 for (filt = options.common_data.filters; filt; filt = filt->next)
568 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dlg), GTK_FILE_FILTER (filt->data));
569
570 if (gtk_dialog_run (GTK_DIALOG (dlg)) == GTK_RESPONSE_ACCEPT)
571 {
572 gchar *file = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dlg));
573
574 gtk_entry_set_text (entry, file);
575 g_free (file);
576 }
577
578 g_free (path);
579 path = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dlg));
580 gtk_widget_destroy (dlg);
581 }
582 }
583
584 static void
date_selected_cb(GtkCalendar * c,gpointer data)585 date_selected_cb (GtkCalendar * c, gpointer data)
586 {
587 gtk_dialog_response (GTK_DIALOG (data), GTK_RESPONSE_ACCEPT);
588 }
589
590 static void
select_date_cb(GtkEntry * entry,GtkEntryIconPosition pos,GdkEventButton * event,gpointer data)591 select_date_cb (GtkEntry * entry, GtkEntryIconPosition pos, GdkEventButton * event, gpointer data)
592 {
593 GtkWidget *dlg, *cal;
594
595 if (event->button == 1)
596 {
597 GDate *d;
598
599 dlg = gtk_dialog_new_with_buttons (_("Select date"),
600 GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (entry))),
601 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
602 _("Cancel"), GTK_RESPONSE_CANCEL,
603 _("OK"), GTK_RESPONSE_ACCEPT, NULL);
604 cal = gtk_calendar_new ();
605 gtk_widget_show (cal);
606 g_signal_connect (G_OBJECT (cal), "day-selected-double-click", G_CALLBACK (date_selected_cb), dlg);
607 gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), cal, TRUE, TRUE, 5);
608
609 d = g_date_new ();
610 g_date_set_parse (d, gtk_entry_get_text (entry));
611 if (g_date_valid (d))
612 {
613 gtk_calendar_select_day (GTK_CALENDAR (cal), g_date_get_day (d));
614 gtk_calendar_select_month (GTK_CALENDAR (cal), g_date_get_month (d) - 1, g_date_get_year (d));
615 }
616 g_date_free (d);
617
618 if (gtk_dialog_run (GTK_DIALOG (dlg)) == GTK_RESPONSE_ACCEPT)
619 {
620 guint day, month, year;
621 gchar *format = options.common_data.date_format;
622 gchar time_string[128];
623
624 gtk_calendar_get_date (GTK_CALENDAR (cal), &day, &month, &year);
625 d = g_date_new_dmy (year, month + 1, day);
626 g_date_strftime (time_string, 127, format, d);
627 gtk_entry_set_text (entry, time_string);
628 g_date_free (d);
629 }
630 gtk_widget_destroy (dlg);
631 }
632
633 gtk_widget_grab_focus (GTK_WIDGET (entry));
634 }
635
636 static gboolean
link_clicked_cb(GtkLinkButton * btn,gpointer data)637 link_clicked_cb (GtkLinkButton *btn, gpointer data)
638 {
639 const gchar *uri = gtk_link_button_get_uri (btn);
640 open_uri (uri);
641 return TRUE;
642 }
643
644 static gboolean
handle_stdin(GIOChannel * ch,GIOCondition cond,gpointer data)645 handle_stdin (GIOChannel * ch, GIOCondition cond, gpointer data)
646 {
647 static guint cnt = 0;
648
649 if ((cond == G_IO_IN) || (cond == G_IO_IN + G_IO_HUP))
650 {
651 GError *err = NULL;
652 GString *string = g_string_new (NULL);
653
654 while (ch->is_readable != TRUE);
655
656 do
657 {
658 gint status;
659
660 if (cnt == n_fields)
661 {
662 if (options.form_data.cycle_read)
663 cnt = 0;
664 else
665 {
666 g_io_channel_shutdown (ch, TRUE, NULL);
667 return FALSE;
668 }
669 }
670
671 do
672 {
673 status = g_io_channel_read_line_string (ch, string, NULL, &err);
674
675 while (gtk_events_pending ())
676 gtk_main_iteration ();
677 }
678 while (status == G_IO_STATUS_AGAIN);
679
680 if (status != G_IO_STATUS_NORMAL)
681 {
682 if (err)
683 {
684 g_printerr ("yad_form_handle_stdin(): %s\n", err->message);
685 g_error_free (err);
686 err = NULL;
687 }
688 /* stop handling */
689 g_io_channel_shutdown (ch, TRUE, NULL);
690 return FALSE;
691 }
692
693 strip_new_line (string->str);
694 if (string->str[0])
695 {
696 if (string->str[0] == '\014')
697 {
698 gint i;
699 /* clear the form and reset fields counter */
700 for (i = 0; i < n_fields; i++)
701 set_field_value (i, "");
702 cnt = -1; /* must be -1 due to next increment */
703 }
704 else
705 set_field_value (cnt, string->str);
706 }
707 cnt++;
708 }
709 while (g_io_channel_get_buffer_condition (ch) == G_IO_IN);
710 g_string_free (string, TRUE);
711 }
712
713 if ((cond != G_IO_IN) && (cond != G_IO_IN + G_IO_HUP))
714 {
715 g_io_channel_shutdown (ch, TRUE, NULL);
716 return FALSE;
717 }
718
719 return TRUE;
720 }
721
722 GtkWidget *
form_create_widget(GtkWidget * dlg)723 form_create_widget (GtkWidget * dlg)
724 {
725 GtkWidget *tbl, *w = NULL;
726 GList *filt;
727
728 if (options.form_data.fields)
729 {
730 GtkWidget *l, *e;
731 GdkPixbuf *pb;
732 guint i, col, row, rows;
733
734 n_fields = g_slist_length (options.form_data.fields);
735
736 row = col = 0;
737 rows = n_fields / options.form_data.columns;
738 if (n_fields % options.form_data.columns > 0)
739 rows++;
740
741 tbl = gtk_grid_new ();
742 gtk_grid_set_row_spacing (GTK_GRID (tbl), 5);
743 gtk_grid_set_column_spacing (GTK_GRID (tbl), 5);
744
745 if (options.form_data.scroll)
746 {
747 GtkWidget *sw = gtk_scrolled_window_new (NULL, NULL);
748 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_NONE);
749 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), options.hscroll_policy, options.vscroll_policy);
750 gtk_container_add (GTK_CONTAINER (sw), tbl);
751 w = sw;
752 }
753 else
754 w = tbl;
755
756 /* create form */
757 for (i = 0; i < n_fields; i++)
758 {
759 YadField *fld = g_slist_nth_data (options.form_data.fields, i);
760
761 /* add field label */
762 l = NULL;
763 if (fld->type != YAD_FIELD_CHECK && fld->type != YAD_FIELD_BUTTON &&
764 fld->type != YAD_FIELD_FULL_BUTTON && fld->type != YAD_FIELD_LINK &&
765 fld->type != YAD_FIELD_LABEL && fld->type != YAD_FIELD_TEXT)
766 {
767 gchar *buf;
768
769 if (fld->name)
770 buf = g_strcompress (fld->name);
771 else
772 buf = g_strdup ("");
773
774 l = gtk_label_new (NULL);
775 if (!options.data.no_markup)
776 {
777 gtk_label_set_markup_with_mnemonic (GTK_LABEL (l), buf);
778 if (fld->tip)
779 gtk_widget_set_tooltip_markup (l, fld->tip);
780 }
781 else
782 {
783 gtk_label_set_text_with_mnemonic (GTK_LABEL (l), buf);
784 if (fld->tip)
785 gtk_widget_set_tooltip_text (l, fld->tip);
786 }
787 gtk_widget_set_name (l, "yad-form-flabel");
788 gtk_label_set_xalign (GTK_LABEL (l), options.common_data.align);
789 gtk_grid_attach (GTK_GRID (tbl), l, col * 2, row, 1, 1);
790 g_free (buf);
791 }
792
793 /* add field entry */
794 switch (fld->type)
795 {
796 case YAD_FIELD_SIMPLE:
797 case YAD_FIELD_HIDDEN:
798 case YAD_FIELD_READ_ONLY:
799 case YAD_FIELD_COMPLETE:
800 e = gtk_entry_new ();
801 gtk_widget_set_name (e, "yad-form-entry");
802 if (fld->tip)
803 {
804 if (!options.data.no_markup)
805 gtk_widget_set_tooltip_markup (e, fld->tip);
806 else
807 gtk_widget_set_tooltip_text (e, fld->tip);
808 }
809 g_signal_connect (G_OBJECT (e), "activate", G_CALLBACK (form_activate_cb), dlg);
810 if (fld->type == YAD_FIELD_HIDDEN)
811 gtk_entry_set_visibility (GTK_ENTRY (e), FALSE);
812 else if (fld->type == YAD_FIELD_READ_ONLY)
813 gtk_widget_set_sensitive (e, FALSE);
814 gtk_grid_attach (GTK_GRID (tbl), e, 1 + col * 2, row, 1, 1);
815 gtk_widget_set_hexpand (e, TRUE);
816
817 if (fld->type == YAD_FIELD_COMPLETE)
818 {
819 GtkEntryCompletion *c = gtk_entry_completion_new ();
820 GtkListStore *m = gtk_list_store_new (1, G_TYPE_STRING);
821
822 gtk_entry_set_completion (GTK_ENTRY (e), c);
823 gtk_entry_completion_set_model (c, GTK_TREE_MODEL (m));
824 gtk_entry_completion_set_text_column (c, 0);
825
826 if (options.common_data.complete != YAD_COMPLETE_SIMPLE)
827 gtk_entry_completion_set_match_func (c, check_complete, NULL, NULL);
828
829 g_object_unref (m);
830 g_object_unref (c);
831 }
832
833 gtk_label_set_mnemonic_widget (GTK_LABEL (l), e);
834 fields = g_slist_append (fields, e);
835 break;
836
837 case YAD_FIELD_NUM:
838 e = gtk_spin_button_new_with_range (0.0, 65525.0, 1.0);
839 gtk_widget_set_name (e, "yad-form-spin");
840 if (fld->tip)
841 {
842 if (!options.data.no_markup)
843 gtk_widget_set_tooltip_markup (e, fld->tip);
844 else
845 gtk_widget_set_tooltip_text (e, fld->tip);
846 }
847 gtk_entry_set_alignment (GTK_ENTRY (e), 1.0);
848 gtk_grid_attach (GTK_GRID (tbl), e, 1 + col * 2, row, 1, 1);
849 gtk_widget_set_hexpand (e, TRUE);
850 gtk_label_set_mnemonic_widget (GTK_LABEL (l), e);
851 fields = g_slist_append (fields, e);
852 break;
853
854 case YAD_FIELD_CHECK:
855 {
856 gchar *buf;
857 if (fld->name)
858 buf = g_strcompress (fld->name);
859 else
860 buf = g_strdup ("");
861 e = gtk_check_button_new_with_label (buf);
862 gtk_widget_set_name (e, "yad-form-check");
863 if (fld->tip)
864 {
865 if (!options.data.no_markup)
866 gtk_widget_set_tooltip_markup (e, fld->tip);
867 else
868 gtk_widget_set_tooltip_text (e, fld->tip);
869 }
870 gtk_grid_attach (GTK_GRID (tbl), e, col * 2, row, 2, 1);
871 gtk_widget_set_hexpand (e, TRUE);
872 fields = g_slist_append (fields, e);
873 g_free (buf);
874 }
875 break;
876
877 case YAD_FIELD_COMBO:
878 e = gtk_combo_box_text_new ();
879 gtk_widget_set_name (e, "yad-form-combo");
880 if (fld->tip)
881 {
882 if (!options.data.no_markup)
883 gtk_widget_set_tooltip_markup (e, fld->tip);
884 else
885 gtk_widget_set_tooltip_text (e, fld->tip);
886 }
887 gtk_grid_attach (GTK_GRID (tbl), e, 1 + col * 2, row, 1, 1);
888 gtk_widget_set_hexpand (e, TRUE);
889 gtk_label_set_mnemonic_widget (GTK_LABEL (l), e);
890 fields = g_slist_append (fields, e);
891 break;
892
893 case YAD_FIELD_COMBO_ENTRY:
894 e = gtk_combo_box_text_new_with_entry ();
895 gtk_widget_set_name (e, "yad-form-edit-combo");
896 if (fld->tip)
897 {
898 if (!options.data.no_markup)
899 gtk_widget_set_tooltip_markup (e, fld->tip);
900 else
901 gtk_widget_set_tooltip_text (e, fld->tip);
902 }
903 gtk_grid_attach (GTK_GRID (tbl), e, 1 + col * 2, row, 1, 1);
904 gtk_widget_set_hexpand (e, TRUE);
905 gtk_label_set_mnemonic_widget (GTK_LABEL (l), e);
906 fields = g_slist_append (fields, e);
907 break;
908
909 case YAD_FIELD_FILE:
910 e = gtk_file_chooser_button_new (_("Select file"), GTK_FILE_CHOOSER_ACTION_OPEN);
911 gtk_widget_set_name (e, "yad-form-file");
912 if (fld->tip)
913 {
914 if (!options.data.no_markup)
915 gtk_widget_set_tooltip_markup (e, fld->tip);
916 else
917 gtk_widget_set_tooltip_text (e, fld->tip);
918 }
919 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (e), g_get_current_dir ());
920 gtk_grid_attach (GTK_GRID (tbl), e, 1 + col * 2, row, 1, 1);
921 gtk_widget_set_hexpand (e, TRUE);
922 gtk_label_set_mnemonic_widget (GTK_LABEL (l), e);
923 fields = g_slist_append (fields, e);
924
925 /* add preview */
926 if (options.common_data.preview)
927 {
928 GtkWidget *p = gtk_image_new ();
929 gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (e), p);
930 g_signal_connect (e, "update-preview", G_CALLBACK (update_preview), p);
931 }
932
933 /* add filters */
934 for (filt = options.common_data.filters; filt; filt = filt->next)
935 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (e), GTK_FILE_FILTER (filt->data));
936
937 break;
938
939 case YAD_FIELD_DIR:
940 e = gtk_file_chooser_button_new (_("Select folder"), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
941 gtk_widget_set_name (e, "yad-form-file");
942 if (fld->tip)
943 {
944 if (!options.data.no_markup)
945 gtk_widget_set_tooltip_markup (e, fld->tip);
946 else
947 gtk_widget_set_tooltip_text (e, fld->tip);
948 }
949 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (e), g_get_current_dir ());
950 gtk_grid_attach (GTK_GRID (tbl), e, 1 + col * 2, row, 1, 1);
951 gtk_widget_set_hexpand (e, TRUE);
952 gtk_label_set_mnemonic_widget (GTK_LABEL (l), e);
953 fields = g_slist_append (fields, e);
954 break;
955
956 case YAD_FIELD_FONT:
957 e = gtk_font_button_new ();
958 gtk_widget_set_name (e, "yad-form-font");
959 if (fld->tip)
960 {
961 if (!options.data.no_markup)
962 gtk_widget_set_tooltip_markup (e, fld->tip);
963 else
964 gtk_widget_set_tooltip_text (e, fld->tip);
965 }
966 gtk_grid_attach (GTK_GRID (tbl), e, 1 + col * 2, row, 1, 1);
967 gtk_widget_set_hexpand (e, TRUE);
968 gtk_label_set_mnemonic_widget (GTK_LABEL (l), e);
969 fields = g_slist_append (fields, e);
970 break;
971
972 case YAD_FIELD_APP:
973 e = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
974 if (fld->tip)
975 {
976 if (!options.data.no_markup)
977 gtk_widget_set_tooltip_markup (e, fld->tip);
978 else
979 gtk_widget_set_tooltip_text (e, fld->tip);
980 }
981 gtk_grid_attach (GTK_GRID (tbl), e, 1 + col * 2, row, 1, 1);
982 gtk_widget_set_hexpand (e, TRUE);
983 gtk_label_set_mnemonic_widget (GTK_LABEL (l), e);
984 fields = g_slist_append (fields, e);
985 break;
986
987 case YAD_FIELD_COLOR:
988 e = gtk_color_button_new ();
989 gtk_widget_set_name (e, "yad-form-color");
990 if (fld->tip)
991 {
992 if (!options.data.no_markup)
993 gtk_widget_set_tooltip_markup (e, fld->tip);
994 else
995 gtk_widget_set_tooltip_text (e, fld->tip);
996 }
997 gtk_grid_attach (GTK_GRID (tbl), e, 1 + col * 2, row, 1, 1);
998 gtk_widget_set_hexpand (e, TRUE);
999 gtk_label_set_mnemonic_widget (GTK_LABEL (l), e);
1000 fields = g_slist_append (fields, e);
1001 break;
1002
1003 case YAD_FIELD_MFILE:
1004 case YAD_FIELD_MDIR:
1005 e = gtk_entry_new ();
1006 gtk_widget_set_name (e, "yad-form-entry");
1007 if (fld->tip)
1008 {
1009 if (!options.data.no_markup)
1010 gtk_widget_set_tooltip_markup (e, fld->tip);
1011 else
1012 gtk_widget_set_tooltip_text (e, fld->tip);
1013 }
1014 gtk_entry_set_icon_from_icon_name (GTK_ENTRY (e), GTK_ENTRY_ICON_SECONDARY, "document-open");
1015 g_signal_connect (G_OBJECT (e), "icon-press", G_CALLBACK (select_files_cb), GINT_TO_POINTER (fld->type));
1016 g_signal_connect (G_OBJECT (e), "activate", G_CALLBACK (form_activate_cb), dlg);
1017 gtk_grid_attach (GTK_GRID (tbl), e, 1 + col * 2, row, 1, 1);
1018 gtk_widget_set_hexpand (e, TRUE);
1019 gtk_label_set_mnemonic_widget (GTK_LABEL (l), e);
1020 fields = g_slist_append (fields, e);
1021 break;
1022
1023 case YAD_FIELD_FILE_SAVE:
1024 case YAD_FIELD_DIR_CREATE:
1025 e = gtk_entry_new ();
1026 gtk_widget_set_name (e, "yad-form-entry");
1027 if (fld->tip)
1028 {
1029 if (!options.data.no_markup)
1030 gtk_widget_set_tooltip_markup (e, fld->tip);
1031 else
1032 gtk_widget_set_tooltip_text (e, fld->tip);
1033 }
1034 gtk_entry_set_icon_from_icon_name (GTK_ENTRY (e), GTK_ENTRY_ICON_SECONDARY, "document-open");
1035 g_signal_connect (G_OBJECT (e), "icon-press", G_CALLBACK (create_files_cb), GINT_TO_POINTER (fld->type));
1036 g_signal_connect (G_OBJECT (e), "activate", G_CALLBACK (form_activate_cb), dlg);
1037 gtk_grid_attach (GTK_GRID (tbl), e, 1 + col * 2, row, 1, 1);
1038 gtk_widget_set_hexpand (e, TRUE);
1039 gtk_label_set_mnemonic_widget (GTK_LABEL (l), e);
1040 fields = g_slist_append (fields, e);
1041 break;
1042
1043 case YAD_FIELD_DATE:
1044 e = gtk_entry_new ();
1045 gtk_widget_set_name (e, "yad-form-entry");
1046 if (fld->tip)
1047 {
1048 if (!options.data.no_markup)
1049 gtk_widget_set_tooltip_markup (e, fld->tip);
1050 else
1051 gtk_widget_set_tooltip_text (e, fld->tip);
1052 }
1053 pb = gdk_pixbuf_new_from_xpm_data (calendar_xpm);
1054 gtk_entry_set_icon_from_pixbuf (GTK_ENTRY (e), GTK_ENTRY_ICON_SECONDARY, pb);
1055 g_object_unref (pb);
1056 g_signal_connect (G_OBJECT (e), "icon-press", G_CALLBACK (select_date_cb), e);
1057 g_signal_connect (G_OBJECT (e), "activate", G_CALLBACK (form_activate_cb), dlg);
1058 gtk_grid_attach (GTK_GRID (tbl), e, 1 + col * 2, row, 1, 1);
1059 gtk_widget_set_hexpand (e, TRUE);
1060 gtk_label_set_mnemonic_widget (GTK_LABEL (l), e);
1061 fields = g_slist_append (fields, e);
1062 break;
1063
1064 case YAD_FIELD_SCALE:
1065 e = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, 0.0, 100.0, 1.0);
1066 gtk_widget_set_name (e, "yad-form-scale");
1067 if (fld->tip)
1068 {
1069 if (!options.data.no_markup)
1070 gtk_widget_set_tooltip_markup (e, fld->tip);
1071 else
1072 gtk_widget_set_tooltip_text (e, fld->tip);
1073 }
1074 gtk_scale_set_value_pos (GTK_SCALE (e), GTK_POS_LEFT);
1075 gtk_grid_attach (GTK_GRID (tbl), e, 1 + col * 2, row, 1, 1);
1076 gtk_widget_set_hexpand (e, TRUE);
1077 gtk_label_set_mnemonic_widget (GTK_LABEL (l), e);
1078 fields = g_slist_append (fields, e);
1079 break;
1080
1081 case YAD_FIELD_BUTTON:
1082 case YAD_FIELD_FULL_BUTTON:
1083 e = gtk_button_new ();
1084 gtk_widget_set_name (e, "yad-form-button");
1085 if (fld->tip)
1086 {
1087 if (!options.data.no_markup)
1088 gtk_widget_set_tooltip_markup (e, fld->tip);
1089 else
1090 gtk_widget_set_tooltip_text (e, fld->tip);
1091 }
1092 g_signal_connect (G_OBJECT (e), "clicked", G_CALLBACK (button_clicked_cb), NULL);
1093 gtk_container_add (GTK_CONTAINER (e), get_label (fld->name, 2, e));
1094 if (fld->type == YAD_FIELD_BUTTON)
1095 gtk_button_set_relief (GTK_BUTTON (e), GTK_RELIEF_NONE);
1096 gtk_grid_attach (GTK_GRID (tbl), e, col * 2, row, 2, 1);
1097 gtk_widget_set_hexpand (e, TRUE);
1098 fields = g_slist_append (fields, e);
1099 break;
1100
1101 case YAD_FIELD_LINK:
1102 {
1103 gchar *buf;
1104 if (fld->name)
1105 buf = g_strdup (fld->name[0] ? fld->name : _("Link"));
1106 else
1107 buf = g_strdup (_("Link"));
1108
1109 e = gtk_link_button_new_with_label ("", buf);
1110 gtk_widget_set_name (e, "yad-form-link");
1111 if (fld->tip)
1112 {
1113 if (!options.data.no_markup)
1114 gtk_widget_set_tooltip_markup (e, fld->tip);
1115 else
1116 gtk_widget_set_tooltip_text (e, fld->tip);
1117 }
1118 g_signal_connect (G_OBJECT (e), "activate-link", G_CALLBACK (link_clicked_cb), NULL);
1119 gtk_grid_attach (GTK_GRID (tbl), e, col * 2, row, 2, 1);
1120 gtk_widget_set_hexpand (e, TRUE);
1121 fields = g_slist_append (fields, e);
1122 g_free (buf);
1123 break;
1124 }
1125
1126 case YAD_FIELD_LABEL:
1127 if (fld->name && fld->name[0])
1128 {
1129 gchar *buf = g_strcompress (fld->name);
1130 e = gtk_label_new (NULL);
1131 gtk_widget_set_name (e, "yad-form-label");
1132 if (fld->tip)
1133 {
1134 if (!options.data.no_markup)
1135 gtk_widget_set_tooltip_markup (e, fld->tip);
1136 else
1137 gtk_widget_set_tooltip_text (e, fld->tip);
1138 }
1139 if (options.data.no_markup)
1140 gtk_label_set_text (GTK_LABEL (e), buf);
1141 else
1142 gtk_label_set_markup (GTK_LABEL (e), buf);
1143 gtk_label_set_line_wrap (GTK_LABEL (e), TRUE);
1144 gtk_label_set_selectable (GTK_LABEL (e), options.data.selectable_labels);
1145 gtk_label_set_xalign (GTK_LABEL (e), options.common_data.align);
1146 g_free (buf);
1147 }
1148 else
1149 {
1150 e = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
1151 gtk_widget_set_name (e, "yad-form-separator");
1152 }
1153 gtk_grid_attach (GTK_GRID (tbl), e, col * 2, row, 2, 1);
1154 gtk_widget_set_hexpand (e, TRUE);
1155 fields = g_slist_append (fields, e);
1156 break;
1157
1158 case YAD_FIELD_TEXT:
1159 {
1160 GtkWidget *l, *sw, *b;
1161 gchar *ltxt;
1162
1163 if (fld->name)
1164 ltxt = g_strcompress (fld->name);
1165 else
1166 ltxt = g_strdup ("");
1167
1168 b = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
1169 l = gtk_label_new ("");
1170 gtk_label_set_xalign (GTK_LABEL (l), 0.0);
1171 if (options.data.no_markup)
1172 gtk_label_set_text (GTK_LABEL (l), ltxt);
1173 else
1174 gtk_label_set_markup (GTK_LABEL (l), ltxt);
1175 g_free (ltxt);
1176 gtk_box_pack_start (GTK_BOX (b), l, FALSE, FALSE, 0);
1177
1178 sw = gtk_scrolled_window_new (NULL, NULL);
1179 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_ETCHED_IN);
1180 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), options.hscroll_policy, options.vscroll_policy);
1181 gtk_box_pack_start (GTK_BOX (b), sw, TRUE, TRUE, 0);
1182
1183 e = gtk_text_view_new ();
1184 gtk_widget_set_name (e, "yad-form-text");
1185 if (fld->tip)
1186 {
1187 if (!options.data.no_markup)
1188 gtk_widget_set_tooltip_markup (e, fld->tip);
1189 else
1190 gtk_widget_set_tooltip_text (e, fld->tip);
1191 }
1192 gtk_text_view_set_editable (GTK_TEXT_VIEW (e), TRUE);
1193 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (e), GTK_WRAP_WORD_CHAR);
1194 gtk_container_add (GTK_CONTAINER (sw), e);
1195
1196 #ifdef HAVE_SPELL
1197 if (options.common_data.enable_spell)
1198 {
1199 GspellTextView *spell_view = gspell_text_view_get_from_gtk_text_view (GTK_TEXT_VIEW (e));
1200 gspell_text_view_basic_setup (spell_view);
1201 }
1202 #endif
1203
1204 gtk_grid_attach (GTK_GRID (tbl), b, col * 2, row, 2, 1);
1205 gtk_widget_set_hexpand (b, TRUE);
1206 gtk_widget_set_vexpand (b, TRUE);
1207 gtk_label_set_mnemonic_widget (GTK_LABEL (l), e);
1208 fields = g_slist_append (fields, e);
1209
1210 break;
1211 }
1212 }
1213
1214 /* increase row and column */
1215 row++;
1216 if (row >= rows)
1217 {
1218 row = 0;
1219 col++;
1220 }
1221 }
1222
1223 /* fill entries with data */
1224 if (options.extra_data)
1225 {
1226 i = 0;
1227 while (options.extra_data[i] && i < n_fields)
1228 {
1229 set_field_value (i, options.extra_data[i]);
1230 i++;
1231 }
1232 }
1233 else
1234 {
1235 GIOChannel *channel = g_io_channel_unix_new (0);
1236 g_io_channel_set_encoding (channel, NULL, NULL);
1237 g_io_channel_set_flags (channel, G_IO_FLAG_NONBLOCK, NULL);
1238 g_io_add_watch (channel, G_IO_IN | G_IO_HUP, handle_stdin, NULL);
1239 }
1240 }
1241
1242 if (options.form_data.focus_field > 0 && options.form_data.focus_field <= n_fields)
1243 gtk_widget_grab_focus (GTK_WIDGET (g_slist_nth_data (fields, options.form_data.focus_field - 1)));
1244
1245 return w;
1246 }
1247
1248 static void
form_print_field(guint fn)1249 form_print_field (guint fn)
1250 {
1251 gchar *buf;
1252 YadField *fld = g_slist_nth_data (options.form_data.fields, fn);
1253
1254 switch (fld->type)
1255 {
1256 case YAD_FIELD_SIMPLE:
1257 case YAD_FIELD_HIDDEN:
1258 case YAD_FIELD_READ_ONLY:
1259 case YAD_FIELD_COMPLETE:
1260 case YAD_FIELD_MFILE:
1261 case YAD_FIELD_MDIR:
1262 case YAD_FIELD_FILE_SAVE:
1263 case YAD_FIELD_DIR_CREATE:
1264 case YAD_FIELD_DATE:
1265 if (options.common_data.quoted_output)
1266 {
1267 buf = g_shell_quote (gtk_entry_get_text (GTK_ENTRY (g_slist_nth_data (fields, fn))));
1268 g_printf ("%s%s", buf, options.common_data.separator);
1269 g_free (buf);
1270 }
1271 else
1272 g_printf ("%s%s", gtk_entry_get_text (GTK_ENTRY (g_slist_nth_data (fields, fn))),
1273 options.common_data.separator);
1274 break;
1275 case YAD_FIELD_NUM:
1276 {
1277 guint prec = gtk_spin_button_get_digits (GTK_SPIN_BUTTON (g_slist_nth_data (fields, fn)));
1278 if (options.common_data.quoted_output)
1279 g_printf ("'%.*f'%s", prec, gtk_spin_button_get_value (GTK_SPIN_BUTTON (g_slist_nth_data (fields, fn))),
1280 options.common_data.separator);
1281 else
1282 g_printf ("%.*f%s", prec, gtk_spin_button_get_value (GTK_SPIN_BUTTON (g_slist_nth_data (fields, fn))),
1283 options.common_data.separator);
1284 break;
1285 }
1286 case YAD_FIELD_CHECK:
1287 if (options.common_data.quoted_output)
1288 g_printf ("'%s'%s", print_bool_val (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (g_slist_nth_data (fields, fn)))),
1289 options.common_data.separator);
1290 else
1291 g_printf ("%s%s", print_bool_val (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (g_slist_nth_data (fields, fn)))),
1292 options.common_data.separator);
1293 break;
1294 case YAD_FIELD_COMBO:
1295 case YAD_FIELD_COMBO_ENTRY:
1296 if (options.common_data.num_output && fld->type == YAD_FIELD_COMBO)
1297 g_printf ("%d%s", gtk_combo_box_get_active (GTK_COMBO_BOX (g_slist_nth_data (fields, fn))) + 1,
1298 options.common_data.separator);
1299 else if (options.common_data.quoted_output)
1300 {
1301 buf = g_shell_quote (gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (g_slist_nth_data (fields, fn))));
1302 g_printf ("%s%s", buf, options.common_data.separator);
1303 g_free (buf);
1304 }
1305 else
1306 g_printf ("%s%s", gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (g_slist_nth_data (fields, fn))),
1307 options.common_data.separator);
1308 break;
1309 case YAD_FIELD_FILE:
1310 case YAD_FIELD_DIR:
1311 if (options.common_data.quoted_output)
1312 {
1313 gchar *fname = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (g_slist_nth_data (fields, fn)));
1314 buf = g_shell_quote (fname ? fname : "");
1315 g_free (fname);
1316 g_printf ("%s%s", buf ? buf : "", options.common_data.separator);
1317 g_free (buf);
1318 }
1319 else
1320 {
1321 buf = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (g_slist_nth_data (fields, fn)));
1322 g_printf ("%s%s", buf ? buf : "", options.common_data.separator);
1323 g_free (buf);
1324 }
1325 break;
1326 case YAD_FIELD_FONT:
1327 {
1328 gchar *fname = gtk_font_chooser_get_font (GTK_FONT_CHOOSER (g_slist_nth_data (fields, fn)));
1329 if (options.common_data.quoted_output)
1330 g_printf ("'%s'%s", fname ? fname : "", options.common_data.separator);
1331 else
1332 g_printf ("%s%s", fname ? fname : "", options.common_data.separator);
1333 g_free (fname);
1334 break;
1335 }
1336 case YAD_FIELD_APP:
1337 {
1338 gchar *exec;
1339 GAppInfo *info = NULL;
1340 GList *wl = gtk_container_get_children (GTK_CONTAINER (g_slist_nth_data (fields, fn)));
1341
1342 if (wl)
1343 {
1344 info = gtk_app_chooser_get_app_info (GTK_APP_CHOOSER (wl->data));
1345 if (info)
1346 exec = (gchar *) g_app_info_get_executable (info);
1347 else
1348 exec = "";
1349 }
1350 else
1351 exec = "";
1352
1353 if (options.common_data.quoted_output)
1354 {
1355 buf = g_shell_quote (exec);
1356 g_printf ("%s%s", buf, options.common_data.separator);
1357 g_free (buf);
1358 }
1359 else
1360 g_printf ("%s%s", exec, options.common_data.separator);
1361 if (info)
1362 g_object_unref (info);
1363 break;
1364 }
1365 case YAD_FIELD_COLOR:
1366 {
1367 gchar *cs;
1368 GdkRGBA c;
1369 GtkColorChooser *cb = GTK_COLOR_CHOOSER (g_slist_nth_data (fields, fn));
1370 gtk_color_chooser_get_rgba (cb, &c);
1371 cs = get_color (&c);
1372
1373 if (options.common_data.quoted_output)
1374 {
1375 buf = g_shell_quote (cs ? cs : "");
1376 g_printf ("%s%s", buf, options.common_data.separator);
1377 g_free (buf);
1378 }
1379 else
1380 g_printf ("%s%s", cs, options.common_data.separator);
1381 g_free (cs);
1382 break;
1383 }
1384 case YAD_FIELD_SCALE:
1385 if (options.common_data.quoted_output)
1386 g_printf ("'%d'%s", (gint) gtk_range_get_value (GTK_RANGE (g_slist_nth_data (fields, fn))),
1387 options.common_data.separator);
1388 else
1389 g_printf ("%d%s", (gint) gtk_range_get_value (GTK_RANGE (g_slist_nth_data (fields, fn))),
1390 options.common_data.separator);
1391 break;
1392 case YAD_FIELD_LINK:
1393 if (options.common_data.quoted_output)
1394 {
1395 buf = g_shell_quote (gtk_link_button_get_uri (GTK_LINK_BUTTON (g_slist_nth_data (fields, fn))));
1396 g_printf ("%s%s", buf, options.common_data.separator);
1397 g_free (buf);
1398 }
1399 else
1400 g_printf ("%s%s", gtk_link_button_get_uri (GTK_LINK_BUTTON (g_slist_nth_data (fields, fn))),
1401 options.common_data.separator);
1402 break;
1403 case YAD_FIELD_BUTTON:
1404 case YAD_FIELD_FULL_BUTTON:
1405 case YAD_FIELD_LABEL:
1406 if (options.common_data.quoted_output)
1407 g_printf ("''%s", options.common_data.separator);
1408 else
1409 g_printf ("%s", options.common_data.separator);
1410 break;
1411 case YAD_FIELD_TEXT:
1412 {
1413 gchar *txt;
1414 GtkTextBuffer *tb;
1415 GtkTextIter b, e;
1416
1417 tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (g_slist_nth_data (fields, fn)));
1418 gtk_text_buffer_get_bounds (tb, &b, &e);
1419 txt = escape_str (gtk_text_buffer_get_text (tb, &b, &e, FALSE));
1420 if (options.common_data.quoted_output)
1421 {
1422 buf = g_shell_quote (txt);
1423 g_printf ("%s%s", buf, options.common_data.separator);
1424 g_free (buf);
1425 }
1426 else
1427 g_printf ("%s%s", txt, options.common_data.separator);
1428 g_free (txt);
1429 }
1430 }
1431 }
1432
1433 void
form_print_result(void)1434 form_print_result (void)
1435 {
1436 guint i;
1437
1438 if (options.form_data.output_by_row)
1439 {
1440 guint j, rows;
1441
1442 rows = n_fields / options.form_data.columns;
1443 rows += (n_fields % options.form_data.columns ? 1 : 0);
1444 for (i = 0; i < rows; i++)
1445 {
1446 for (j = 0; j < options.form_data.columns; j++)
1447 {
1448 guint fld = i + rows * j;
1449 if (fld < n_fields)
1450 form_print_field (fld);
1451 }
1452 }
1453 }
1454 else
1455 {
1456 for (i = 0; i < n_fields; i++)
1457 form_print_field (i);
1458 }
1459 g_printf ("\n");
1460 }
1461