1 /*
2 * gretl -- Gnu Regression, Econometrics and Time-series Library
3 * Copyright (C) 2001 Allin Cottrell and Riccardo "Jack" Lucchetti
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 */
19
20 /* dlgutils.c for gretl: utilities for composing dialog boxes */
21
22 #include "gretl.h"
23 #include "textbuf.h"
24 #include "menustate.h"
25 #include "tabwin.h"
26 #include "dlgutils.h"
27
28 #include "libset.h"
29 #include "system.h"
30 #include "gretl_bfgs.h"
31
dialog_opts_new(int n,int type,gretlopt * optp,const gretlopt * vals,const char ** strs)32 dialog_opts *dialog_opts_new (int n, int type,
33 gretlopt *optp,
34 const gretlopt *vals,
35 const char **strs)
36 {
37 dialog_opts *opts;
38
39 opts = malloc(sizeof *opts);
40 if (opts == NULL) {
41 nomem();
42 return NULL;
43 }
44
45 opts->n = n;
46 opts->type = type;
47 opts->optp = optp;
48 opts->vals = vals;
49 opts->strs = strs;
50
51 return opts;
52 }
53
dialog_opts_free(dialog_opts * opts)54 void dialog_opts_free (dialog_opts *opts)
55 {
56 free(opts);
57 }
58
vbox_add_hsep(GtkWidget * vbox)59 void vbox_add_hsep (GtkWidget *vbox)
60 {
61 GtkWidget *h = gtk_hseparator_new();
62
63 gtk_box_pack_start(GTK_BOX(vbox), h, FALSE, FALSE, 0);
64 gtk_widget_show(h);
65 }
66
pack_in_hbox(GtkWidget * w,GtkWidget * vbox,int vspace)67 void pack_in_hbox (GtkWidget *w, GtkWidget *vbox, int vspace)
68 {
69 GtkWidget *hbox = gtk_hbox_new(FALSE, 5);
70
71 gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 5);
72 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, vspace);
73 }
74
75 /* Various buttons, usable in several sorts of dialogs */
76
cancel_delete_button(GtkWidget * hbox,GtkWidget * targ)77 GtkWidget *cancel_delete_button (GtkWidget *hbox, GtkWidget *targ)
78 {
79 GtkWidget *button;
80
81 button = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
82 gtk_widget_set_can_default(button, TRUE);
83 gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
84 g_signal_connect(G_OBJECT(button), "clicked",
85 G_CALLBACK(delete_widget),
86 targ);
87
88 return button;
89 }
90
ok_button(GtkWidget * hbox)91 GtkWidget *ok_button (GtkWidget *hbox)
92 {
93 GtkWidget *w;
94
95 w = gtk_button_new_from_stock(GTK_STOCK_OK);
96 gtk_widget_set_can_default(w, TRUE);
97 gtk_container_add(GTK_CONTAINER(hbox), w);
98
99 return w;
100 }
101
set_valid_response(GtkButton * b,int * valptr)102 static void set_valid_response (GtkButton *b, int *valptr)
103 {
104 int *retptr = g_object_get_data(G_OBJECT(b), "retptr");
105
106 if (valptr == NULL) {
107 *retptr = 0;
108 } else {
109 *retptr = *valptr;
110 }
111 }
112
113 /* on "OK": if @valptr is non-NULL, copy the valid value from
114 @valptr to @retptr; otherwise signal all-clear by copying
115 0 to @retptr
116 */
117
ok_validate_button(GtkWidget * hbox,int * retptr,int * valptr)118 GtkWidget *ok_validate_button (GtkWidget *hbox, int *retptr,
119 int *valptr)
120 {
121 GtkWidget *button = ok_button(hbox);
122
123 g_object_set_data(G_OBJECT(button), "retptr", retptr);
124 g_signal_connect(G_OBJECT(button), "clicked",
125 G_CALLBACK(set_valid_response), valptr);
126
127 return button;
128 }
129
apply_button(GtkWidget * hbox)130 GtkWidget *apply_button (GtkWidget *hbox)
131 {
132 GtkWidget *w;
133
134 w = gtk_button_new_from_stock(GTK_STOCK_APPLY);
135 gtk_widget_set_can_default(w, TRUE);
136 gtk_container_add(GTK_CONTAINER(hbox), w);
137
138 return w;
139 }
140
cancel_button(GtkWidget * hbox)141 GtkWidget *cancel_button (GtkWidget *hbox)
142 {
143 GtkWidget *w;
144
145 w = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
146 gtk_widget_set_can_default(w, TRUE);
147 gtk_container_add(GTK_CONTAINER(hbox), w);
148
149 return w;
150 }
151
close_button(GtkWidget * hbox)152 GtkWidget *close_button (GtkWidget *hbox)
153 {
154 GtkWidget *w;
155
156 w = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
157 gtk_widget_set_can_default(w, TRUE);
158 gtk_container_add(GTK_CONTAINER(hbox), w);
159
160 return w;
161 }
162
next_button(GtkWidget * hbox)163 GtkWidget *next_button (GtkWidget *hbox)
164 {
165 GtkWidget *w;
166
167 w = gtk_button_new_from_stock(GTK_STOCK_GO_FORWARD);
168 gtk_widget_set_can_default(w, TRUE);
169 gtk_container_add(GTK_CONTAINER(hbox), w);
170
171 return w;
172 }
173
back_button(GtkWidget * hbox)174 GtkWidget *back_button (GtkWidget *hbox)
175 {
176 GtkWidget *w;
177
178 w = gtk_button_new_from_stock(GTK_STOCK_GO_BACK);
179 gtk_widget_set_can_default(w, TRUE);
180 gtk_container_add(GTK_CONTAINER(hbox), w);
181
182 return w;
183 }
184
set_dialog_border_widths(GtkWidget * ca,GtkWidget * aa)185 static void set_dialog_border_widths (GtkWidget *ca, GtkWidget *aa)
186 {
187 int w1 = 10, w2 = 5;
188
189 gtk_container_set_border_width(GTK_CONTAINER(ca), w1);
190 gtk_box_set_spacing(GTK_BOX(ca), w2);
191 gtk_container_set_border_width(GTK_CONTAINER(aa), w2);
192 }
193
gretl_dialog_set_resizeable(GtkWidget * w,gboolean s)194 static void gretl_dialog_set_resizeable (GtkWidget *w, gboolean s)
195 {
196 gtk_window_set_resizable(GTK_WINDOW(w), s);
197 }
198
199 static GtkWidget *current_dialog;
200 static GtkWidget *open_edit_dialog;
201 static int plugin_dialog_open;
202
maybe_raise_dialog(void)203 int maybe_raise_dialog (void)
204 {
205 int ret = 0;
206
207 if (plugin_dialog_open) {
208 ret = 1;
209 } else if (current_dialog != NULL) {
210 gtk_window_present(GTK_WINDOW(current_dialog));
211 ret = 1;
212 } else if (open_edit_dialog != NULL) {
213 gtk_window_present(GTK_WINDOW(open_edit_dialog));
214 ret = 1;
215 }
216
217 return ret;
218 }
219
set_plugin_dialog_open(gboolean s)220 void set_plugin_dialog_open (gboolean s)
221 {
222 plugin_dialog_open = s;
223 }
224
dialog_unblock(GtkWidget * w,gpointer p)225 static gint dialog_unblock (GtkWidget *w, gpointer p)
226 {
227 gtk_main_quit();
228 current_dialog = NULL;
229 return FALSE;
230 }
231
gretl_dialog_set_destruction(GtkWidget * w,gpointer p)232 gint gretl_dialog_set_destruction (GtkWidget *w, gpointer p)
233 {
234 gtk_window_set_transient_for(GTK_WINDOW(w), GTK_WINDOW(p));
235 gtk_window_set_destroy_with_parent(GTK_WINDOW(w), TRUE);
236
237 if (g_object_get_data(G_OBJECT(p), "tabwin") != NULL) {
238 tabwin_register_dialog(w, p);
239 }
240
241 return FALSE;
242 }
243
gretl_dialog_new(const char * title,GtkWidget * parent,unsigned char flags)244 GtkWidget *gretl_dialog_new (const char *title, GtkWidget *parent,
245 unsigned char flags)
246 {
247 GtkWidget *d = gretl_gtk_dialog();
248 GtkWidget *ca, *aa;
249
250 if (flags & GRETL_DLG_UNDECORATED) {
251 gtk_window_set_decorated(GTK_WINDOW(d), FALSE);
252 } else if (title != NULL) {
253 gtk_window_set_title(GTK_WINDOW(d), title);
254 } else {
255 gtk_window_set_title(GTK_WINDOW(d), "gretl");
256 }
257
258 ca = gtk_dialog_get_content_area(GTK_DIALOG(d));
259 aa = gtk_dialog_get_action_area(GTK_DIALOG(d));
260 gtk_button_box_set_layout(GTK_BUTTON_BOX(aa), GTK_BUTTONBOX_END);
261 set_dialog_border_widths(ca, aa);
262 gtk_window_set_position(GTK_WINDOW(d), GTK_WIN_POS_MOUSE);
263
264 if (flags & GRETL_DLG_BLOCK) {
265 current_dialog = d;
266 }
267
268 if (flags & GRETL_DLG_MODAL) {
269 gretl_set_window_modal(d);
270 } else if (flags & GRETL_DLG_QUASI_MODAL) {
271 gretl_set_window_quasi_modal(d);
272 }
273
274 if (!(flags & GRETL_DLG_RESIZE)) {
275 gretl_dialog_set_resizeable(d, FALSE);
276 }
277
278 if (flags & GRETL_DLG_BLOCK) {
279 g_signal_connect(G_OBJECT(d), "destroy",
280 G_CALLBACK(dialog_unblock), NULL);
281 }
282
283 if (parent == NULL && mdata != NULL) {
284 parent = mdata->main;
285 }
286
287 if (parent != NULL) {
288 g_signal_connect(G_OBJECT(d), "realize", /* was "show" */
289 G_CALLBACK(gretl_dialog_set_destruction),
290 parent);
291 }
292
293 if (flags & GRETL_DLG_BLOCK) {
294 g_signal_connect(G_OBJECT(d), "show",
295 G_CALLBACK(gtk_main), NULL);
296 }
297
298 return d;
299 }
300
sensitize_widget(GtkWidget * b,GtkWidget * w)301 static void sensitize_widget (GtkWidget *b, GtkWidget *w)
302 {
303 gboolean s = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b));
304
305 gtk_widget_set_sensitive(w, s);
306 }
307
308 /* make the sensitivity of widget @w positively dependent on the state
309 of button @b */
310
sensitize_conditional_on(GtkWidget * w,GtkWidget * b)311 void sensitize_conditional_on (GtkWidget *w, GtkWidget *b)
312 {
313 g_signal_connect(G_OBJECT(b), "toggled",
314 G_CALLBACK(sensitize_widget), w);
315 }
316
desensitize_widget(GtkWidget * b,GtkWidget * w)317 static void desensitize_widget (GtkWidget *b, GtkWidget *w)
318 {
319 gboolean s = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b));
320
321 gtk_widget_set_sensitive(w, !s);
322 }
323
324 /* make the sensitivity of widget @w negatively dependent on the state
325 of button @b */
326
desensitize_conditional_on(GtkWidget * w,GtkWidget * b)327 void desensitize_conditional_on (GtkWidget *w, GtkWidget *b)
328 {
329 g_signal_connect(G_OBJECT(b), "toggled",
330 G_CALLBACK(desensitize_widget), w);
331 }
332
set_double_from_spinner(GtkSpinButton * b,double * x)333 void set_double_from_spinner (GtkSpinButton *b, double *x)
334 {
335 *x = gtk_spin_button_get_value(b);
336 }
337
set_int_from_spinner(GtkSpinButton * b,int * k)338 void set_int_from_spinner (GtkSpinButton *b, int *k)
339 {
340 *k = gtk_spin_button_get_value_as_int(b);
341 }
342
toggle_gretl_option(GtkToggleButton * b,gretlopt * popt)343 static void toggle_gretl_option (GtkToggleButton *b, gretlopt *popt)
344 {
345 gretlopt val =
346 GPOINTER_TO_INT(g_object_get_data(G_OBJECT(b), "optval"));
347
348 if (gtk_toggle_button_get_active(b)) {
349 *popt |= val;
350 } else {
351 *popt &= ~val;
352 }
353 }
354
355 /* Create a check button which sets @val in @popt when
356 activated, and unsets the flag when deactivated */
357
gretl_option_check_button(const char * label,gretlopt * popt,gretlopt val)358 GtkWidget *gretl_option_check_button (const char *label,
359 gretlopt *popt,
360 gretlopt val)
361 {
362 GtkWidget *button;
363
364 button = gtk_check_button_new_with_label(label);
365 g_object_set_data(G_OBJECT(button), "optval",
366 GINT_TO_POINTER(val));
367 g_signal_connect(G_OBJECT(button), "toggled",
368 G_CALLBACK(toggle_gretl_option), popt);
369
370 return button;
371 }
372
toggle_gretl_option_switched(GtkToggleButton * b,gretlopt * popt)373 static void toggle_gretl_option_switched (GtkToggleButton *b, gretlopt *popt)
374 {
375 gretlopt val =
376 GPOINTER_TO_INT(g_object_get_data(G_OBJECT(b), "optval"));
377
378 if (gtk_toggle_button_get_active(b)) {
379 *popt &= ~val;
380 } else {
381 *popt |= val;
382 }
383 }
384
385 /* Create a check button which unsets @val in @popt when
386 activated, and sets the flag when deactivated */
387
gretl_option_check_button_switched(const char * label,gretlopt * popt,gretlopt val)388 GtkWidget *gretl_option_check_button_switched (const char *label,
389 gretlopt *popt,
390 gretlopt val)
391 {
392 GtkWidget *button;
393
394 button = gtk_check_button_new_with_label(label);
395 g_object_set_data(G_OBJECT(button), "optval",
396 GINT_TO_POINTER(val));
397 g_signal_connect(G_OBJECT(button), "toggled",
398 G_CALLBACK(toggle_gretl_option_switched), popt);
399
400 return button;
401 }
402
403 /* "edit dialog" apparatus */
404
405 static GtkWidget *active_edit_id;
406 static GtkWidget *active_edit_name;
407 static GtkWidget *active_edit_text;
408
get_active_edit_id(void)409 GtkWidget *get_active_edit_id (void)
410 {
411 return active_edit_id;
412 }
413
get_active_edit_name(void)414 GtkWidget *get_active_edit_name (void)
415 {
416 return active_edit_name;
417 }
418
get_active_edit_text(void)419 GtkWidget *get_active_edit_text (void)
420 {
421 return active_edit_text;
422 }
423
set_active_edit_name(GtkWidget * w)424 void set_active_edit_name (GtkWidget *w)
425 {
426 active_edit_name = w;
427 }
428
429 struct dialog_t_ {
430 int ci;
431 void (*okfunc)();
432 void *data;
433 int blocking;
434 int *cancel;
435 gretlopt opt;
436 GtkWidget *dialog;
437 GtkWidget *vbox;
438 GtkWidget *bbox;
439 GtkWidget *edit;
440 GtkWidget *popup;
441 };
442
destroy_edit_dialog(GtkWidget * w,gpointer data)443 static void destroy_edit_dialog (GtkWidget *w, gpointer data)
444 {
445 dialog_t *d = (dialog_t *) data;
446
447 if (d->blocking) {
448 gtk_main_quit();
449 }
450
451 g_free(d);
452
453 open_edit_dialog = NULL;
454
455 if (active_edit_id) active_edit_id = NULL;
456 if (active_edit_name) active_edit_name = NULL;
457 if (active_edit_text) active_edit_text = NULL;
458 }
459
esc_kills_window(GtkWidget * w,GdkEventKey * key,gpointer p)460 gboolean esc_kills_window (GtkWidget *w, GdkEventKey *key,
461 gpointer p)
462 {
463 if (key->keyval == GDK_Escape) {
464 gtk_widget_destroy(w);
465 return TRUE;
466 } else {
467 return FALSE;
468 }
469 }
470
edit_dialog_new(int ci,const char * title,void (* okfunc)(),void * data,int helpcode,GtkWidget * parent,int * canceled)471 static dialog_t *edit_dialog_new (int ci, const char *title,
472 void (*okfunc)(), void *data,
473 int helpcode, GtkWidget *parent,
474 int *canceled)
475 {
476 dialog_t *d = mymalloc(sizeof *d);
477
478 if (d == NULL) {
479 return NULL;
480 }
481
482 d->ci = ci;
483 d->okfunc = okfunc;
484 d->data = data;
485 d->opt = OPT_NONE;
486 d->popup = NULL;
487 d->blocking = 0;
488 d->cancel = canceled;
489
490 d->dialog = gretl_gtk_dialog();
491 d->vbox = gtk_dialog_get_content_area(GTK_DIALOG(d->dialog));
492 d->bbox = gtk_dialog_get_action_area(GTK_DIALOG(d->dialog));
493
494 if (canceled != NULL) {
495 *canceled = 1; /* will be undone by "OK" */
496 d->blocking = 1;
497 }
498
499 if (!strncmp(title, "gretl", 5)) {
500 gtk_window_set_title(GTK_WINDOW(d->dialog), title);
501 } else {
502 gchar *tmp = g_strdup_printf("gretl: %s", title);
503
504 gtk_window_set_title(GTK_WINDOW(d->dialog), tmp);
505 g_free(tmp);
506 }
507
508 gtk_box_set_homogeneous(GTK_BOX(d->bbox), TRUE);
509 gtk_window_set_position(GTK_WINDOW(d->dialog), GTK_WIN_POS_MOUSE);
510
511 if (parent == NULL) {
512 parent = mdata->main;
513 }
514
515 g_signal_connect(G_OBJECT(d->dialog), "destroy",
516 G_CALLBACK(destroy_edit_dialog), d);
517 g_signal_connect(G_OBJECT(d->dialog), "key-press-event",
518 G_CALLBACK(esc_kills_window), NULL);
519 g_signal_connect(G_OBJECT(d->dialog), "show",
520 G_CALLBACK(gretl_dialog_set_destruction), parent);
521 if (d->blocking) {
522 g_signal_connect(G_OBJECT(d->dialog), "show",
523 G_CALLBACK(gtk_main), NULL);
524 }
525
526 return d;
527 }
528
edit_dialog_close(dialog_t * dlg)529 void edit_dialog_close (dialog_t *dlg)
530 {
531 gtk_widget_destroy(dlg->dialog);
532 }
533
534 /* saved material from "complex" edit dialog */
535
536 static int edit_save_code;
537 static char *edit_save_buf;
538
edit_save_buf_clear(void)539 static void edit_save_buf_clear (void)
540 {
541 g_free(edit_save_buf);
542 edit_save_buf = NULL;
543 edit_save_code = 0;
544 }
545
set_edit_save_buf(const char * buf,int code)546 static void set_edit_save_buf (const char *buf, int code)
547 {
548 edit_save_buf_clear();
549
550 if (buf != NULL) {
551 edit_save_buf = g_strdup(buf);
552 edit_save_code = code;
553 }
554 }
555
dlg_text_set_previous(dialog_t * d)556 static int dlg_text_set_previous (dialog_t *d)
557 {
558 if (d->ci == edit_save_code &&
559 edit_save_buf != NULL) {
560 textview_set_text(d->edit, edit_save_buf);
561 return 1;
562 } else {
563 return 0;
564 }
565 }
566
dlg_text_set_skeleton(dialog_t * d)567 static int dlg_text_set_skeleton (dialog_t *d)
568 {
569 const char *gmm_skel =
570 "# initializations go here\n\n\n"
571 "gmm\n"
572 " orthog\n"
573 " weights\n"
574 " params\n"
575 "end gmm\n";
576 const char *sys_skel =
577 "system\n\n"
578 "end system\n";
579
580 if (edit_save_buf == NULL) {
581 if (d->ci == GMM) {
582 textview_set_text(d->edit, gmm_skel);
583 textview_set_cursor_at_line(d->edit, 1);
584 return 1;
585 } else if (d->ci == SYSTEM) {
586 textview_set_text(d->edit, sys_skel);
587 textview_set_cursor_at_line(d->edit, 1);
588 return 1;
589 }
590 }
591
592 return 0;
593 }
594
595 /* end edit saver apparatus */
596
edit_dialog_special_get_text(dialog_t * dlg)597 gchar *edit_dialog_special_get_text (dialog_t *dlg)
598 {
599 gchar *buf;
600
601 if (dlg == NULL) {
602 edit_save_buf_clear();
603 return NULL;
604 }
605
606 buf = textview_get_text(dlg->edit);
607
608 if (buf != NULL && *buf == '\0') {
609 /* nothing was entered */
610 g_free(buf);
611 buf = NULL;
612 }
613
614 if (buf == NULL) {
615 gtk_widget_destroy(dlg->dialog);
616 }
617
618 set_edit_save_buf(buf, dlg->ci);
619
620 return buf;
621 }
622
edit_dialog_get_text(dialog_t * dlg)623 const gchar *edit_dialog_get_text (dialog_t *dlg)
624 {
625 const gchar *buf;
626
627 buf = gtk_entry_get_text(GTK_ENTRY(dlg->edit));
628
629 if (buf == NULL || *buf == '\0') {
630 if (dlg->ci != CORRGM) {
631 gtk_widget_destroy(dlg->dialog);
632 }
633 return NULL;
634 }
635
636 return buf;
637 }
638
edit_dialog_get_action(const dialog_t * dlg)639 int edit_dialog_get_action (const dialog_t *dlg)
640 {
641 return dlg->ci;
642 }
643
edit_dialog_get_opt(const dialog_t * dlg)644 gretlopt edit_dialog_get_opt (const dialog_t *dlg)
645 {
646 return dlg->opt;
647 }
648
edit_dialog_get_data(dialog_t * dlg)649 gpointer edit_dialog_get_data (dialog_t *dlg)
650 {
651 return dlg->data;
652 }
653
edit_dialog_get_window(dialog_t * dlg)654 GtkWidget *edit_dialog_get_window (dialog_t *dlg)
655 {
656 return dlg->dialog;
657 }
658
dialog_table_setup(dialog_t * dlg,int hsize)659 static void dialog_table_setup (dialog_t *dlg, int hsize)
660 {
661 GtkWidget *sw;
662
663 sw = gtk_scrolled_window_new(NULL, NULL);
664 gtk_widget_set_size_request(sw, hsize, 200);
665 gtk_box_pack_start(GTK_BOX(dlg->vbox), sw, TRUE, TRUE, FALSE);
666 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (sw),
667 GTK_POLICY_AUTOMATIC,
668 GTK_POLICY_AUTOMATIC);
669 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (sw),
670 GTK_SHADOW_IN);
671 gtk_container_add(GTK_CONTAINER(sw), dlg->edit);
672 gtk_widget_show(dlg->edit);
673 gtk_widget_show(sw);
674 }
675
dlg_text_edit_new(int * hsize,gboolean s)676 static GtkWidget *dlg_text_edit_new (int *hsize, gboolean s)
677 {
678 GtkTextBuffer *tbuf;
679 GtkWidget *tview;
680
681 tbuf = gtk_text_buffer_new(NULL);
682 tview = gtk_text_view_new_with_buffer(tbuf);
683
684 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(tview), GTK_WRAP_WORD);
685 gtk_text_view_set_left_margin(GTK_TEXT_VIEW(tview), 4);
686 gtk_text_view_set_right_margin(GTK_TEXT_VIEW(tview), 4);
687
688 gtk_widget_modify_font(GTK_WIDGET(tview), fixed_font);
689 *hsize *= get_char_width(tview);
690 *hsize += 48;
691 gtk_text_view_set_editable(GTK_TEXT_VIEW(tview), s);
692 gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(tview), s);
693
694 return tview;
695 }
696
dlg_text_set_from_sys(equation_system * sys,dialog_t * d)697 static void dlg_text_set_from_sys (equation_system *sys,
698 dialog_t *d)
699 {
700 const char *buf;
701 PRN *prn;
702
703 if (bufopen(&prn)) {
704 return;
705 }
706
707 print_equation_system_info(sys, dataset, OPT_NONE, prn);
708 buf = gretl_print_get_buffer(prn);
709 textview_set_text(d->edit, buf);
710 gretl_print_destroy(prn);
711 }
712
713 enum {
714 ADD_EQN,
715 ADD_DERIV,
716 ADD_IDENT,
717 ADD_ENDO_LIST,
718 ADD_INSTR_LIST
719 };
720
edit_has_list(GtkWidget * w,int i)721 static int edit_has_list (GtkWidget *w, int i)
722 {
723 gchar *buf;
724 int ret = 0;
725
726 buf = textview_get_text(w);
727
728 if (buf != NULL) {
729 if (i == ADD_ENDO_LIST) {
730 if (strstr(buf, "endog ")) ret = 1;
731 } else if (i == ADD_INSTR_LIST) {
732 if (strstr(buf, "instr ")) ret = 1;
733 }
734 g_free(buf);
735 }
736
737 return ret;
738 }
739
edit_popup_click(GtkWidget * w,dialog_t * d)740 static gint edit_popup_click (GtkWidget *w, dialog_t *d)
741 {
742 gint action =
743 GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w), "action"));
744 const char *ins = NULL;
745
746 if (action == ADD_EQN) {
747 ins = "equation ";
748 } else if (action == ADD_DERIV) {
749 ins = "deriv ";
750 } else if (action == ADD_IDENT) {
751 ins = "identity ";
752 } else if (action == ADD_ENDO_LIST) {
753 ins = "endog ";
754 } else if (action == ADD_INSTR_LIST) {
755 ins = "instr ";
756 }
757
758 if (ins != NULL) {
759 GtkTextBuffer *tbuf;
760 GtkTextMark *mark;
761 GtkTextIter iter;
762 gint offset, at_end;
763
764 tbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(d->edit));
765 mark = gtk_text_buffer_get_insert(tbuf);
766 gtk_text_buffer_get_iter_at_mark(tbuf, &iter, mark);
767 offset = gtk_text_iter_get_line_offset(&iter);
768 at_end = gtk_text_iter_ends_line(&iter);
769 if (offset == 0) {
770 /* at start of line */
771 if (!at_end) {
772 gtk_text_iter_forward_to_line_end(&iter);
773 gtk_text_buffer_insert(tbuf, &iter, "\n", -1);
774 }
775 } else {
776 if (!at_end) {
777 gtk_text_iter_forward_to_line_end(&iter);
778 }
779 gtk_text_buffer_insert(tbuf, &iter, "\n", -1);
780 }
781 gtk_text_buffer_insert(tbuf, &iter, ins, -1);
782 }
783
784 gtk_widget_destroy(d->popup);
785
786 return FALSE;
787 }
788
build_edit_popup(dialog_t * d)789 static GtkWidget *build_edit_popup (dialog_t *d)
790 {
791 const char *items[] = {
792 N_("Add equation"),
793 N_("Add derivative"),
794 N_("Add identity"),
795 N_("Add list of endogenous variables"),
796 N_("Add list of instruments")
797 };
798 GtkWidget *menu;
799 GtkWidget *item;
800 int i, n_items = sizeof items / sizeof items[0];
801
802 if (d->ci == GMM || d->ci == RESTRICT) {
803 return NULL;
804 }
805
806 menu = gtk_menu_new();
807
808 for (i=0; i<n_items; i++) {
809 if (d->ci == NLS && (i != ADD_DERIV)) {
810 continue;
811 } else if (d->ci == MLE && (i != ADD_DERIV)) {
812 continue;
813 } else if (d->ci == SYSTEM) {
814 if (i == ADD_DERIV) continue;
815 if ((i == ADD_ENDO_LIST || i == ADD_INSTR_LIST) &&
816 edit_has_list(d->edit, i)) {
817 continue;
818 }
819 }
820 item = gtk_menu_item_new_with_label(_(items[i]));
821 g_object_set_data(G_OBJECT(item), "action", GINT_TO_POINTER(i));
822 g_signal_connect(G_OBJECT(item), "activate",
823 G_CALLBACK(edit_popup_click), d);
824 gtk_widget_show(item);
825 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
826 }
827
828 return menu;
829 }
830
831 static gboolean
edit_dialog_popup_handler(GtkWidget * w,GdkEventButton * event,dialog_t * d)832 edit_dialog_popup_handler (GtkWidget *w, GdkEventButton *event,
833 dialog_t *d)
834 {
835 if (right_click(event)) {
836 if (d->popup != NULL) {
837 gtk_widget_destroy(d->popup);
838 d->popup = NULL;
839 }
840
841 d->popup = build_edit_popup(d);
842
843 if (d->popup != NULL) {
844 gtk_menu_popup(GTK_MENU(d->popup), NULL, NULL, NULL, NULL,
845 event->button, event->time);
846 g_signal_connect(G_OBJECT(d->popup), "destroy",
847 G_CALLBACK(gtk_widget_destroyed),
848 &d->popup);
849 }
850 return TRUE;
851 }
852
853 return FALSE;
854 }
855
set_sys_method(GtkComboBox * box,dialog_t * d)856 static void set_sys_method (GtkComboBox *box, dialog_t *d)
857 {
858 gchar *str = combo_box_get_active_text(box);
859 char *s, mstr[8] = {0};
860
861 s = strrchr(str, '(');
862
863 if (s != NULL) {
864 GtkWidget *bt, *bv;
865
866 sscanf(s + 1, "%7[^)]", mstr);
867 d->opt = system_method_from_string(mstr);
868
869 bt = g_object_get_data(G_OBJECT(box), "bt");
870 bv = g_object_get_data(G_OBJECT(box), "bv");
871
872 if (d->opt == 0 || d->opt == 1 || d->opt == 6) {
873 /* SUR, 3SLS, WLS */
874 gtk_widget_set_sensitive(bt, TRUE);
875 gtk_widget_set_sensitive(bv, TRUE);
876 } else if (d->opt == 2) {
877 /* FIML */
878 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bt), TRUE);
879 gtk_widget_set_sensitive(bt, FALSE);
880 gtk_widget_set_sensitive(bv, TRUE);
881 } else {
882 /* LIML, OLS, TSLS */
883 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bt), FALSE);
884 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bt), FALSE);
885 gtk_widget_set_sensitive(bt, FALSE);
886 gtk_widget_set_sensitive(bv, FALSE);
887 }
888 }
889
890 g_free(str);
891 }
892
dialog_option_switch(GtkWidget * vbox,dialog_t * dlg,gretlopt opt,MODEL * pmod)893 static GtkWidget *dialog_option_switch (GtkWidget *vbox, dialog_t *dlg,
894 gretlopt opt, MODEL *pmod)
895 {
896 GtkWidget *b = NULL;
897
898 if (opt == OPT_T) {
899 b = gretl_option_check_button(_("Iterated estimation"),
900 &dlg->opt, opt); /* OPT_T vs OPT_I?? */
901 if (pmod != NULL && (pmod->opt & OPT_I)) {
902 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b), TRUE);
903 }
904 } else if (opt == OPT_V) {
905 b = gretl_option_check_button(_("Show details of iterations"),
906 &dlg->opt, opt);
907 } else if (opt == OPT_R) {
908 b = gretl_option_check_button(_("Robust standard errors"),
909 &dlg->opt, opt);
910 if (pmod != NULL && (pmod->opt & OPT_R)) {
911 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b), TRUE);
912 }
913 } else if (opt == OPT_B) {
914 b = gretl_option_check_button(_("Use bootstrap"),
915 &dlg->opt, opt);
916 } else if (opt == OPT_F) {
917 b = gretl_option_check_button(_("Show full restricted estimates"),
918 &dlg->opt, opt);
919 }
920
921 if (b != NULL) {
922 GtkWidget *hbox = gtk_hbox_new(FALSE, 5);
923
924 gtk_box_pack_start(GTK_BOX(hbox), b, TRUE, TRUE, 5);
925 gtk_widget_show(b);
926
927 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
928 gtk_widget_show(hbox);
929 }
930
931 return b;
932 }
933
combo_opt_changed(GtkComboBox * box,combo_opts * opts)934 static void combo_opt_changed (GtkComboBox *box, combo_opts *opts)
935 {
936 gchar *s = combo_box_get_active_text(box);
937 int i;
938
939 for (i=0; opts->strs[i] != NULL; i++) {
940 if (!strcmp(s, _(opts->strs[i]))) {
941 *opts->optp |= opts->vals[i];
942 } else {
943 *opts->optp &= ~opts->vals[i];
944 }
945 }
946
947 g_free(s);
948 }
949
gretl_opts_combo_full(combo_opts * opts,int deflt,const int * masked,GCallback callback,gpointer calldata)950 GtkWidget *gretl_opts_combo_full (combo_opts *opts, int deflt,
951 const int *masked,
952 GCallback callback,
953 gpointer calldata)
954 {
955 GtkWidget *combo;
956 int i;
957
958 *opts->optp |= opts->vals[deflt];
959
960 combo = gtk_combo_box_text_new();
961 for (i=0; opts->strs[i] != NULL; i++) {
962 if (!in_gretl_list(masked, i)) {
963 combo_box_append_text(combo, _(opts->strs[i]));
964 }
965 }
966 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), deflt);
967 g_signal_connect(G_OBJECT(combo), "changed",
968 G_CALLBACK(combo_opt_changed), opts);
969 if (callback != NULL) {
970 g_signal_connect(G_OBJECT(combo), "changed",
971 callback, calldata);
972 }
973
974 return combo;
975 }
976
gretl_opts_combo(combo_opts * opts,int deflt)977 GtkWidget *gretl_opts_combo (combo_opts *opts, int deflt)
978 {
979 return gretl_opts_combo_full(opts, deflt, NULL, NULL, NULL);
980 }
981
gretl_opts_combo_masked(combo_opts * opts,int deflt,const int * masked)982 GtkWidget *gretl_opts_combo_masked (combo_opts *opts, int deflt,
983 const int *masked)
984 {
985 return gretl_opts_combo_full(opts, deflt, masked,
986 NULL, NULL);
987 }
988
depopulate_combo_box(GtkComboBox * box)989 void depopulate_combo_box (GtkComboBox *box)
990 {
991 GtkTreeModel *model = gtk_combo_box_get_model(box);
992 GtkTreeIter iter;
993
994 while (gtk_tree_model_get_iter_first(model, &iter)) {
995 combo_box_remove(box, 0);
996 }
997 }
998
mle_gmm_iters_dialog(GtkWidget * w,dialog_t * d)999 static void mle_gmm_iters_dialog (GtkWidget *w, dialog_t *d)
1000 {
1001 int maxit, lmem = 0, optim = BFGS_MAX;
1002 double tol;
1003 int resp;
1004
1005 BFGS_defaults(&maxit, &tol, d->ci);
1006 lmem = libset_get_int(LBFGS_MEM);
1007
1008 if (maxit <= 0) {
1009 maxit = 1000;
1010 }
1011
1012 if ((d->opt & OPT_L) || libset_get_bool(USE_LBFGS)) {
1013 optim = LBFGS_MAX;
1014 }
1015
1016 resp = iter_control_dialog(&optim, &maxit, &tol, &lmem,
1017 d->dialog);
1018
1019 if (!canceled(resp)) {
1020 int err;
1021
1022 err = libset_set_int(BFGS_MAXITER, maxit);
1023 err += libset_set_double(BFGS_TOLER, tol);
1024
1025 if (optim == LBFGS_MAX) {
1026 d->opt |= OPT_L;
1027 libset_set_int(LBFGS_MEM, lmem);
1028 } else {
1029 d->opt &= ~OPT_L;
1030 }
1031
1032 if (err) {
1033 errbox("Error setting values");
1034 }
1035 }
1036 }
1037
add_bfgs_controls(dialog_t * d,GtkWidget * vbox,GtkWidget * hbox)1038 static void add_bfgs_controls (dialog_t *d,
1039 GtkWidget *vbox,
1040 GtkWidget *hbox)
1041 {
1042 GtkWidget *button;
1043
1044 button = gtk_button_new_from_stock(GTK_STOCK_PREFERENCES);
1045 g_signal_connect(G_OBJECT(button), "clicked",
1046 G_CALLBACK(mle_gmm_iters_dialog), d);
1047 if (hbox == NULL) {
1048 /* in the MLE case we want this on a new line */
1049 hbox = gtk_hbox_new(FALSE, 5);
1050 }
1051 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1052 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
1053 gtk_widget_show_all(hbox);
1054 }
1055
build_gmm_combo(GtkWidget * vbox,dialog_t * d,MODEL * pmod)1056 static void build_gmm_combo (GtkWidget *vbox, dialog_t *d, MODEL *pmod)
1057 {
1058 GtkWidget *combo, *hbox;
1059 static const char *strs[] = {
1060 N_("One-step estimation"),
1061 N_("Two-step estimation"),
1062 N_("Iterated estimation"),
1063 NULL
1064 };
1065 static gretlopt opts[] = {
1066 OPT_NONE,
1067 OPT_T,
1068 OPT_I
1069 };
1070 static combo_opts gmm_opts;
1071 int deflt = 0;
1072
1073 gmm_opts.strs = strs;
1074 gmm_opts.vals = opts;
1075 gmm_opts.optp = &d->opt;
1076
1077 if (pmod != NULL) {
1078 if (pmod->opt & OPT_T) {
1079 deflt = 1;
1080 } else if (pmod->opt & OPT_I) {
1081 deflt = 2;
1082 }
1083 if (pmod->opt & OPT_L) {
1084 d->opt |= OPT_L;
1085 }
1086 }
1087
1088 combo = gretl_opts_combo(&gmm_opts, deflt);
1089 hbox = gtk_hbox_new(FALSE, 5);
1090 gtk_box_pack_start(GTK_BOX(hbox), combo, FALSE, FALSE, 5);
1091 add_bfgs_controls(d, vbox, hbox);
1092 }
1093
build_mle_combo(GtkWidget * vbox,dialog_t * d,MODEL * pmod)1094 static void build_mle_combo (GtkWidget *vbox, dialog_t *d, MODEL *pmod)
1095 {
1096 GtkWidget *combo, *hbox, *label;
1097 static const char *strs[] = {
1098 N_("Outer product of gradient"),
1099 N_("Hessian"),
1100 N_("Robust (QML)"),
1101 N_("Robust (HAC)"),
1102 NULL
1103 };
1104 static gretlopt opts[] = {
1105 OPT_NONE,
1106 OPT_H,
1107 OPT_R,
1108 OPT_N
1109 };
1110 static combo_opts mle_opts;
1111 int tsmask[2] = {1, 3};
1112 int deflt = 0;
1113
1114 mle_opts.strs = strs;
1115 mle_opts.vals = opts;
1116 mle_opts.optp = &d->opt;
1117
1118 if (pmod != NULL) {
1119 if (pmod->opt & OPT_H) {
1120 deflt = 1;
1121 } else if (pmod->opt & OPT_R) {
1122 deflt = 2;
1123 }
1124 if (pmod->opt & OPT_L) {
1125 d->opt |= OPT_L;
1126 }
1127 }
1128
1129 if (dataset_is_time_series(dataset)) {
1130 combo = gretl_opts_combo(&mle_opts, deflt);
1131 } else {
1132 /* disallow the HAC option */
1133 combo = gretl_opts_combo_masked(&mle_opts, deflt, tsmask);
1134 }
1135 hbox = gtk_hbox_new(FALSE, 5);
1136 label = gtk_label_new(_("Standard errors"));
1137 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
1138 gtk_box_pack_start(GTK_BOX(hbox), combo, FALSE, FALSE, 5);
1139 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
1140 gtk_widget_show_all(hbox);
1141 add_bfgs_controls(d, vbox, NULL);
1142 }
1143
system_estimator_list(GtkWidget * vbox,dialog_t * d,GtkWidget * bt,GtkWidget * bv)1144 static void system_estimator_list (GtkWidget *vbox, dialog_t *d,
1145 GtkWidget *bt, GtkWidget *bv)
1146 {
1147 equation_system *sys = NULL;
1148 GtkWidget *w, *hbox;
1149 gchar *str;
1150 int active = 0;
1151 int i, j;
1152
1153 if (d->data != NULL) {
1154 sys = (equation_system *) d->data;
1155 }
1156
1157 hbox = gtk_hbox_new(FALSE, 5);
1158 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
1159 gtk_widget_show(hbox);
1160
1161 w = gtk_label_new(_("Estimator"));
1162 gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 5);
1163 gtk_widget_show(w);
1164
1165 w = gtk_combo_box_text_new();
1166
1167 j = 0;
1168 for (i=SYS_METHOD_SUR; i<SYS_METHOD_MAX; i++) {
1169 if (system_supports_method(sys, i)) {
1170 str = g_strdup_printf("%s (%s)", _(system_method_full_string(i)),
1171 system_method_short_string(i));
1172 combo_box_append_text(w, str);
1173 g_free(str);
1174 if (sys != NULL && sys->method == i) {
1175 active = j;
1176 }
1177 j++;
1178 }
1179 }
1180
1181 g_object_set_data(G_OBJECT(w), "bt", bt);
1182 g_object_set_data(G_OBJECT(w), "bv", bv);
1183 g_signal_connect(G_OBJECT(w), "changed",
1184 G_CALLBACK(set_sys_method), d);
1185
1186 gtk_combo_box_set_active(GTK_COMBO_BOX(w), active);
1187
1188 gtk_box_pack_start(GTK_BOX(hbox), w, TRUE, TRUE, 5);
1189 gtk_widget_show(w);
1190 }
1191
dlg_display_sys(dialog_t * d)1192 static void dlg_display_sys (dialog_t *d)
1193 {
1194 equation_system *sys = d->data;
1195 GtkWidget *w;
1196 int hsize = 62;
1197
1198 if (d->ci == ESTIMATE) {
1199 /* estimating an existing system, not editing */
1200 w = gtk_label_new(sys->name);
1201 gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_CENTER);
1202 gtk_box_pack_start(GTK_BOX(d->vbox), w, TRUE, TRUE, 10);
1203 gtk_widget_show(w);
1204 }
1205
1206 d->edit = dlg_text_edit_new(&hsize, d->ci == SYSTEM);
1207 dialog_table_setup(d, hsize);
1208 dlg_text_set_from_sys(sys, d);
1209 gretl_dialog_set_resizeable(d->dialog, TRUE);
1210 }
1211
raise_and_focus_dialog(GtkEditable * entry,GtkWidget * parent)1212 void raise_and_focus_dialog (GtkEditable *entry,
1213 GtkWidget *parent)
1214 {
1215 g_return_if_fail(entry != NULL && parent != NULL);
1216
1217 gtk_window_present(GTK_WINDOW(parent));
1218
1219 if (!gtk_widget_has_focus(GTK_WIDGET(entry))) {
1220 gtk_widget_grab_focus(GTK_WIDGET(entry));
1221 }
1222 }
1223
edit_dialog_help_code(int ci,void * p)1224 static int edit_dialog_help_code (int ci, void *p)
1225 {
1226 int hc = ci;
1227
1228 if (ci == ESTIMATE || ci == CREATE_DATASET ||
1229 ci == PRINT || ci == MINIBUF) {
1230 hc = 0;
1231 } else if (ci == RESTRICT) {
1232 windata_t *vwin = (windata_t *) p;
1233
1234 if (vwin->role == VIEW_MODEL) {
1235 hc = MODEL_RESTR;
1236 } else if (vwin->role == SYSTEM) {
1237 hc = SYS_RESTR;
1238 } else if (vwin->role == VECM) {
1239 hc = VECM_RESTR;
1240 }
1241 }
1242
1243 return hc;
1244 }
1245
clear_dlg_previous(GtkWidget * w,dialog_t * d)1246 static void clear_dlg_previous (GtkWidget *w, dialog_t *d)
1247 {
1248 edit_save_buf_clear();
1249 textview_set_text(d->edit, NULL);
1250 }
1251
edit_dialog_ok(GtkWidget * w,dialog_t * d)1252 static void edit_dialog_ok (GtkWidget *w, dialog_t *d)
1253 {
1254 if (d->okfunc != NULL) {
1255 d->okfunc(w, d);
1256 } else {
1257 gtk_widget_destroy(d->dialog);
1258 }
1259 }
1260
ols_model_window(windata_t * vwin)1261 static int ols_model_window (windata_t *vwin)
1262 {
1263 if (vwin->role == VIEW_MODEL) {
1264 MODEL *pmod = (MODEL *) vwin->data;
1265
1266 if (pmod->ci == OLS) {
1267 return 1;
1268 }
1269 }
1270
1271 return 0;
1272 }
1273
vecm_model_window(windata_t * vwin)1274 static int vecm_model_window (windata_t *vwin)
1275 {
1276 return vwin->role == VECM;
1277 }
1278
edit_dialog_add_note(int ci,const char * s,GtkWidget * vbox)1279 static void edit_dialog_add_note (int ci, const char *s,
1280 GtkWidget *vbox)
1281 {
1282 GtkWidget *w;
1283 gchar *lbl;
1284
1285 if (ci == GMM) {
1286 lbl = g_strdup_printf("%s\n%s", s,
1287 _("(Please refer to Help for guidance)"));
1288 } else {
1289 lbl = g_strdup_printf("%s\n%s\n%s", s,
1290 _("(Please refer to Help for guidance)"),
1291 _("right-click for some shortcuts"));
1292 }
1293 w = gtk_label_new(lbl);
1294 gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_CENTER);
1295 gtk_box_pack_start(GTK_BOX(vbox), w, FALSE, FALSE, 10);
1296 gtk_widget_show(w);
1297 g_free(lbl);
1298 }
1299
1300 void
blocking_edit_dialog(int ci,const char * title,const char * info,const char * deflt,void (* okfunc)(),void * okptr,Varclick click,GtkWidget * parent,int * canceled)1301 blocking_edit_dialog (int ci, const char *title,
1302 const char *info, const char *deflt,
1303 void (*okfunc)(), void *okptr,
1304 Varclick click, GtkWidget *parent,
1305 int *canceled)
1306 {
1307 dialog_t *d;
1308 GtkWidget *w;
1309 MODEL *pmod = NULL;
1310 int helpcode;
1311 int clear = 0;
1312
1313 if (open_edit_dialog != NULL && ci != MINIBUF) {
1314 gtk_window_present(GTK_WINDOW(open_edit_dialog));
1315 return;
1316 }
1317
1318 helpcode = edit_dialog_help_code(ci, okptr);
1319 d = edit_dialog_new(ci, title, okfunc, okptr, helpcode,
1320 parent, canceled);
1321 if (d == NULL) return;
1322
1323 open_edit_dialog = d->dialog;
1324 set_dialog_border_widths(d->vbox, d->bbox);
1325 gretl_dialog_set_resizeable(d->dialog, FALSE);
1326
1327 gtk_button_box_set_layout(GTK_BUTTON_BOX(d->bbox),
1328 GTK_BUTTONBOX_END);
1329
1330 if (ci == ESTIMATE) {
1331 /* estimating saved equation system */
1332 dlg_display_sys(d);
1333 } else if (ci == SYSTEM && d->data != NULL) {
1334 /* respecifying equation system */
1335 edit_dialog_add_note(ci, info, d->vbox);
1336 dlg_display_sys(d);
1337 clear = 1;
1338 } else if (ci == NLS || ci == MLE || ci == GMM ||
1339 ci == SYSTEM || ci == RESTRICT) {
1340 int hsize = 62;
1341
1342 edit_dialog_add_note(ci, info, d->vbox);
1343 d->edit = dlg_text_edit_new(&hsize, TRUE);
1344 dialog_table_setup(d, hsize);
1345 gretl_dialog_set_resizeable(d->dialog, TRUE);
1346
1347 if (ci != RESTRICT && deflt != NULL) {
1348 /* re-specifying a nonlinear model */
1349 textview_set_text(d->edit, deflt);
1350 if (ci == NLS || ci == MLE || ci == GMM) {
1351 pmod = okptr;
1352 }
1353 } else if (dlg_text_set_previous(d) ||
1354 dlg_text_set_skeleton(d)) {
1355 /* insert previous text, if any, and if the command
1356 is the same as previously -- or insert skeleton
1357 of command
1358 */
1359 clear = 1;
1360 }
1361 g_signal_connect(G_OBJECT(d->edit), "button-press-event",
1362 G_CALLBACK(edit_dialog_popup_handler), d);
1363 } else {
1364 if (info != NULL) {
1365 w = gtk_label_new(info);
1366 gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
1367 gtk_box_pack_start(GTK_BOX(d->vbox), w, TRUE, TRUE, 5);
1368 gtk_widget_show(w);
1369 }
1370
1371 d->edit = gtk_entry_new();
1372 gtk_box_pack_start(GTK_BOX(d->vbox), d->edit, TRUE, TRUE, 5);
1373
1374 /* make the Enter key do the business */
1375 if (okfunc != NULL) {
1376 gtk_entry_set_activates_default(GTK_ENTRY(d->edit), TRUE);
1377 }
1378
1379 if (deflt != NULL && *deflt != '\0') {
1380 gtk_entry_set_text(GTK_ENTRY(d->edit), deflt);
1381 gtk_editable_select_region(GTK_EDITABLE(d->edit), 0, strlen(deflt));
1382 }
1383
1384 g_signal_connect(G_OBJECT(GTK_EDITABLE(d->edit)), "changed",
1385 G_CALLBACK(raise_and_focus_dialog), d->dialog);
1386 }
1387
1388 if (ci == SYSTEM || ci == ESTIMATE) {
1389 GtkWidget *bt, *bv;
1390
1391 bt = dialog_option_switch(d->vbox, d, OPT_T, NULL);
1392 bv = dialog_option_switch(d->vbox, d, OPT_V, NULL);
1393 system_estimator_list(d->vbox, d, bt, bv);
1394 } else if (ci == NLS) {
1395 dialog_option_switch(d->vbox, d, OPT_V, pmod);
1396 dialog_option_switch(d->vbox, d, OPT_R, pmod);
1397 } else if (ci == MLE) {
1398 dialog_option_switch(d->vbox, d, OPT_V, pmod);
1399 build_mle_combo(d->vbox, d, pmod);
1400 } else if (ci == GMM) {
1401 dialog_option_switch(d->vbox, d, OPT_V, pmod);
1402 build_gmm_combo(d->vbox, d, pmod);
1403 } else if (ci == RESTRICT && ols_model_window(okptr)) {
1404 dialog_option_switch(d->vbox, d, OPT_B, NULL);
1405 } else if (ci == RESTRICT && vecm_model_window(okptr)) {
1406 dialog_option_switch(d->vbox, d, OPT_F, NULL);
1407 } else if (ci == GR_BOX) {
1408 dialog_option_switch(d->vbox, d, OPT_O, NULL);
1409 }
1410
1411 if (click == VARCLICK_INSERT_ID) {
1412 active_edit_id = d->edit;
1413 } else if (click == VARCLICK_INSERT_NAME) {
1414 active_edit_name = d->edit;
1415 } else if (click == VARCLICK_INSERT_TEXT) {
1416 active_edit_text = d->edit;
1417 }
1418
1419 if (click != VARCLICK_NONE || helpcode > 0) {
1420 gtk_window_set_keep_above(GTK_WINDOW(d->dialog), FALSE);
1421 } else {
1422 gtk_window_set_keep_above(GTK_WINDOW(d->dialog), TRUE);
1423 }
1424
1425 gtk_widget_grab_focus(d->edit);
1426
1427 /* "Clear" button? */
1428 if (clear) {
1429 w = gtk_button_new_from_stock(GTK_STOCK_CLEAR);
1430 gtk_container_add(GTK_CONTAINER(d->bbox), w);
1431 g_signal_connect(G_OBJECT(w), "clicked",
1432 G_CALLBACK(clear_dlg_previous), d);
1433 }
1434
1435 /* "Cancel" button */
1436 cancel_delete_button(d->bbox, d->dialog);
1437
1438 /* "OK" button */
1439 if (canceled != NULL) {
1440 w = ok_validate_button(d->bbox, canceled, NULL);
1441 } else {
1442 w = ok_button(d->bbox);
1443 }
1444 g_signal_connect(G_OBJECT(w), "clicked",
1445 G_CALLBACK(edit_dialog_ok), d);
1446 gtk_widget_grab_default(w);
1447
1448 /* "Help" button, if wanted */
1449 if (helpcode > 0) {
1450 context_help_button(d->bbox, helpcode);
1451 }
1452
1453 if (ci == GENR) {
1454 gtk_widget_set_size_request(GTK_WIDGET(d->dialog), 400, -1);
1455 }
1456
1457 gtk_widget_show_all(d->dialog);
1458 }
1459
edit_dialog(int ci,const char * title,const char * info,const char * deflt,void (* okfunc)(),void * okptr,Varclick click,GtkWidget * parent)1460 void edit_dialog (int ci, const char *title,
1461 const char *info, const char *deflt,
1462 void (*okfunc)(), void *okptr,
1463 Varclick click, GtkWidget *parent)
1464 {
1465 blocking_edit_dialog(ci, title, info, deflt, okfunc, okptr,
1466 click, parent, NULL);
1467 }
1468
edit_dialog_reset(dialog_t * dlg)1469 void edit_dialog_reset (dialog_t *dlg)
1470 {
1471 if (dlg->cancel != NULL) {
1472 *dlg->cancel = 1;
1473 }
1474 }
1475
entry_box_get_trimmed_text(GtkWidget * w)1476 gchar *entry_box_get_trimmed_text (GtkWidget *w)
1477 {
1478 const gchar *s = gtk_entry_get_text(GTK_ENTRY(w));
1479 gchar *ret = NULL;
1480
1481 if (s != NULL) {
1482 while (isspace(*s)) s++;
1483 if (*s != '\0') {
1484 ret = g_strstrip(g_strdup(s));
1485 }
1486 }
1487
1488 return ret;
1489 }
1490
set_combo_box_strings_from_list(GtkWidget * box,GList * list)1491 void set_combo_box_strings_from_list (GtkWidget *box, GList *list)
1492 {
1493 GList *mylist = list;
1494
1495 while (mylist != NULL) {
1496 combo_box_append_text(box, mylist->data);
1497 mylist = mylist->next;
1498 }
1499 }
1500
set_combo_box_default_text(GtkComboBox * box,const char * s)1501 void set_combo_box_default_text (GtkComboBox *box, const char *s)
1502 {
1503 GtkWidget *entry = gtk_bin_get_child(GTK_BIN(box));
1504
1505 gtk_entry_set_text(GTK_ENTRY(entry), s);
1506 }
1507
combo_box_text_new_with_entry(void)1508 GtkWidget *combo_box_text_new_with_entry (void)
1509 {
1510 #if GTK_MAJOR_VERSION >= 3
1511 return gtk_combo_box_text_new_with_entry();
1512 #else
1513 return gtk_combo_box_entry_new_text();
1514 #endif
1515 }
1516
combo_box_get_active_text(gpointer p)1517 gchar *combo_box_get_active_text (gpointer p)
1518 {
1519 gchar *ret = NULL;
1520
1521 #if GTK_MAJOR_VERSION >= 3
1522 ret = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(p));
1523 #else /* gtk < 2.24 */
1524 ret = gtk_combo_box_get_active_text(GTK_COMBO_BOX(p));
1525 #endif
1526
1527 return ret;
1528 }
1529
combo_box_append_text(gpointer p,const gchar * s)1530 void combo_box_append_text (gpointer p, const gchar *s)
1531 {
1532 #if GTK_MAJOR_VERSION >= 3
1533 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(p), s);
1534 #else
1535 gtk_combo_box_append_text(GTK_COMBO_BOX(p), s);
1536 #endif
1537 }
1538
combo_box_prepend_text(gpointer p,const gchar * s)1539 void combo_box_prepend_text (gpointer p, const gchar *s)
1540 {
1541 #if GTK_MAJOR_VERSION >= 3
1542 gtk_combo_box_text_prepend_text(GTK_COMBO_BOX_TEXT(p), s);
1543 #else
1544 gtk_combo_box_prepend_text(GTK_COMBO_BOX(p), s);
1545 #endif
1546 }
1547
combo_box_remove(gpointer p,int pos)1548 void combo_box_remove (gpointer p, int pos)
1549 {
1550 #if GTK_MAJOR_VERSION >= 3
1551 gtk_combo_box_text_remove(GTK_COMBO_BOX_TEXT(p), pos);
1552 #else
1553 gtk_combo_box_remove_text(GTK_COMBO_BOX(p), pos);
1554 #endif
1555 }
1556
widget_get_pointer_info(GtkWidget * w,gint * x,gint * y,GdkModifierType * mask)1557 gboolean widget_get_pointer_info (GtkWidget *w, gint *x, gint *y,
1558 GdkModifierType *mask)
1559 {
1560 GdkWindow *window = gtk_widget_get_window(w);
1561
1562 if (window == NULL) {
1563 return FALSE;
1564 } else {
1565 gdk_window_get_pointer(window, x, y, mask);
1566 return TRUE;
1567 }
1568 }
1569
1570 /* set-up for a top-level window, @dlg, which emulates a GtkDialog
1571 structure: *pvbox is like the vbox member of a GtkDialog, and
1572 *pbbox like the action_area member.
1573 */
1574
gretl_emulated_dialog_add_structure(GtkWidget * dlg,GtkWidget ** pvbox,GtkWidget ** pbbox)1575 void gretl_emulated_dialog_add_structure (GtkWidget *dlg,
1576 GtkWidget **pvbox,
1577 GtkWidget **pbbox)
1578 {
1579 GtkWidget *base;
1580
1581 g_signal_connect(G_OBJECT(dlg), "key-press-event",
1582 G_CALLBACK(esc_kills_window), NULL);
1583
1584 base = gtk_vbox_new(FALSE, 5);
1585 gtk_container_add(GTK_CONTAINER(dlg), base);
1586
1587 *pvbox = gtk_vbox_new(FALSE, 0);
1588
1589 /* make (upper) vbox expansible */
1590 gtk_box_pack_start(GTK_BOX(base), *pvbox, TRUE, TRUE, 0);
1591 gtk_container_set_border_width(GTK_CONTAINER(*pvbox), 5);
1592 gtk_box_set_spacing(GTK_BOX(*pvbox), 5);
1593
1594 #if 0
1595 vbox_add_hsep(base);
1596 #endif
1597
1598 *pbbox = gtk_hbutton_box_new();
1599 gtk_button_box_set_layout(GTK_BUTTON_BOX(*pbbox),
1600 GTK_BUTTONBOX_END);
1601 gtk_box_set_spacing(GTK_BOX(*pbbox), 10);
1602 gtk_box_pack_start(GTK_BOX(base), *pbbox,
1603 FALSE, FALSE, 0);
1604 gtk_container_set_border_width(GTK_CONTAINER(*pbbox), 5);
1605 }
1606