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 /* dialogs.c for gretl */
21
22 #include "gretl.h"
23 #include "cmdstack.h"
24 #include "session.h"
25 #include "obsbutton.h"
26 #include "textutil.h"
27 #include "menustate.h"
28 #include "dlgutils.h"
29 #include "treeutils.h"
30 #include "ssheet.h"
31 #include "database.h"
32 #include "selector.h"
33 #include "fileselect.h"
34 #include "winstack.h"
35 #include "gretl_panel.h"
36 #include "gretl_midas.h"
37 #include "texprint.h"
38 #include "forecast.h"
39 #include "console.h"
40 #include "libset.h"
41 #include "uservar.h"
42 #include "gretl_bfgs.h"
43 #include "libglue.h"
44
45 #include <errno.h>
46
47 static GtkWidget *option_spinbox (int *spinvar, const char *spintxt,
48 int spinmin, int spinmax,
49 int hcode, gpointer p);
50 static GtkWidget *option_checkbox (int *checkvar, const char *checktxt);
51 static void set_radio_opt (GtkWidget *w, int *opt);
52 static GtkWidget *dialog_blurb_box (const char *text);
53
menu_exit_check(void)54 void menu_exit_check (void)
55 {
56 if (!exit_check()) {
57 gtk_main_quit();
58 }
59 }
60
61 /* This callback is invoked if the user is quitting a session and (a)
62 the session is not associated with a file on disk (in which case
63 the data-save is automatic if the session is saved) and (b) the
64 dataset has been modified.
65 */
66
save_data_callback(void)67 static void save_data_callback (void)
68 {
69 data_export_selection_wrapper(SAVE_DATA);
70 if (data_status & MODIFIED_DATA) {
71 data_status ^= MODIFIED_DATA;
72 }
73 /* FIXME: need to do more here? */
74 }
75
gretl_dialog_keep_above(GtkWidget * w)76 static void gretl_dialog_keep_above (GtkWidget *w)
77 {
78 /* note: this could be ifdef'd out if not wanted */
79 gtk_window_set_keep_above(GTK_WINDOW(w), TRUE);
80 }
81
gretl_dialog_add_message(GtkWidget * dlg,const char * msg)82 void gretl_dialog_add_message (GtkWidget *dlg, const char *msg)
83 {
84 GtkWidget *hbox, *vbox;
85 GtkWidget *label;
86
87 hbox = gtk_hbox_new(FALSE, 0);
88 label = gtk_label_new(msg);
89 gtk_widget_show(label);
90 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 12);
91 gtk_widget_show(hbox);
92
93 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dlg));
94 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 12);
95 }
96
97 static gint
real_yes_no_dialog(const char * title,const char * msg,int cancel,GtkWidget * parent,int default_id)98 real_yes_no_dialog (const char *title, const char *msg,
99 int cancel, GtkWidget *parent,
100 int default_id)
101 {
102 GtkDialogFlags flags = GTK_DIALOG_MODAL;
103 GtkWidget *dlg;
104 int ret = GTK_RESPONSE_HELP;
105
106 if (title == NULL) {
107 title = "gretl";
108 }
109
110 if (parent != NULL) {
111 flags |= GTK_DIALOG_DESTROY_WITH_PARENT;
112 } else if (mdata != NULL && mdata->main != NULL) {
113 parent = mdata->main;
114 flags |= GTK_DIALOG_DESTROY_WITH_PARENT;
115 }
116
117 dlg = gtk_dialog_new_with_buttons(title,
118 GTK_WINDOW(parent),
119 flags,
120 GTK_STOCK_YES,
121 GTK_RESPONSE_ACCEPT,
122 GTK_STOCK_NO,
123 GTK_RESPONSE_NO,
124 NULL);
125
126 if (cancel) {
127 gtk_dialog_add_button(GTK_DIALOG(dlg),
128 GTK_STOCK_CANCEL,
129 GTK_RESPONSE_REJECT);
130 }
131
132 if (default_id != 0) {
133 gtk_dialog_set_default_response(GTK_DIALOG(dlg), default_id);
134 }
135
136 gretl_dialog_add_message(dlg, msg);
137
138 #if GTK_MAJOR_VERSION < 3
139 gtk_dialog_set_has_separator(GTK_DIALOG(dlg), FALSE);
140 #endif
141 gtk_window_set_keep_above(GTK_WINDOW(dlg), TRUE);
142 ret = gtk_dialog_run(GTK_DIALOG(dlg));
143
144 gtk_widget_destroy(dlg);
145
146 switch (ret) {
147 case GTK_RESPONSE_ACCEPT:
148 return GRETL_YES;
149 case GTK_RESPONSE_NO:
150 return GRETL_NO;
151 default:
152 return GRETL_CANCEL;
153 }
154 }
155
yes_no_dialog(const char * title,const char * msg,GtkWidget * parent)156 gint yes_no_dialog (const char *title,
157 const char *msg,
158 GtkWidget *parent)
159 {
160 return real_yes_no_dialog(title, msg, 0, parent, 0);
161 }
162
yes_no_cancel_dialog(const char * title,const char * msg,GtkWidget * parent)163 gint yes_no_cancel_dialog (const char *title,
164 const char *msg,
165 GtkWidget *parent)
166 {
167 return real_yes_no_dialog(title, msg, 1, parent, 0);
168 }
169
no_yes_dialog(const char * title,const char * msg)170 gint no_yes_dialog (const char *title, const char *msg)
171 {
172 return real_yes_no_dialog(title, msg, 0, NULL,
173 GTK_RESPONSE_NO);
174 }
175
toggle_session_prompt(GtkToggleButton * b)176 static void toggle_session_prompt (GtkToggleButton *b)
177 {
178 set_session_prompt(button_is_active(b));
179 }
180
set_ret_no(GtkButton * b,int * ret)181 static void set_ret_no (GtkButton *b, int *ret)
182 {
183 *ret = GRETL_NO;
184 }
185
set_ret_yes(GtkButton * b,int * ret)186 static void set_ret_yes (GtkButton *b, int *ret)
187 {
188 *ret = GRETL_YES;
189 }
190
save_session_prompt(int gui_session)191 static int save_session_prompt (int gui_session)
192 {
193 const char *gui_msg =
194 N_("Do you want to save this gretl session?");
195 const char *cmds_msg =
196 N_("Save a record of the commands you executed?");
197 const char *check_msg =
198 N_("Always prompt if there are unsaved changes");
199 GtkWidget *dialog;
200 GtkWidget *vbox, *hbox, *tmp, *b;
201 gchar *title;
202 int ret = GRETL_CANCEL;
203
204 title = g_strdup_printf("gretl: %s", gui_session ?
205 _("save session") : _("save commands"));
206 dialog = gretl_dialog_new(title, NULL, GRETL_DLG_BLOCK);
207 g_free(title);
208
209 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
210
211 /* label */
212 tmp = dialog_blurb_box(gui_session ? _(gui_msg) : _(cmds_msg));
213 gtk_box_pack_start(GTK_BOX(vbox), tmp, TRUE, TRUE, 5);
214
215 /* check button */
216 b = gtk_check_button_new_with_label(_(check_msg));
217 gtk_box_pack_start(GTK_BOX(vbox), b, TRUE, TRUE, 0);
218 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b), session_prompt_on());
219 g_signal_connect(G_OBJECT(b), "clicked",
220 G_CALLBACK(toggle_session_prompt), NULL);
221
222 hbox = gtk_dialog_get_action_area(GTK_DIALOG(dialog));
223
224 /* "Yes" button */
225 b = gtk_button_new_from_stock(GTK_STOCK_YES);
226 gtk_box_pack_start(GTK_BOX(hbox), b, TRUE, TRUE, 0);
227 g_signal_connect(G_OBJECT(b), "clicked",
228 G_CALLBACK(set_ret_yes), &ret);
229 g_signal_connect(G_OBJECT(b), "clicked",
230 G_CALLBACK(delete_widget),
231 dialog);
232
233 gtk_widget_set_can_default(b, TRUE);
234 gtk_widget_grab_default(b);
235 gtk_widget_grab_focus(b);
236
237 /* "No" button */
238 b = gtk_button_new_from_stock(GTK_STOCK_NO);
239 gtk_box_pack_start(GTK_BOX(hbox), b, TRUE, TRUE, 0);
240 g_signal_connect(G_OBJECT(b), "clicked",
241 G_CALLBACK(set_ret_no), &ret);
242 g_signal_connect(G_OBJECT(b), "clicked",
243 G_CALLBACK(delete_widget),
244 dialog);
245
246 /* Cancel button */
247 cancel_delete_button(hbox, dialog);
248
249 /* "Help" button */
250 context_help_button(hbox, gui_session ? SAVE_SESSION :
251 SAVE_CMD_LOG);
252
253 gtk_widget_show_all(dialog);
254
255 return ret;
256 }
257
258 /* exit_check: returning FALSE allows the exit to proceed;
259 to block the exit we return TRUE.
260 */
261
exit_check(void)262 gboolean exit_check (void)
263 {
264 int resp, datamod, status = 0;
265 int err = 0;
266
267 if (maybe_raise_dialog() || console_is_busy()) {
268 /* we're not ready: block the exit now */
269 return TRUE;
270 }
271
272 if (window_list_exit_check()) {
273 /* got cancel exit message from an editor window */
274 return TRUE;
275 }
276
277 datamod = (data_status & MODIFIED_DATA);
278
279 if (session_file_is_open() && (session_is_modified() || datamod)) {
280 const char *save_msg = N_("Do you want to save the changes you made\n"
281 "to this session?");
282
283 resp = yes_no_cancel_dialog("gretl", _(save_msg), NULL);
284 if (resp == GRETL_YES) {
285 err = save_session(NULL);
286 if (err) {
287 /* give the user a shot at remedial action */
288 return TRUE;
289 }
290 } else if (resp == GRETL_CANCEL) {
291 /* canceled exit: block */
292 return TRUE;
293 }
294 } else if (session_prompt_on()) {
295 if (session_is_modified()) {
296 /* give the user the chance to save the session */
297 resp = save_session_prompt(1);
298 if (resp == GRETL_YES) {
299 file_selector(SAVE_SESSION, FSEL_DATA_STATUS, &status);
300 if (status != 0 && status != GRETL_CANCEL) {
301 /* error saving session */
302 return TRUE;
303 }
304 /* now provisionally allow exit to proceed */
305 } else if (resp == GRETL_CANCEL) {
306 /* canceled exit: block */
307 return TRUE;
308 }
309 } else if (!session_file_is_open() && get_commands_recorded()) {
310 /* give the user the chance to save commands */
311 resp = save_session_prompt(0);
312 if (resp == GRETL_YES) {
313 file_selector(SAVE_CMD_LOG, FSEL_DATA_STATUS, &status);
314 if (status != 0 && status != GRETL_CANCEL) {
315 /* error saving commands */
316 return TRUE;
317 }
318 /* now provisionally allow exit to proceed */
319 } else if (resp == GRETL_CANCEL) {
320 /* canceled exit: block */
321 return TRUE;
322 }
323 }
324 }
325
326 if (!session_file_is_open() && (data_status & MODIFIED_DATA)) {
327 /* give the user a chance to save modified dataset */
328 resp =
329 yes_no_cancel_dialog("gretl",
330 _("Do you want to save changes you have\n"
331 "made to the current data set?"), NULL);
332 if (resp == GRETL_YES) {
333 save_data_callback();
334 } else if (resp == GRETL_CANCEL) {
335 /* the user canceled exit: block further processing */
336 return TRUE;
337 }
338 }
339
340 write_rc(OPT_NONE);
341
342 return FALSE;
343 }
344
gui_double_from_string(const char * str,int * err)345 double gui_double_from_string (const char *str, int *err)
346 {
347 double x = 0;
348 char *p, s[32];
349
350 gretl_error_clear();
351
352 *s = '\0';
353 strncat(s, str, 31);
354 p = s + strspn(s, " ");
355 gretl_lower(p);
356
357 if (!strcmp(p, "na") || !strcmp(p, "nan") || !strcmp(p, ".")) {
358 x = NADBL;
359 } else {
360 int sub = 0;
361
362 if (get_local_decpoint() != '.') {
363 gretl_push_c_numeric_locale();
364 gretl_charsub(p, ',', '.');
365 sub = 1;
366 }
367
368 *err = check_atof(p);
369
370 if (*err) {
371 gui_errmsg(*err);
372 } else {
373 x = atof(p);
374 }
375
376 if (sub) {
377 gretl_pop_c_numeric_locale();
378 }
379 }
380
381 return x;
382 }
383
hboxit(GtkWidget * w,GtkWidget * vbox)384 static GtkWidget *hboxit (GtkWidget *w, GtkWidget *vbox)
385 {
386 GtkWidget *hbox = gtk_hbox_new(FALSE, 5);
387
388 gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 5);
389 if (vbox != NULL) {
390 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
391 }
392
393 return hbox;
394 }
395
csv_na_callback(GtkComboBox * box,gpointer p)396 static void csv_na_callback (GtkComboBox *box, gpointer p)
397 {
398 gchar *s = combo_box_get_active_text(box);
399
400 set_csv_na_write_string(s);
401 g_free(s);
402 }
403
csv_na_combo(void)404 static GtkWidget *csv_na_combo (void)
405 {
406 GtkWidget *hbox, *label, *combo;
407 const char *na_strs[] = {
408 "NA", ".NaN", "-999", "-9999.0", "?", "."
409 };
410 const char *setna = get_csv_na_write_string();
411 int i, n = G_N_ELEMENTS(na_strs);
412 int matched = 0;
413
414 hbox = gtk_hbox_new(FALSE, 5);
415 label = gtk_label_new(_("Print missing values as:"));
416 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
417
418 combo = gtk_combo_box_text_new();
419 gtk_box_pack_start(GTK_BOX(hbox), combo, FALSE, FALSE, 5);
420 for (i=0; i<n; i++) {
421 combo_box_append_text(combo, na_strs[i]);
422 if (!strcmp(setna, na_strs[i])) {
423 matched = 1;
424 }
425 }
426
427 if (!matched) {
428 combo_box_append_text(combo, setna);
429 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), i);
430 } else {
431 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0);
432 }
433
434 g_signal_connect(G_OBJECT(combo), "changed",
435 G_CALLBACK(csv_na_callback), NULL);
436
437 return hbox;
438 }
439
440 /* CSV files: setting the delimiter, etc. */
441
442 typedef struct {
443 GtkWidget *semic_button;
444 GtkWidget *comma_sep;
445 gint delim; /* delimiter (comma, etc.) */
446 gint decpoint; /* decimal character */
447 gboolean xobs; /* exclude obs column on export? */
448 } csv_stuff;
449
set_dec(GtkWidget * w,csv_stuff * csv)450 static void set_dec (GtkWidget *w, csv_stuff *csv)
451 {
452 gint i;
453
454 if (button_is_active(w)) {
455 i = widget_get_int(w, "action");
456 csv->decpoint = i;
457 if (csv->decpoint == ',') {
458 csv->delim = ';';
459 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(csv->semic_button),
460 TRUE);
461 } else if (csv->delim == ';') {
462 csv->delim = ',';
463 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(csv->comma_sep),
464 TRUE);
465 }
466 }
467 }
468
set_delim(GtkWidget * w,csv_stuff * csv)469 static void set_delim (GtkWidget *w, csv_stuff *csv)
470 {
471 gint i;
472
473 if (button_is_active(w)) {
474 i = widget_get_int(w, "action");
475 if (i != 'a') {
476 csv->delim = i;
477 }
478 }
479 }
480
toggle_csv_xobs(GtkToggleButton * b,csv_stuff * csv)481 static void toggle_csv_xobs (GtkToggleButton *b, csv_stuff *csv)
482 {
483 csv->xobs = !gtk_toggle_button_get_active(b);
484 }
485
really_set_csv_stuff(GtkWidget * w,csv_stuff * csv)486 static void really_set_csv_stuff (GtkWidget *w, csv_stuff *csv)
487 {
488 set_data_export_delimiter(csv->delim);
489 set_data_export_decimal_comma(csv->decpoint == ',');
490 set_csv_exclude_obs(csv->xobs);
491 }
492
destroy_delim_dialog(GtkWidget * w,gint * p)493 static void destroy_delim_dialog (GtkWidget *w, gint *p)
494 {
495 free(p);
496 }
497
csv_options_dialog(int ci,GretlObjType otype,GtkWidget * parent)498 int csv_options_dialog (int ci, GretlObjType otype, GtkWidget *parent)
499 {
500 GtkWidget *dialog, *vbox, *hbox;
501 GtkWidget *tmp, *button;
502 GSList *group = NULL;
503 csv_stuff *csvp = NULL;
504 int ret = GRETL_CANCEL;
505
506 if (maybe_raise_dialog()) {
507 return ret;
508 }
509
510 csvp = mymalloc(sizeof *csvp);
511 if (csvp == NULL) {
512 return ret;
513 }
514
515 csvp->delim = ',';
516 csvp->decpoint = '.';
517 csvp->xobs = get_csv_exclude_obs();
518
519 dialog = gretl_dialog_new(_("gretl: data delimiter"), parent,
520 GRETL_DLG_BLOCK);
521
522 g_signal_connect(G_OBJECT(dialog), "destroy",
523 G_CALLBACK(destroy_delim_dialog), csvp);
524
525 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
526
527 tmp = gtk_label_new(_("separator for data columns:"));
528 pack_in_hbox(tmp, vbox, 5);
529
530 if (ci == OPEN_DATA || ci == APPEND_DATA) {
531 /* on input only, add option to auto-detect separator */
532 button = gtk_radio_button_new_with_label(group, _("auto-detect"));
533 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
534 pack_in_hbox(button, vbox, 0);
535 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
536 g_signal_connect(G_OBJECT(button), "clicked",
537 G_CALLBACK(set_delim), csvp);
538 g_object_set_data(G_OBJECT(button), "action",
539 GINT_TO_POINTER('a'));
540 }
541
542 /* comma separator */
543 button = gtk_radio_button_new_with_label(group, _("comma (,)"));
544 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
545 csvp->comma_sep = button;
546 pack_in_hbox(button, vbox, 0);
547 if (ci != OPEN_DATA && ci != APPEND_DATA)
548 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
549 g_signal_connect(G_OBJECT(button), "clicked",
550 G_CALLBACK(set_delim), csvp);
551 g_object_set_data(G_OBJECT(button), "action",
552 GINT_TO_POINTER(','));
553
554 /* space separator */
555 button = gtk_radio_button_new_with_label(group, _("space"));
556 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
557 pack_in_hbox(button, vbox, 0);
558 if (csvp->delim == ' ')
559 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
560 g_signal_connect(G_OBJECT(button), "clicked",
561 G_CALLBACK(set_delim), csvp);
562 g_object_set_data(G_OBJECT(button), "action",
563 GINT_TO_POINTER(' '));
564
565 /* tab separator */
566 button = gtk_radio_button_new_with_label(group, _("tab"));
567 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
568 pack_in_hbox(button, vbox, 0);
569 g_signal_connect(G_OBJECT(button), "clicked",
570 G_CALLBACK(set_delim), csvp);
571 g_object_set_data(G_OBJECT(button), "action",
572 GINT_TO_POINTER('\t'));
573
574 /* semicolon separator */
575 button = gtk_radio_button_new_with_label(group, _("semicolon"));
576 csvp->semic_button = button;
577 pack_in_hbox(button, vbox, 0);
578 g_signal_connect(G_OBJECT(button), "clicked",
579 G_CALLBACK(set_delim), csvp);
580 g_object_set_data(G_OBJECT(button), "action",
581 GINT_TO_POINTER(';'));
582
583 if (',' == get_local_decpoint()) {
584 GSList *dgroup;
585
586 vbox_add_hsep(vbox);
587 tmp = gtk_label_new(_("decimal point character:"));
588 pack_in_hbox(tmp, vbox, 5);
589
590 /* period decpoint */
591 button = gtk_radio_button_new_with_label(NULL, _("period (.)"));
592 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
593 pack_in_hbox(button, vbox, 0);
594 g_signal_connect(G_OBJECT(button), "clicked",
595 G_CALLBACK(set_dec), csvp);
596 g_object_set_data(G_OBJECT(button), "action",
597 GINT_TO_POINTER('.'));
598
599 /* comma decpoint */
600 dgroup = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
601 button = gtk_radio_button_new_with_label(dgroup, _("comma (,)"));
602 pack_in_hbox(button, vbox, 0);
603 g_signal_connect(G_OBJECT(button), "clicked",
604 G_CALLBACK(set_dec), csvp);
605 g_object_set_data(G_OBJECT(button), "action",
606 GINT_TO_POINTER(','));
607 }
608
609 if (otype == GRETL_OBJ_DSET && (ci == EXPORT_CSV || ci == COPY_CSV)) {
610 /* On export/copy of series data only: allow choice to exclude
611 the observations column, and/or on representation of NAs,
612 if applicable.
613 */
614 int hsep_done = 0;
615
616 if (dataset_is_time_series(dataset) || dataset->S != NULL) {
617 vbox_add_hsep(vbox);
618 hsep_done = 1;
619 tmp = gtk_check_button_new_with_label(_("include observations column"));
620 g_signal_connect(G_OBJECT(tmp), "toggled",
621 G_CALLBACK(toggle_csv_xobs), csvp);
622 pack_in_hbox(tmp, vbox, 0);
623 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tmp), !csvp->xobs);
624 }
625
626 if (any_missing_user_values(dataset)) {
627 if (!hsep_done) {
628 vbox_add_hsep(vbox);
629 }
630 tmp = csv_na_combo();
631 pack_in_hbox(tmp, vbox, 0);
632 }
633 }
634
635 /* buttons */
636 hbox = gtk_dialog_get_action_area(GTK_DIALOG(dialog));
637 tmp = ok_validate_button(hbox, &ret, NULL);
638 g_signal_connect(G_OBJECT(tmp), "clicked",
639 G_CALLBACK(really_set_csv_stuff), csvp);
640 g_signal_connect(G_OBJECT(tmp), "clicked",
641 G_CALLBACK(delete_widget), dialog);
642 gtk_widget_grab_default(tmp);
643
644 gretl_dialog_keep_above(dialog);
645 gtk_widget_show_all(dialog);
646
647 return ret;
648 }
649
650 /* selection of format in which to copy material to clipboard,
651 or save to file */
652
653 struct format_info {
654 GtkWidget *dialog;
655 windata_t *vwin;
656 int format;
657 int multi;
658 int action;
659 };
660
destroy_format_dialog(GtkWidget * w,struct format_info * finfo)661 static void destroy_format_dialog (GtkWidget *w, struct format_info *finfo)
662 {
663 free(finfo);
664 }
665
copy_with_format_callback(GtkWidget * w,struct format_info * finfo)666 static void copy_with_format_callback (GtkWidget *w, struct format_info *finfo)
667 {
668 windata_t *vwin = finfo->vwin;
669 int format = finfo->format;
670 int action = finfo->action;
671 int force_decpoint = 0;
672
673 gtk_widget_destroy(finfo->dialog);
674
675 if (action == W_COPY &&
676 vwin->role == VIEW_MODEL &&
677 format == GRETL_FORMAT_CSV &&
678 get_local_decpoint() == ',') {
679 const char *opts[] = {
680 N_("period (.)"),
681 N_("comma (,)")
682 };
683 int resp;
684
685 resp = radio_dialog(NULL, _("decimal point character:"),
686 opts, 2, 0, 0, vwin_toplevel(vwin));
687 if (resp < 0) {
688 return;
689 } else if (resp == 0) {
690 force_decpoint = 1;
691 }
692 }
693
694 if (force_decpoint) {
695 gretl_push_c_numeric_locale();
696 }
697
698 if (action == W_COPY) {
699 window_copy(vwin, format);
700 } else {
701 window_save(vwin, format);
702 }
703
704 if (force_decpoint) {
705 gretl_pop_c_numeric_locale();
706 }
707 }
708
preferred_format(int f,int multi)709 static int preferred_format (int f, int multi)
710 {
711 # ifdef G_OS_WIN32
712 static int multi_pref = GRETL_FORMAT_RTF;
713 static int simple_pref = GRETL_FORMAT_TXT;
714 # else
715 static int multi_pref = GRETL_FORMAT_TEX;
716 static int simple_pref = GRETL_FORMAT_TXT;
717 #endif
718 int ret;
719
720 if (multi) {
721 if (f) multi_pref = f;
722 ret = multi_pref;
723 } else {
724 if (f) simple_pref = f;
725 ret = simple_pref;
726 }
727
728 return ret;
729 }
730
set_copy_format(GtkWidget * w,struct format_info * finfo)731 static void set_copy_format (GtkWidget *w, struct format_info *finfo)
732 {
733 gpointer p = g_object_get_data(G_OBJECT(w), "format");
734
735 if (p != NULL) {
736 int f = GPOINTER_TO_INT(p);
737
738 finfo->format = f;
739 if (f != GRETL_FORMAT_CSV) {
740 preferred_format(finfo->format, finfo->multi);
741 }
742 }
743 }
744
745 static GtkWidget *
copy_item_button(GSList * group,GtkWidget * vbox,struct format_info * finfo,int format,const char * label,int pref)746 copy_item_button (GSList *group, GtkWidget *vbox, struct format_info *finfo,
747 int format, const char *label, int pref)
748 {
749 GtkWidget *button;
750
751 button = gtk_radio_button_new_with_label(group, label);
752 gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0);
753 g_signal_connect(G_OBJECT(button), "clicked",
754 G_CALLBACK(set_copy_format), finfo);
755 g_object_set_data(G_OBJECT(button), "format",
756 GINT_TO_POINTER(format));
757 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),
758 (pref == format));
759
760 return button;
761 }
762
763 #define can_do_tsv(v) ((v->role == PRINT && v->data != NULL) || \
764 v->role == VIEW_SERIES)
765
766 #define can_do_csv(v) ((v->role == PRINT && v->data != NULL) || \
767 v->role == VIEW_SERIES || \
768 v->role == VIEW_MODEL)
769
770 /* This dialog allows for selection of a format option when saving
771 material to file or copying to the clipboard. The range of
772 formats offered depends on the content/role of @vwin.
773 */
774
copy_format_dialog(windata_t * vwin,int action)775 void copy_format_dialog (windata_t *vwin, int action)
776 {
777 GtkWidget *dialog, *tmp, *hbox;
778 GtkWidget *button;
779 GtkWidget *vbox;
780 GSList *group = NULL;
781 struct format_info *finfo;
782 const char *rtf_label;
783 int rtf_format;
784 int pref;
785
786 if (maybe_raise_dialog()) {
787 return;
788 }
789
790 finfo = mymalloc(sizeof *finfo);
791 if (finfo == NULL) return;
792
793 dialog = gretl_dialog_new(_("gretl: select format"),
794 vwin_toplevel(vwin),
795 GRETL_DLG_BLOCK);
796 finfo->vwin = vwin;
797 finfo->dialog = dialog;
798
799 finfo->multi = multiple_formats_ok(vwin);
800 finfo->format = pref = preferred_format(0, finfo->multi);
801 finfo->action = action;
802
803 g_signal_connect(G_OBJECT(dialog), "destroy",
804 G_CALLBACK(destroy_format_dialog), finfo);
805
806 /* set RTF params */
807 #ifdef G_OS_WIN32
808 rtf_label = "RTF (MS Word)";
809 #else
810 rtf_label = "RTF";
811 #endif
812 if (finfo->multi || can_do_tsv(finfo->vwin)) {
813 rtf_format = GRETL_FORMAT_RTF;
814 } else {
815 rtf_format = GRETL_FORMAT_RTF_TXT;
816 }
817
818 vbox = gtk_vbox_new(FALSE, 2);
819
820 hbox = gtk_hbox_new(FALSE, 5);
821 tmp = gtk_label_new((action == W_COPY)? _("Copy as:") : _("Save as"));
822 gtk_box_pack_start(GTK_BOX(hbox), tmp, TRUE, TRUE, 5);
823 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 2);
824
825 #ifdef G_OS_WIN32
826 /* Windows: put RTF option first */
827 button = copy_item_button(group, vbox, finfo, rtf_format,
828 rtf_label, pref);
829 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
830 #endif
831
832 if (can_do_tsv(vwin)) {
833 /* tab-separated option */
834 button = copy_item_button(group, vbox, finfo, GRETL_FORMAT_TAB,
835 _("Tab separated"), pref);
836 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
837 }
838
839 if (can_do_csv(vwin)) {
840 /* comma-separated option */
841 button = copy_item_button(group, vbox, finfo, GRETL_FORMAT_CSV,
842 _("Comma separated"), pref);
843 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
844 }
845
846 /* plain text option */
847 button = copy_item_button(group, vbox, finfo, GRETL_FORMAT_TXT,
848 _("plain text"), pref);
849 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
850
851 /* LaTeX option? */
852 if (finfo->multi) {
853 button = copy_item_button(group, vbox, finfo, GRETL_FORMAT_TEX,
854 "LaTeX", pref);
855 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
856 }
857
858 #ifndef G_OS_WIN32
859 /* not Windows: put RTF option last */
860 button = copy_item_button(group, vbox, finfo, rtf_format,
861 rtf_label, pref);
862 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
863 #endif
864
865 hbox = gtk_hbox_new(FALSE, 5);
866 gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 5);
867
868 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
869 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 2);
870
871 /* buttons */
872 hbox = gtk_dialog_get_action_area(GTK_DIALOG(dialog));
873 cancel_delete_button(hbox, dialog);
874 tmp = ok_button(hbox);
875 g_signal_connect(G_OBJECT(tmp), "clicked",
876 G_CALLBACK(copy_with_format_callback), finfo);
877 gtk_widget_grab_default(tmp);
878
879 gretl_dialog_keep_above(dialog);
880 gtk_widget_show_all(dialog);
881 }
882
883 enum {
884 SET_CI = 1,
885 SET_PVAL,
886 SET_PAIRS,
887 SET_WILD,
888 SET_UHAT,
889 SET_NORMAL,
890 SET_STUDENT
891 };
892
set_bs_opt(GtkWidget * w,gretlopt * opt)893 static void set_bs_opt (GtkWidget *w, gretlopt *opt)
894 {
895 int i = widget_get_int(w, "action");
896
897 switch (i) {
898 case SET_CI:
899 *opt &= ~OPT_T;
900 *opt &= ~OPT_P;
901 break;
902 case SET_PVAL:
903 *opt &= ~OPT_T;
904 *opt |= OPT_P;
905 break;
906 case SET_UHAT:
907 *opt &= ~OPT_X;
908 *opt &= ~OPT_W;
909 *opt &= ~OPT_N;
910 break;
911 case SET_PAIRS:
912 *opt &= ~OPT_N;
913 *opt &= ~OPT_W;
914 *opt |= OPT_X;
915 break;
916 case SET_WILD:
917 *opt &= ~OPT_N;
918 *opt &= ~OPT_X;
919 *opt |= OPT_W;
920 break;
921 case SET_NORMAL:
922 *opt &= ~OPT_X;
923 *opt &= ~OPT_W;
924 *opt |= OPT_N;
925 break;
926 case SET_STUDENT:
927 *opt &= ~OPT_P;
928 *opt |= OPT_T;
929 break;
930 }
931 }
932
bs_select_coeff(GtkComboBox * b,int * p)933 static void bs_select_coeff (GtkComboBox *b, int *p)
934 {
935 *p = gtk_combo_box_get_active(b);
936 }
937
938 struct replic_set {
939 GtkWidget *dlg;
940 GtkWidget *w;
941 int *B;
942 };
943
set_bs_replics(GtkButton * b,struct replic_set * rs)944 static void set_bs_replics (GtkButton *b, struct replic_set *rs)
945 {
946 char *s = combo_box_get_active_text(GTK_COMBO_BOX(rs->w));
947 char *test = NULL;
948 unsigned long u;
949
950 errno = 0;
951 u = strtoul(s, &test, 10);
952 if (*test != '\0' || errno || (int) u <= 0) {
953 warnbox(_("Invalid entry"));
954 } else {
955 *rs->B = (int) u;
956 gtk_widget_destroy(rs->dlg);
957 }
958
959 g_free(s);
960 }
961
make_replics_list(GtkWidget * w)962 static void make_replics_list (GtkWidget *w)
963 {
964 combo_box_append_text(w, "100");
965 combo_box_append_text(w, "1000");
966 combo_box_append_text(w, "10000");
967 combo_box_append_text(w, "100000");
968
969 gtk_combo_box_set_active(GTK_COMBO_BOX(w), 1);
970 }
971
bs_coeff_popdown(MODEL * pmod,int * pp)972 static GtkWidget *bs_coeff_popdown (MODEL *pmod, int *pp)
973 {
974 GtkWidget *w;
975 int *xlist = NULL;
976 int i, vi;
977
978 xlist = gretl_model_get_x_list(pmod);
979 if (xlist == NULL) {
980 return NULL;
981 }
982
983 w = gtk_combo_box_text_new();
984
985 for (i=1; i<=xlist[0]; i++) {
986 vi = xlist[i];
987 combo_box_append_text(w, dataset->varname[vi]);
988 }
989
990 if (pmod->ifc && pmod->ncoeff > 1) {
991 *pp = 1;
992 gtk_combo_box_set_active(GTK_COMBO_BOX(w), 1);
993 } else {
994 *pp = 0;
995 gtk_combo_box_set_active(GTK_COMBO_BOX(w), 0);
996 }
997
998 free(xlist);
999
1000 return w;
1001 }
1002
bootstrap_dialog(windata_t * vwin,int * pp,int * pB,gretlopt * popt)1003 int bootstrap_dialog (windata_t *vwin, int *pp, int *pB,
1004 gretlopt *popt)
1005 {
1006 MODEL *pmod = vwin->data;
1007 GtkWidget *dialog, *hbox, *vbox;
1008 GtkWidget *popdown = NULL;
1009 GtkWidget *button;
1010 GtkWidget *tmp;
1011 GSList *group = NULL;
1012 gchar *tmpstr;
1013 struct replic_set rs;
1014 int htest = (pp == NULL);
1015 int ret = GRETL_CANCEL;
1016
1017 if (maybe_raise_dialog()) {
1018 return ret;
1019 }
1020
1021 if (pp != NULL) {
1022 popdown = bs_coeff_popdown(pmod, pp);
1023 if (popdown == NULL) {
1024 gui_errmsg(E_DATA);
1025 return ret;
1026 }
1027 }
1028
1029 dialog = gretl_dialog_new(_("gretl: bootstrap analysis"),
1030 vwin_toplevel(vwin),
1031 GRETL_DLG_BLOCK);
1032 rs.dlg = dialog;
1033
1034 vbox = gtk_vbox_new(FALSE, 5);
1035 hbox = gtk_hbox_new(FALSE, 5);
1036 tmpstr = g_strdup_printf("%s:", _("Coefficient"));
1037 tmp = gtk_label_new(tmpstr);
1038 g_free(tmpstr);
1039 gtk_box_pack_start(GTK_BOX(hbox), tmp, TRUE, TRUE, 5);
1040
1041 if (htest) {
1042 /* not selecting coeff, or conf int vs p-value */
1043 goto htest_only;
1044 }
1045
1046 /* coefficient / variable selection */
1047
1048 g_signal_connect(G_OBJECT(popdown), "changed",
1049 G_CALLBACK(bs_select_coeff), pp);
1050 gtk_box_pack_start(GTK_BOX(hbox), popdown, TRUE, TRUE, 5);
1051 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
1052
1053 vbox_add_hsep(vbox);
1054
1055 /* confidence interval vs p-value */
1056
1057 button = gtk_radio_button_new_with_label(NULL, _("Confidence interval"));
1058 gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0);
1059 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (button), TRUE);
1060 g_object_set_data(G_OBJECT(button), "action", GINT_TO_POINTER(SET_CI));
1061 g_signal_connect(G_OBJECT(button), "clicked",
1062 G_CALLBACK(set_bs_opt), popt);
1063
1064 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
1065 button = gtk_radio_button_new_with_label(group, _("Studentized confidence interval"));
1066 gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0);
1067 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (button), FALSE);
1068 g_object_set_data(G_OBJECT(button), "action", GINT_TO_POINTER(SET_STUDENT));
1069 g_signal_connect(G_OBJECT(button), "clicked",
1070 G_CALLBACK(set_bs_opt), popt);
1071
1072 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
1073 button = gtk_radio_button_new_with_label(group, _("P-value"));
1074 gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0);
1075 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (button), FALSE);
1076 g_object_set_data(G_OBJECT(button), "action", GINT_TO_POINTER(SET_PVAL));
1077 g_signal_connect(G_OBJECT(button), "clicked",
1078 G_CALLBACK(set_bs_opt), popt);
1079
1080 vbox_add_hsep(vbox);
1081
1082 htest_only:
1083
1084 /* bootstrap method options */
1085
1086 button = gtk_radio_button_new_with_label(NULL, _("Resample residuals"));
1087 gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0);
1088 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (button), TRUE);
1089 g_object_set_data(G_OBJECT(button), "action", GINT_TO_POINTER(SET_UHAT));
1090 g_signal_connect(G_OBJECT(button), "clicked",
1091 G_CALLBACK(set_bs_opt), popt);
1092
1093 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
1094 button = gtk_radio_button_new_with_label(group, _("Resample data \"pairs\""));
1095 gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0);
1096 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (button), FALSE);
1097 g_object_set_data(G_OBJECT(button), "action", GINT_TO_POINTER(SET_PAIRS));
1098 g_signal_connect(G_OBJECT(button), "clicked",
1099 G_CALLBACK(set_bs_opt), popt);
1100
1101 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
1102 button = gtk_radio_button_new_with_label(group, _("Wild bootstrap"));
1103 gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0);
1104 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (button), FALSE);
1105 g_object_set_data(G_OBJECT(button), "action", GINT_TO_POINTER(SET_WILD));
1106 g_signal_connect(G_OBJECT(button), "clicked",
1107 G_CALLBACK(set_bs_opt), popt);
1108
1109 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
1110 button = gtk_radio_button_new_with_label(group, _("Simulate normal errors"));
1111 gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0);
1112 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (button), FALSE);
1113 g_object_set_data(G_OBJECT(button), "action", GINT_TO_POINTER(SET_NORMAL));
1114 g_signal_connect(G_OBJECT(button), "clicked",
1115 G_CALLBACK(set_bs_opt), popt);
1116
1117 vbox_add_hsep(vbox);
1118
1119 /* Number of replications */
1120
1121 hbox = gtk_hbox_new(FALSE, 5);
1122 tmp = gtk_label_new(_("Number of replications:"));
1123 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
1124
1125 rs.B = pB;
1126 rs.w = combo_box_text_new_with_entry();
1127 make_replics_list(rs.w);
1128 tmp = gtk_bin_get_child(GTK_BIN(rs.w));
1129 gtk_entry_set_width_chars(GTK_ENTRY(tmp), 7);
1130 gtk_box_pack_start(GTK_BOX(hbox), rs.w, FALSE, FALSE, 5);
1131
1132 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
1133
1134 if (!htest) {
1135 /* graph check box */
1136 button = gretl_option_check_button(_("Show graph of sampling "
1137 "distribution"),
1138 popt, OPT_G);
1139 gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 5);
1140 }
1141
1142 /* switch for saving output to file */
1143 button = gretl_option_check_button(_("Save bootstrap data to file"),
1144 popt, OPT_A);
1145 gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 5);
1146
1147 /* pack all of the above */
1148 hbox = gtk_hbox_new(FALSE, 5);
1149 gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 5);
1150 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
1151 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
1152
1153 /* buttons */
1154 hbox = gtk_dialog_get_action_area(GTK_DIALOG(dialog));
1155 cancel_delete_button(hbox, dialog);
1156 button = ok_button(hbox);
1157 g_signal_connect(G_OBJECT(button), "clicked",
1158 G_CALLBACK(set_ret_yes), &ret);
1159 g_signal_connect(G_OBJECT(button), "clicked",
1160 G_CALLBACK(set_bs_replics), &rs);
1161 gtk_widget_grab_default(button);
1162 if (!htest) {
1163 context_help_button(hbox, BOOTSTRAP);
1164 } else {
1165 gretl_dialog_keep_above(dialog);
1166 }
1167
1168 gtk_widget_show_all(dialog);
1169
1170 return ret;
1171 }
1172
db_descrip_callback(GtkWidget * w,GtkWidget * dlg)1173 static void db_descrip_callback (GtkWidget *w, GtkWidget *dlg)
1174 {
1175 GtkWidget *entry;
1176 gchar *fname;
1177
1178 entry = g_object_get_data(G_OBJECT(dlg), "entry");
1179 fname = g_object_get_data(G_OBJECT(dlg), "fname");
1180
1181 if (entry != NULL && fname != NULL) {
1182 const gchar *newdesc = gtk_entry_get_text(GTK_ENTRY(entry));
1183
1184 write_db_description(fname, newdesc);
1185 }
1186
1187 gtk_widget_destroy(dlg);
1188 }
1189
free_db_fname(GtkWidget * w,char * fname)1190 static void free_db_fname (GtkWidget *w, char *fname)
1191 {
1192 g_free(fname);
1193 }
1194
database_description_dialog(const char * binname)1195 void database_description_dialog (const char *binname)
1196 {
1197 GtkWidget *dlg, *entry;
1198 GtkWidget *tmp, *vbox, *hbox;
1199 gchar *fname, *descrip;
1200
1201 if (maybe_raise_dialog()) {
1202 return;
1203 }
1204
1205 descrip = get_db_description(binname);
1206 if (descrip == NULL) {
1207 return;
1208 }
1209
1210 fname = g_strdup(binname);
1211
1212 dlg = gretl_dialog_new(_("gretl: database description"), NULL,
1213 GRETL_DLG_BLOCK | GRETL_DLG_RESIZE);
1214
1215 hbox = gtk_hbox_new(FALSE, 5);
1216 tmp = gtk_label_new(_("description:"));
1217 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 0);
1218
1219 g_signal_connect(G_OBJECT(dlg), "destroy",
1220 G_CALLBACK(free_db_fname), fname);
1221
1222 entry = gtk_entry_new();
1223 gtk_entry_set_max_length(GTK_ENTRY(entry), 64);
1224 gtk_entry_set_width_chars(GTK_ENTRY(entry), 32);
1225
1226 gtk_entry_set_text(GTK_ENTRY(entry), descrip);
1227 gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, FALSE, 0);
1228 gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
1229
1230 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dlg));
1231 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
1232
1233 /* set data on dialog */
1234 g_object_set_data(G_OBJECT(dlg), "entry", entry);
1235 g_object_set_data(G_OBJECT(dlg), "fname", fname);
1236
1237 /* buttons */
1238 hbox = gtk_dialog_get_action_area(GTK_DIALOG(dlg));
1239 tmp = ok_button(hbox);
1240 g_signal_connect(G_OBJECT(tmp), "clicked",
1241 G_CALLBACK(db_descrip_callback), dlg);
1242 gtk_widget_grab_default(tmp);
1243
1244 gretl_set_window_modal(dlg);
1245 gtk_widget_show_all(dlg);
1246 }
1247
set_rand_seed(GtkWidget * w,GtkAdjustment * adj)1248 static void set_rand_seed (GtkWidget *w, GtkAdjustment *adj)
1249 {
1250 guint32 s = (guint32) gtk_adjustment_get_value(GTK_ADJUSTMENT(adj));
1251
1252 gretl_rand_set_seed(s);
1253 lib_command_sprintf("set seed %u", s);
1254 record_command_verbatim();
1255 }
1256
rand_seed_dialog(void)1257 void rand_seed_dialog (void)
1258 {
1259 GtkWidget *dlg;
1260 GtkWidget *tmp, *hbox, *vbox;
1261 GtkAdjustment *adj;
1262 guint32 dseed;
1263
1264 if (maybe_raise_dialog()) {
1265 return;
1266 }
1267
1268 dlg = gretl_dialog_new(_("gretl: seed for random numbers"), NULL,
1269 GRETL_DLG_BLOCK | GRETL_DLG_RESIZE);
1270
1271 hbox = gtk_hbox_new(FALSE, 5);
1272 tmp = gtk_label_new(_("Seed for generator:"));
1273 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
1274
1275 dseed = gretl_rand_get_seed();
1276 adj = (GtkAdjustment *) gtk_adjustment_new((gdouble) dseed, 1,
1277 (gdouble) UINT_MAX,
1278 1, 10000, 0);
1279 tmp = gtk_spin_button_new(adj, 1, 0);
1280 gtk_entry_set_width_chars(GTK_ENTRY(tmp), 10);
1281 gtk_entry_set_activates_default(GTK_ENTRY(tmp), TRUE);
1282 gtk_box_pack_start(GTK_BOX(hbox), tmp, TRUE, TRUE, 5);
1283
1284 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dlg));
1285 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
1286
1287 /* buttons */
1288 hbox = gtk_dialog_get_action_area(GTK_DIALOG(dlg));
1289 cancel_delete_button(hbox, dlg);
1290 tmp = ok_button(hbox);
1291 g_signal_connect(G_OBJECT(tmp), "clicked",
1292 G_CALLBACK(set_rand_seed), adj);
1293 g_signal_connect(G_OBJECT(tmp), "clicked",
1294 G_CALLBACK(delete_widget), dlg);
1295 gtk_widget_grab_default(tmp);
1296 context_help_button(hbox, SEED_RANDOM);
1297
1298 gtk_widget_show_all(dlg);
1299 }
1300
set_listname(GtkComboBox * combo,char * listname)1301 static void set_listname (GtkComboBox *combo,
1302 char *listname)
1303 {
1304 gchar *active = combo_box_get_active_text(combo);
1305
1306 strcpy(listname, active);
1307 g_free(active);
1308 }
1309
select_list_dialog(char * listname)1310 int select_list_dialog (char *listname)
1311 {
1312 GtkWidget *dlg;
1313 GtkWidget *combo;
1314 GtkWidget *hbox, *vbox, *tmp;
1315 GList *llist;
1316 int ret = GRETL_CANCEL;
1317
1318 if (maybe_raise_dialog()) {
1319 return ret;
1320 }
1321
1322 dlg = gretl_dialog_new(NULL, NULL, GRETL_DLG_BLOCK);
1323
1324 llist = user_var_names_for_type(GRETL_TYPE_LIST);
1325 llist = g_list_first(llist);
1326 strcpy(listname, (char *) llist->data);
1327
1328 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dlg));
1329
1330 /* label */
1331 hbox = gtk_hbox_new(FALSE, 5);
1332 tmp = gtk_label_new(_("Choose named list"));
1333 gtk_box_pack_start(GTK_BOX(hbox), tmp, TRUE, TRUE, 5);
1334 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
1335
1336 /* selector */
1337 hbox = gtk_hbox_new(FALSE, 5);
1338 combo = gtk_combo_box_text_new();
1339 set_combo_box_strings_from_list(combo, llist);
1340 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0);
1341 g_signal_connect(G_OBJECT(combo), "changed",
1342 G_CALLBACK(set_listname), listname);
1343 gtk_box_pack_start(GTK_BOX(hbox), combo, TRUE, FALSE, 5);
1344 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
1345 g_list_free(llist);
1346
1347 /* buttons */
1348 hbox = gtk_dialog_get_action_area(GTK_DIALOG(dlg));
1349 cancel_delete_button(hbox, dlg);
1350 tmp = ok_validate_button(hbox, &ret, NULL);
1351 g_signal_connect(G_OBJECT(tmp), "clicked",
1352 G_CALLBACK(delete_widget), dlg);
1353 gtk_widget_grab_default(tmp);
1354
1355 gtk_widget_show_all(dlg);
1356
1357 return ret;
1358 }
1359
combo_set_retval(GtkComboBox * combo,int * ret)1360 static void combo_set_retval (GtkComboBox *combo, int *ret)
1361 {
1362 *ret = gtk_combo_box_get_active(combo);
1363 }
1364
combo_selector_dialog(GList * list,const char * msg,int deflt,GtkWidget * parent)1365 int combo_selector_dialog (GList *list, const char *msg,
1366 int deflt, GtkWidget *parent)
1367 {
1368 GtkWidget *dlg;
1369 GtkWidget *combo;
1370 GtkWidget *hbox, *vbox, *tmp;
1371 int selval = deflt;
1372 int ret = GRETL_CANCEL;
1373
1374 dlg = gretl_dialog_new(NULL, parent, GRETL_DLG_BLOCK);
1375 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dlg));
1376
1377 /* label */
1378 hbox = gtk_hbox_new(FALSE, 5);
1379 tmp = gtk_label_new(msg);
1380 gtk_box_pack_start(GTK_BOX(hbox), tmp, TRUE, TRUE, 5);
1381 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
1382
1383 /* selector */
1384 hbox = gtk_hbox_new(FALSE, 5);
1385 combo = gtk_combo_box_text_new();
1386 set_combo_box_strings_from_list(combo, list);
1387 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), deflt);
1388 g_signal_connect(G_OBJECT(combo), "changed",
1389 G_CALLBACK(combo_set_retval), &selval);
1390 gtk_box_pack_start(GTK_BOX(hbox), combo, TRUE, FALSE, 5);
1391 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
1392
1393 /* buttons */
1394 hbox = gtk_dialog_get_action_area(GTK_DIALOG(dlg));
1395 cancel_delete_button(hbox, dlg);
1396 tmp = ok_validate_button(hbox, &ret, &selval);
1397 g_signal_connect(G_OBJECT(tmp), "clicked",
1398 G_CALLBACK(delete_widget), dlg);
1399 gtk_widget_grab_default(tmp);
1400
1401 gtk_widget_show_all(dlg);
1402
1403 return ret;
1404 }
1405
bfgs_mode_callback(GtkToggleButton * button,int * s)1406 static void bfgs_mode_callback (GtkToggleButton *button, int *s)
1407 {
1408 if (gtk_toggle_button_get_active(button)) {
1409 *s = LBFGS_MAX;
1410 } else {
1411 *s = BFGS_MAX;
1412 }
1413 }
1414
1415 struct ic_info {
1416 double v1;
1417 int v2;
1418 double *ptol;
1419 int *ret;
1420 };
1421
iter_control_callback(GtkButton * b,struct ic_info * ic)1422 static void iter_control_callback (GtkButton *b, struct ic_info *ic)
1423 {
1424 char numstr[32];
1425
1426 sprintf(numstr, "%fe-%d", ic->v1, ic->v2);
1427 *ic->ptol = atof(numstr);
1428 *ic->ret = 0;
1429 }
1430
iter_control_dialog(int * optim,int * pmaxit,double * ptol,int * plmem,GtkWidget * parent)1431 int iter_control_dialog (int *optim, int *pmaxit, double *ptol,
1432 int *plmem, GtkWidget *parent)
1433 {
1434 struct ic_info ic;
1435 static GtkWidget *dlg;
1436 GtkWidget *tmp, *hbox, *vbox;
1437 const char *title;
1438 char *s, numstr[32];
1439 int ret = GRETL_CANCEL;
1440
1441 if (dlg != NULL) {
1442 gtk_window_present(GTK_WINDOW(dlg));
1443 return ret;
1444 }
1445
1446 dlg = gretl_dialog_new(_("gretl: iteration controls"), parent,
1447 GRETL_DLG_BLOCK);
1448
1449 g_signal_connect(G_OBJECT(dlg), "destroy",
1450 G_CALLBACK(gtk_widget_destroyed), &dlg);
1451
1452 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dlg));
1453
1454 sprintf(numstr, "%g", *ptol);
1455 s = strchr(numstr, '-');
1456 *s = '\0';
1457
1458 ic.v1 = atof(numstr);
1459 ic.v2 = atoi(s+1);
1460 ic.ptol = ptol;
1461 ic.ret = &ret;
1462
1463 title = (*optim == BHHH_MAX)? N_("BHHH maximizer") :
1464 N_("BFGS maximizer");
1465
1466 hbox = gtk_hbox_new(FALSE, 5);
1467 tmp = gtk_label_new(_(title));
1468 gtk_box_pack_start(GTK_BOX(hbox), tmp, TRUE, TRUE, 5);
1469 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
1470
1471 hbox = gtk_hbox_new(FALSE, 5);
1472 tmp = gtk_label_new(_("Maximum iterations:"));
1473 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
1474 tmp = gtk_spin_button_new_with_range(100, 100000, 100);
1475 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tmp), *pmaxit);
1476 g_signal_connect(G_OBJECT(tmp), "value-changed",
1477 G_CALLBACK(set_int_from_spinner), pmaxit);
1478 gtk_entry_set_activates_default(GTK_ENTRY(tmp), TRUE);
1479 gtk_box_pack_start(GTK_BOX(hbox), tmp, TRUE, TRUE, 5);
1480 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
1481
1482 hbox = gtk_hbox_new(FALSE, 5);
1483 tmp = gtk_label_new(_("Convergence tolerance:"));
1484 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
1485 tmp = gtk_spin_button_new_with_range(1.00, 9.99, 0.01);
1486 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tmp), ic.v1);
1487 g_signal_connect(G_OBJECT(tmp), "value-changed",
1488 G_CALLBACK(set_double_from_spinner), &ic.v1);
1489 gtk_entry_set_activates_default(GTK_ENTRY(tmp), TRUE);
1490 gtk_box_pack_start(GTK_BOX(hbox), tmp, TRUE, TRUE, 0);
1491
1492 tmp = gtk_label_new("E-");
1493 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 0);
1494 tmp = gtk_spin_button_new_with_range(2, 14, 1);
1495 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tmp), ic.v2);
1496 g_signal_connect(G_OBJECT(tmp), "value-changed",
1497 G_CALLBACK(set_int_from_spinner), &ic.v2);
1498 gtk_entry_set_activates_default(GTK_ENTRY(tmp), TRUE);
1499 gtk_box_pack_start(GTK_BOX(hbox), tmp, TRUE, TRUE, 0);
1500 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
1501
1502 if (*optim != BHHH_MAX) {
1503 GtkWidget *lb;
1504
1505 hbox = gtk_hbox_new(FALSE, 5);
1506 lb = gtk_check_button_new_with_label(_("Use L-BFGS-B, memory size:"));
1507 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lb),
1508 (*optim == LBFGS_MAX));
1509 g_signal_connect(G_OBJECT(lb), "toggled",
1510 G_CALLBACK(bfgs_mode_callback), optim);
1511 gtk_box_pack_start(GTK_BOX(hbox), lb, FALSE, FALSE, 5);
1512 tmp = gtk_spin_button_new_with_range(3, 20, 1);
1513 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tmp), *plmem);
1514 g_signal_connect(G_OBJECT(tmp), "value-changed",
1515 G_CALLBACK(set_int_from_spinner), plmem);
1516 gtk_entry_set_activates_default(GTK_ENTRY(tmp), TRUE);
1517 gtk_widget_set_sensitive(tmp, (*optim == LBFGS_MAX));
1518 sensitize_conditional_on(tmp, lb);
1519 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 0);
1520 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
1521 }
1522
1523 /* buttons */
1524 hbox = gtk_dialog_get_action_area(GTK_DIALOG(dlg));
1525 cancel_delete_button(hbox, dlg);
1526 tmp = ok_button(hbox);
1527 g_signal_connect(G_OBJECT(tmp), "clicked",
1528 G_CALLBACK(iter_control_callback), &ic);
1529 g_signal_connect(G_OBJECT(tmp), "clicked",
1530 G_CALLBACK(delete_widget), dlg);
1531 gtk_widget_grab_default(tmp);
1532 if (*optim == BFGS_MAX) {
1533 context_help_button(hbox, BFGS_CONFIG);
1534 }
1535
1536 gtk_widget_show_all(dlg);
1537
1538 return ret;
1539 }
1540
1541 /* apparatus for setting sample range */
1542
1543 struct range_setting {
1544 gretlopt opt;
1545 DATASET dinfo; /* auxiliary data info structure */
1546 GtkWidget *dlg; /* dialog box */
1547 GtkWidget *obslabel; /* label for showing number of selected obs */
1548 GtkAdjustment *adj1; /* adjustment for start spinner */
1549 GtkAdjustment *adj2; /* adjustment for end spinner */
1550 GtkWidget *spin1; /* start-of-range spinner */
1551 GtkWidget *spin2; /* end-of-range spinner */
1552 GtkWidget *combo; /* multi-purpose selector */
1553 GtkWidget *entry;
1554 gboolean markers;
1555 gpointer p;
1556 MODEL *pmod;
1557 int *t1;
1558 int *t2;
1559 };
1560
free_rsetting(GtkWidget * w,struct range_setting * rset)1561 static void free_rsetting (GtkWidget *w, struct range_setting *rset)
1562 {
1563 set_active_edit_name(NULL);
1564 free(rset);
1565 }
1566
unit_get_first_obs(int u)1567 static int unit_get_first_obs (int u)
1568 {
1569 return u * dataset->pd;
1570 }
1571
unit_get_last_obs(int u)1572 static int unit_get_last_obs (int u)
1573 {
1574 return (u+1) * dataset->pd - 1;
1575 }
1576
1577 static gboolean
set_sample_from_dialog(GtkWidget * w,struct range_setting * rset)1578 set_sample_from_dialog (GtkWidget *w, struct range_setting *rset)
1579 {
1580 const char *extra;
1581 int err;
1582
1583 if ((rset->opt & OPT_P) && (rset->opt & OPT_T)) {
1584 extra = " --replace --permanent";
1585 } else if (rset->opt & OPT_P) {
1586 extra = " --replace";
1587 } else if (rset->opt & OPT_T) {
1588 extra = " --permanent";
1589 } else {
1590 extra = "";
1591 }
1592
1593 if (rset->opt & OPT_R) {
1594 /* boolean restriction */
1595 gchar *s = get_genr_string(rset->entry, NULL);
1596
1597 if (s == NULL) {
1598 return TRUE;
1599 }
1600
1601 err = bool_subsample(s, rset->opt, rset->dlg);
1602 if (!err) {
1603 lib_command_sprintf("smpl %s --restrict%s", s, extra);
1604 record_command_verbatim();
1605 gtk_widget_destroy(rset->dlg);
1606 }
1607 g_free(s);
1608 } else if (rset->opt & OPT_O) {
1609 /* sampling using a dummy var */
1610 gchar *dumv;
1611
1612 dumv = combo_box_get_active_text(GTK_COMBO_BOX(rset->combo));
1613 err = bool_subsample(dumv, rset->opt, rset->dlg);
1614 if (!err) {
1615 lib_command_sprintf("smpl %s --dummy%s", dumv, extra);
1616 record_command_verbatim();
1617 gtk_widget_destroy(rset->dlg);
1618 }
1619 g_free(dumv);
1620 } else if (rset->opt & OPT_N) {
1621 /* random subsample */
1622 int subn = obs_button_get_value(rset->spin1);
1623 gchar *nstr = g_strdup_printf("%d", subn);
1624
1625 err = bool_subsample(nstr, rset->opt, rset->dlg);
1626 if (!err) {
1627 lib_command_sprintf("smpl %d --random%s", subn, extra);
1628 record_command_verbatim();
1629 gtk_widget_destroy(rset->dlg);
1630 }
1631 g_free(nstr);
1632 } else {
1633 GtkSpinButton *button;
1634 char s1[OBSLEN], s2[OBSLEN];
1635 int t1, t2;
1636
1637 button = GTK_SPIN_BUTTON(rset->spin1);
1638 strcpy(s1, gtk_entry_get_text(GTK_ENTRY(button)));
1639 t1 = gtk_spin_button_get_value_as_int(button);
1640
1641 button = GTK_SPIN_BUTTON(rset->spin2);
1642 strcpy(s2, gtk_entry_get_text(GTK_ENTRY(button)));
1643 t2 = gtk_spin_button_get_value_as_int(button);
1644
1645 if (rset->opt & OPT_C) {
1646 /* creating a new dataset */
1647 gchar **obsstr = (gchar **) rset->p;
1648
1649 if (obsstr != NULL) {
1650 *obsstr = g_strdup_printf("%s %s", s1, s2);
1651 }
1652 gtk_widget_destroy(rset->dlg);
1653 return TRUE;
1654 } else if (rset->opt & OPT_P) {
1655 /* selecting panel group range */
1656 t1 = unit_get_first_obs(t1);
1657 t2 = unit_get_last_obs(t2);
1658 ntolabel(s1, t1, dataset);
1659 ntolabel(s2, t2, dataset);
1660 }
1661
1662 if (t1 != dataset->t1 || t2 != dataset->t2) {
1663 err = set_sample(s1, s2, dataset, 0);
1664 if (err) {
1665 gui_errmsg(err);
1666 } else {
1667 lib_command_sprintf("smpl %s %s", s1, s2);
1668 record_command_verbatim();
1669 gtk_widget_destroy(rset->dlg);
1670 set_sample_label(dataset);
1671 mark_session_changed();
1672 }
1673 } else {
1674 /* no change */
1675 gtk_widget_destroy(rset->dlg);
1676 }
1677 }
1678
1679 return TRUE;
1680 }
1681
1682 static void
set_obs_from_dialog(GtkButton * b,struct range_setting * rset)1683 set_obs_from_dialog (GtkButton *b, struct range_setting *rset)
1684 {
1685 GtkSpinButton *button;
1686
1687 if (rset->spin1 != NULL && rset->t1 != NULL) {
1688 button = GTK_SPIN_BUTTON(rset->spin1);
1689 *rset->t1 = gtk_spin_button_get_value_as_int(button);
1690 }
1691
1692 if (rset->spin2 != NULL && rset->t2 != NULL) {
1693 button = GTK_SPIN_BUTTON(rset->spin2);
1694 *rset->t2 = gtk_spin_button_get_value_as_int(button);
1695 }
1696
1697 gtk_widget_destroy(rset->dlg);
1698 }
1699
get_dummy_list(int * thisdum)1700 static GList *get_dummy_list (int *thisdum)
1701 {
1702 GList *dumlist = NULL;
1703 int v = mdata_active_var();
1704 int i, j = 0;
1705
1706 for (i=1; i<dataset->v; i++) {
1707 if (gretl_isdummy(dataset->t1, dataset->t2, dataset->Z[i])) {
1708 dumlist = g_list_append(dumlist, dataset->varname[i]);
1709 if (i == v) {
1710 *thisdum = j;
1711 }
1712 j++;
1713 }
1714 }
1715
1716 return dumlist;
1717 }
1718
update_obs_label(GtkComboBox * box,gpointer data)1719 gboolean update_obs_label (GtkComboBox *box, gpointer data)
1720 {
1721 struct range_setting *rset = (struct range_setting *) data;
1722 int t1 = 0, t2 = 0, n = 0;
1723
1724 if (box != NULL) {
1725 gchar *vname = combo_box_get_active_text(box);
1726
1727 if (vname != NULL) {
1728 int v = series_index(dataset, vname);
1729
1730 if (v < dataset->v) {
1731 n = gretl_isdummy(0, dataset->n - 1, dataset->Z[v]);
1732 }
1733 g_free(vname);
1734 }
1735 } else {
1736 t1 = obs_button_get_value(rset->spin1);
1737 t2 = obs_button_get_value(rset->spin2);
1738 n = t2 - t1 + 1;
1739 }
1740
1741 if (n > 0) {
1742 gchar *obstr = NULL;
1743
1744 if (rset->opt == OPT_G) {
1745 obstr = g_strdup_printf(_("groups (N = %d)"), n);
1746 } else if (rset->opt == OPT_P) {
1747 obstr = g_strdup_printf(_("Included groups: %d"), n);
1748 } else {
1749 obstr = g_strdup_printf(_("Observations: %d"), n);
1750 }
1751
1752 if (rset->markers) {
1753 const char *s1 = dataset->S[t1];
1754 const char *s2 = dataset->S[t2];
1755 gchar *tmp = g_strconcat(obstr, "\n(", s1,
1756 " .. ", s2, ")", NULL);
1757
1758 g_free(obstr);
1759 obstr = tmp;
1760 }
1761
1762 gtk_label_set_text(GTK_LABEL(rset->obslabel), obstr);
1763 g_free(obstr);
1764 }
1765
1766 return FALSE;
1767 }
1768
default_randsize(void)1769 static int default_randsize (void)
1770 {
1771 int n = sample_size(dataset);
1772
1773 if (n > 1000) {
1774 return n / 10;
1775 } else {
1776 return n / 2;
1777 }
1778 }
1779
rset_new(guint code,gpointer p,MODEL * pmod,int * t1,int * t2,const gchar * title,GtkWidget * parent)1780 static struct range_setting *rset_new (guint code, gpointer p,
1781 MODEL *pmod,
1782 int *t1, int *t2,
1783 const gchar *title,
1784 GtkWidget *parent)
1785 {
1786 struct range_setting *rset;
1787
1788 rset = mymalloc(sizeof *rset);
1789 if (rset == NULL) return NULL;
1790
1791 rset->opt = OPT_NONE;
1792 rset->markers = 0;
1793
1794 if (code == SMPLDUM) {
1795 rset->opt = OPT_O;
1796 } else if (code == SMPLBOOL) {
1797 rset->opt = OPT_R;
1798 } else if (code == SMPLRAND) {
1799 rset->opt = OPT_N;
1800 } else if (code == CREATE_DATASET) {
1801 rset->opt = OPT_C;
1802 }
1803
1804 rset->dlg = gretl_dialog_new(title, parent, GRETL_DLG_BLOCK);
1805 rset->combo = rset->entry = NULL;
1806 rset->adj1 = rset->adj2 = NULL;
1807 rset->spin1 = rset->spin2 = NULL;
1808 rset->obslabel = NULL;
1809
1810 datainfo_init(&rset->dinfo);
1811 rset->p = p;
1812 rset->pmod = pmod;
1813
1814 rset->t1 = t1;
1815 rset->t2 = t2;
1816
1817 return rset;
1818 }
1819
1820 /* Special sample range selector for panel datasets: express the
1821 choice as a matter of which units/groups to include. The
1822 @temp argument is non-zero if we're just setting the panel sample
1823 temporarily for the purpose of doing a panel plot.
1824 */
1825
panel_sample_spinbox(struct range_setting * rset,int temp)1826 static GtkWidget *panel_sample_spinbox (struct range_setting *rset,
1827 int temp)
1828 {
1829 GtkWidget *lbl;
1830 GtkWidget *vbox;
1831 GtkWidget *hbox;
1832
1833 rset->dinfo.n = dataset->n / dataset->pd;
1834
1835 if (temp) {
1836 rset->dinfo.t1 = *rset->t1;
1837 rset->dinfo.t2 = *rset->t2;
1838 } else {
1839 rset->dinfo.t1 = dataset->t1 / dataset->pd;
1840 rset->dinfo.t2 = dataset->t2 / dataset->pd;
1841 }
1842
1843 dataset_obs_info_default(&rset->dinfo);
1844
1845 vbox = gtk_dialog_get_content_area(GTK_DIALOG(rset->dlg));
1846
1847 if (temp) {
1848 hbox = gtk_hbox_new(FALSE, 5);
1849 } else {
1850 lbl = gtk_label_new(_("Panel groups"));
1851 gtk_box_pack_start(GTK_BOX(vbox), lbl, FALSE, FALSE, 5);
1852 hbox = gtk_hbox_new(TRUE, 5);
1853 }
1854
1855 /* spinner for u1 */
1856 lbl = gtk_label_new(_("Start:"));
1857 rset->adj1 = (GtkAdjustment *) gtk_adjustment_new(rset->dinfo.t1, 0,
1858 rset->dinfo.n - 1,
1859 1, 1, 0);
1860 rset->spin1 = obs_button_new(rset->adj1, &rset->dinfo, OBS_BUTTON_T1);
1861
1862 if (temp) {
1863 gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(" "), FALSE, FALSE, 0);
1864 gtk_box_pack_start(GTK_BOX(hbox), lbl, FALSE, FALSE, 5);
1865 gtk_box_pack_start(GTK_BOX(hbox), rset->spin1, FALSE, FALSE, 0);
1866 } else {
1867 vbox = gtk_vbox_new(FALSE, 5);
1868 gtk_box_pack_start(GTK_BOX(vbox), lbl, FALSE, FALSE, 0);
1869 gtk_entry_set_activates_default(GTK_ENTRY(rset->spin1), TRUE);
1870 gtk_box_pack_start(GTK_BOX(vbox), rset->spin1, FALSE, FALSE, 0);
1871 gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 5);
1872 }
1873
1874 /* spinner for u2 */
1875 lbl = gtk_label_new(_("End:"));
1876 rset->adj2 = (GtkAdjustment *) gtk_adjustment_new(rset->dinfo.t2, 0,
1877 rset->dinfo.n - 1,
1878 1, 1, 0);
1879 rset->spin2 = obs_button_new(rset->adj2, &rset->dinfo, OBS_BUTTON_T2);
1880
1881 if (temp) {
1882 gtk_box_pack_start(GTK_BOX(hbox), lbl, FALSE, FALSE, 5);
1883 gtk_box_pack_start(GTK_BOX(hbox), rset->spin2, FALSE, FALSE, 0);
1884 } else {
1885 vbox = gtk_vbox_new(FALSE, 5);
1886 gtk_box_pack_start(GTK_BOX(vbox), lbl, FALSE, FALSE, 0);
1887 gtk_entry_set_activates_default(GTK_ENTRY(rset->spin2), TRUE);
1888 gtk_box_pack_start(GTK_BOX(vbox), rset->spin2, FALSE, FALSE, 0);
1889 gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 5);
1890 }
1891
1892 /* inter-connect the two spinners */
1893 obs_button_set_partner(rset->spin1, rset->spin2);
1894 obs_button_set_partner(rset->spin2, rset->spin1);
1895
1896 return hbox;
1897 }
1898
1899 #if 0 /* not ready yet */
1900
1901 typedef struct panel_setting_ {
1902 int u1, u2;
1903 int t1, t2;
1904 int Nmax, Tmax;
1905 GtkWidget *spin[4];
1906 GtkWidget *dlg;
1907 GtkWidget *obslabel;
1908 } panel_setting;
1909
1910 static panel_setting *pset_new (void)
1911 {
1912 panel_setting *pset;
1913
1914 pset = mymalloc(sizeof *pset);
1915 if (pset == NULL) return NULL;
1916
1917 pset->dlg = gretl_dialog_new(_("gretl: set sample"), NULL,
1918 GRETL_DLG_BLOCK);
1919 pset->obslabel = NULL;
1920
1921 return pset;
1922 }
1923
1924 static void free_pset (GtkWidget *w, panel_setting *pset)
1925 {
1926 free(pset);
1927 }
1928
1929 static void gui_set_panel_sample (GtkWidget *w, panel_setting *pset)
1930 {
1931 int orig_u1 = 1 + dataset->t1 / dataset->pd;
1932 int orig_u2 = (dataset->t2 + 1) / dataset->pd;
1933 int T = pset->t2 - pset->t1 + 1;
1934
1935 fprintf(stderr, "set panel sample\n");
1936 fprintf(stderr, "orig_u1 = %d, orig_u2 = %d\n", orig_u1, orig_u2);
1937 fprintf(stderr, "u1 = %d, u2 = %d, t1 = %d, t2 = %d\n",
1938 pset->u1, pset->u2, pset->t1, pset->t2);
1939
1940 if (T < dataset->pd) {
1941 fprintf(stderr, "Need to shrink (restrict) by time\n");
1942 }
1943
1944 if (pset->u1 != orig_u1 || pset->u2 != orig_u2) {
1945 fprintf(stderr, "Need to smpl by unit\n");
1946 }
1947 }
1948
1949 static void panel_sample_callback (GtkSpinButton *b,
1950 panel_setting *pset)
1951 {
1952 int N, T, k = gtk_spin_button_get_value_as_int(b);
1953 GtkWidget *w = GTK_WIDGET(b);
1954 gchar *msg;
1955
1956 if (w == pset->spin[0]) {
1957 if (k > pset->u2) {
1958 if (pset->u2 < pset->Nmax) {
1959 gtk_spin_button_set_value(GTK_SPIN_BUTTON(pset->spin[1]),
1960 pset->u2 + 1);
1961 } else {
1962 gtk_spin_button_set_value(b, --k);
1963 }
1964 }
1965 pset->u1 = k;
1966 } else if (w == pset->spin[1]) {
1967 if (k < pset->u1) {
1968 if (pset->u1 > 1) {
1969 gtk_spin_button_set_value(GTK_SPIN_BUTTON(pset->spin[0]),
1970 pset->u1 - 1);
1971 } else {
1972 gtk_spin_button_set_value(b, ++k);
1973 }
1974 }
1975 pset->u2 = k;
1976 } else if (w == pset->spin[2]) {
1977 if (k > pset->t2) {
1978 if (pset->t2 < pset->Tmax) {
1979 gtk_spin_button_set_value(GTK_SPIN_BUTTON(pset->spin[3]),
1980 pset->t2 + 1);
1981 } else {
1982 gtk_spin_button_set_value(b, --k);
1983 }
1984 }
1985 pset->t1 = k;
1986 } else if (w == pset->spin[3]) {
1987 if (k < pset->t1) {
1988 if (pset->t1 > 1) {
1989 gtk_spin_button_set_value(GTK_SPIN_BUTTON(pset->spin[2]),
1990 pset->t1 - 1);
1991 } else {
1992 gtk_spin_button_set_value(b, ++k);
1993 }
1994 }
1995 pset->t2 = k;
1996 }
1997
1998 N = pset->u2 - pset->u1 + 1;
1999 T = pset->t2 - pset->t1 + 1;
2000
2001 msg = g_strdup_printf("N=%d, T=%d, NT=%d", N, T, N*T);
2002 gtk_label_set_text(GTK_LABEL(pset->obslabel), msg);
2003 g_free(msg);
2004 }
2005
2006 static void panel_new_spinbox (panel_setting *pset)
2007 {
2008 GtkWidget *lbl, *vbox;
2009 GtkWidget *tbl, *spin;
2010 GtkWidget *hbox;
2011 gchar *msg;
2012 int i, k, N, T;
2013
2014 pset->u1 = 1 + dataset->t1 / dataset->pd;
2015 pset->u2 = (dataset->t2 + 1) / dataset->pd;
2016 pset->t1 = 1;
2017 pset->t2 = dataset->pd;
2018 pset->Nmax = dataset->n / dataset->pd;
2019 pset->Tmax = dataset->pd;
2020
2021 vbox = gtk_dialog_get_content_area(GTK_DIALOG(pset->dlg));
2022 hbox = gtk_hbox_new(FALSE, 5);
2023
2024 tbl = gtk_table_new(2, 4, FALSE);
2025 gtk_table_set_row_spacings(GTK_TABLE(tbl), 5);
2026 gtk_table_set_col_spacings(GTK_TABLE(tbl), 5);
2027 gtk_box_pack_start(GTK_BOX(hbox), tbl, FALSE, FALSE, 5);
2028 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
2029
2030 k = 0;
2031
2032 /* group/unit spinners */
2033 for (i=0; i<2; i++) {
2034 int spinmax = (i==0)? pset->Nmax : pset->Tmax;
2035 int s1 = (i==0)? pset->u1 : pset->t1;
2036 int s2 = (i==0)? pset->u2 : pset->t2;
2037
2038 lbl = gtk_label_new((i==0)? _("Groups") : _("Periods"));
2039 gtk_table_attach_defaults(GTK_TABLE(tbl), lbl, 0, 1, i, i+1);
2040 spin = gtk_spin_button_new_with_range(1, spinmax, 1);
2041 gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin), s1);
2042 pset->spin[k++] = spin;
2043 gtk_table_attach_defaults(GTK_TABLE(tbl), spin,
2044 1, 2, i, i+1);
2045 lbl = gtk_label_new(_("to"));
2046 gtk_table_attach_defaults(GTK_TABLE(tbl), lbl,
2047 2, 3, i, i+1);
2048 spin = gtk_spin_button_new_with_range(1, spinmax, 1);
2049 gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin), s2);
2050 pset->spin[k++] = spin;
2051 gtk_table_attach_defaults(GTK_TABLE(tbl), spin,
2052 3, 4, i, i+1);
2053 }
2054
2055 for (i=0; i<4; i++) {
2056 gtk_entry_set_activates_default(GTK_ENTRY(pset->spin[i]), TRUE);
2057 g_signal_connect(G_OBJECT(pset->spin[i]), "value-changed",
2058 G_CALLBACK(panel_sample_callback), pset);
2059 }
2060
2061 N = pset->u2 - pset->u1 + 1;
2062 T = pset->t2 - pset->t1 + 1;
2063
2064 hbox = gtk_hbox_new(FALSE, 5);
2065 msg = g_strdup_printf("N=%d, T=%d, NT=%d", N, T, N*T);
2066 pset->obslabel = lbl = gtk_label_new(msg);
2067 gtk_box_pack_start(GTK_BOX(hbox), lbl, TRUE, TRUE, 0);
2068 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
2069 g_free(msg);
2070 }
2071
2072 static void panel_sample_dialog (void)
2073 {
2074 panel_setting *pset;
2075 GtkWidget *w, *hbox;
2076
2077 pset = pset_new();
2078 if (pset == NULL) {
2079 return;
2080 }
2081
2082 panel_new_spinbox(pset);
2083
2084 /* buttons */
2085 hbox = gtk_dialog_get_action_area(GTK_DIALOG(pset->dlg));
2086 cancel_delete_button(hbox, pset->dlg);
2087 w = ok_button(hbox);
2088 g_signal_connect(G_OBJECT(w), "clicked",
2089 G_CALLBACK(gui_set_panel_sample), pset);
2090 gtk_widget_grab_default(w);
2091 g_signal_connect(G_OBJECT(pset->dlg), "destroy",
2092 G_CALLBACK(free_pset), pset);
2093
2094 gretl_dialog_keep_above(pset->dlg);
2095 gtk_widget_show_all(pset->dlg);
2096 }
2097
2098 #endif /* not ready */
2099
2100 typedef enum {
2101 SPIN_LABEL_NONE,
2102 SPIN_LABEL_ABOVE,
2103 SPIN_LABEL_INLINE
2104 } SpinLabelAlign;
2105
2106 static GtkWidget *
obs_spinbox(struct range_setting * rset,const char * label,const char * t1str,const char * t2str,int t1min,int t1max,int t1,int t2min,int t2max,int t2,SpinLabelAlign align)2107 obs_spinbox (struct range_setting *rset, const char *label,
2108 const char *t1str, const char *t2str,
2109 int t1min, int t1max, int t1,
2110 int t2min, int t2max, int t2,
2111 SpinLabelAlign align)
2112 {
2113 GtkWidget *lbl;
2114 GtkWidget *vbox;
2115 GtkWidget *hbox;
2116 int smin; /* "step increment" */
2117 int smaj; /* "page increment" */
2118
2119 if (dataset_is_panel(dataset)) {
2120 int tmp;
2121
2122 smin = smaj = dataset->pd;
2123 /* below: minimal selection should be the complete time series
2124 for a single panel unit */
2125 if (t1max == t2max) {
2126 tmp = t1max - dataset->pd;
2127 t1max = (tmp < 0)? 0 : tmp;
2128 }
2129 if (t2min == t1min) {
2130 tmp = t2min + dataset->pd;
2131 t2min = (tmp > dataset->n - 1)? dataset->n - 1 : tmp;
2132 }
2133 } else {
2134 smin = 1;
2135 smaj = dataset->pd;
2136 }
2137
2138 if (label != NULL && align == SPIN_LABEL_ABOVE) {
2139 lbl = gtk_label_new(label);
2140 vbox = gtk_dialog_get_content_area(GTK_DIALOG(rset->dlg));
2141 gtk_box_pack_start(GTK_BOX(vbox), lbl, FALSE, FALSE, 5);
2142 }
2143
2144 if (label != NULL && align == SPIN_LABEL_INLINE) {
2145 hbox = gtk_hbox_new(FALSE, 5);
2146 lbl = gtk_label_new(label);
2147 gtk_box_pack_start(GTK_BOX(hbox), lbl, FALSE, FALSE, 5);
2148 } else {
2149 hbox = gtk_hbox_new(TRUE, 5);
2150 }
2151
2152 /* spinner for t1 */
2153 vbox = gtk_vbox_new(FALSE, 5);
2154 if (t1str != NULL) {
2155 lbl = gtk_label_new(t1str);
2156 gtk_box_pack_start(GTK_BOX(vbox), lbl, FALSE, FALSE, 0);
2157 }
2158 rset->adj1 = (GtkAdjustment *) gtk_adjustment_new(t1, t1min, t1max,
2159 smin, smaj, 0);
2160 rset->spin1 = obs_button_new(rset->adj1, dataset, OBS_BUTTON_T1);
2161 gtk_entry_set_activates_default(GTK_ENTRY(rset->spin1), TRUE);
2162 gtk_box_pack_start(GTK_BOX(vbox), rset->spin1, FALSE, FALSE, 0);
2163 gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 5);
2164
2165 /* spinner for t2, if wanted */
2166 if (!(t2min == 0 && t2max == 0)) {
2167 vbox = gtk_vbox_new(FALSE, 5);
2168 if (t2str != NULL) {
2169 lbl = gtk_label_new(t2str);
2170 gtk_box_pack_start(GTK_BOX(vbox), lbl, FALSE, FALSE, 0);
2171 }
2172 rset->adj2 = (GtkAdjustment *) gtk_adjustment_new(t2, t2min, t2max,
2173 smin, smaj, 0);
2174 rset->spin2 = obs_button_new(rset->adj2, dataset, OBS_BUTTON_T2);
2175 gtk_entry_set_activates_default(GTK_ENTRY(rset->spin2), TRUE);
2176 gtk_box_pack_start(GTK_BOX(vbox), rset->spin2, FALSE, FALSE, 0);
2177 gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 5);
2178
2179 /* inter-connect the two spinners */
2180 obs_button_set_partner(rset->spin1, rset->spin2);
2181 obs_button_set_partner(rset->spin2, rset->spin1);
2182 }
2183
2184 return hbox;
2185 }
2186
sample_range_code(GtkAction * action)2187 static int sample_range_code (GtkAction *action)
2188 {
2189 const gchar *s = gtk_action_get_name(action);
2190
2191 return (!strcmp(s, "SMPLRAND"))? SMPLRAND : SMPL;
2192 }
2193
build_dummies_combo(GList * dumlist,int thisdum)2194 static GtkWidget *build_dummies_combo (GList *dumlist,
2195 int thisdum)
2196 {
2197 GtkWidget *combo = gtk_combo_box_text_new();
2198 GList *dlist = dumlist;
2199
2200 while (dlist != NULL) {
2201 combo_box_append_text(combo, dlist->data);
2202 dlist = dlist->next;
2203 }
2204
2205 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), thisdum);
2206
2207 return combo;
2208 }
2209
add_dummies_combo(GList * dumlist,int thisdum,const gchar * label,GtkWidget * vbox)2210 static GtkWidget *add_dummies_combo (GList *dumlist,
2211 int thisdum,
2212 const gchar *label,
2213 GtkWidget *vbox)
2214 {
2215 GtkWidget *w, *hbox, *combo;
2216
2217 if (label != NULL) {
2218 w = gtk_label_new(label);
2219 hbox = gtk_hbox_new(TRUE, 5);
2220 gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 5);
2221 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
2222 }
2223
2224 combo = build_dummies_combo(dumlist, thisdum);
2225
2226 hbox = gtk_hbox_new(TRUE, 5);
2227 gtk_box_pack_start(GTK_BOX(hbox), combo, FALSE, FALSE, 5);
2228 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
2229
2230 return combo;
2231 }
2232
toggle_smpl_permanence(GtkToggleButton * b,struct range_setting * rset)2233 static void toggle_smpl_permanence (GtkToggleButton *b,
2234 struct range_setting *rset)
2235 {
2236 if (gtk_toggle_button_get_active(b)) {
2237 rset->opt |= OPT_T;
2238 } else {
2239 rset->opt &= ~OPT_T;
2240 }
2241 }
2242
add_smpl_permanent_check(GtkWidget * vbox,struct range_setting * rset)2243 static void add_smpl_permanent_check (GtkWidget *vbox,
2244 struct range_setting *rset)
2245 {
2246 GtkWidget *hbox, *check;
2247
2248 hbox = gtk_hbox_new(FALSE, 5);
2249 check = gtk_check_button_new_with_label(_("Make this restriction permanent"));
2250 gtk_box_pack_start(GTK_BOX(hbox), check, FALSE, FALSE, 5);
2251 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), FALSE);
2252 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2253
2254 g_signal_connect(G_OBJECT(check), "toggled",
2255 G_CALLBACK(toggle_smpl_permanence), rset);
2256 }
2257
sample_range_dialog(GtkAction * action,gpointer p)2258 void sample_range_dialog (GtkAction *action, gpointer p)
2259 {
2260 struct range_setting *rset = NULL;
2261 GtkWidget *w, *vbox, *hbox;
2262 int u = sample_range_code(action);
2263 int T = sample_size(dataset);
2264
2265 #if 0 /* not ready */
2266 if (dataset_is_panel(dataset) && u == SMPL) {
2267 panel_sample_dialog();
2268 return;
2269 }
2270 #endif
2271
2272 if (u == SMPLRAND && T < 2) {
2273 warnbox(_("The current data range is too small for this option"));
2274 return;
2275 }
2276
2277 rset = rset_new(u, p, NULL, NULL, NULL, _("gretl: set sample"), NULL);
2278 if (rset == NULL) return;
2279
2280 vbox = gtk_dialog_get_content_area(GTK_DIALOG(rset->dlg));
2281
2282 if (u == SMPLRAND) {
2283 gchar *labtxt;
2284 GtkAdjustment *adj;
2285
2286 hbox = gtk_hbox_new(FALSE, 5);
2287
2288 labtxt = g_strdup_printf(_("Number of observations to select (max %d)"),
2289 T - 1);
2290
2291 /* spinner for number of obs */
2292 w = gtk_label_new(labtxt);
2293 gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 5);
2294 adj = (GtkAdjustment *) gtk_adjustment_new(default_randsize(),
2295 1, T - 1,
2296 1, 1, 0);
2297 rset->spin1 = gtk_spin_button_new(adj, 1, 0);
2298 gtk_entry_set_activates_default(GTK_ENTRY(rset->spin1), TRUE);
2299 gtk_box_pack_start(GTK_BOX(hbox), rset->spin1, FALSE, FALSE, 5);
2300
2301 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
2302 } else if (u == SMPL && dataset_is_panel(dataset)) {
2303 hbox = panel_sample_spinbox(rset, 0);
2304 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
2305 rset->opt = OPT_P;
2306 } else {
2307 /* either plain SMPL or CREATE_DATASET */
2308 hbox = obs_spinbox(rset, _("Set sample range"),
2309 _("Start:"), _("End:"),
2310 0, dataset->n - 1, dataset->t1,
2311 0, dataset->n - 1, dataset->t2,
2312 SPIN_LABEL_ABOVE);
2313 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
2314 }
2315
2316 if (u == SMPLRAND) {
2317 if (!complex_subsampled()) {
2318 add_smpl_permanent_check(vbox, rset);
2319 }
2320 } else {
2321 /* label that will show the number of observations */
2322 rset->obslabel = gtk_label_new("");
2323 gtk_box_pack_start(GTK_BOX(vbox), rset->obslabel, FALSE, FALSE, 5);
2324 }
2325
2326 if (u == SMPL || u == CREATE_DATASET) {
2327 g_object_set_data(G_OBJECT(rset->spin1), "rset", rset);
2328 g_object_set_data(G_OBJECT(rset->spin2), "rset", rset);
2329 }
2330
2331 /* buttons */
2332 hbox = gtk_dialog_get_action_area(GTK_DIALOG(rset->dlg));
2333 cancel_delete_button(hbox, rset->dlg);
2334 w = ok_button(hbox);
2335 g_signal_connect(G_OBJECT(w), "clicked",
2336 G_CALLBACK(set_sample_from_dialog), rset);
2337 gtk_widget_grab_default(w);
2338
2339 g_signal_connect(G_OBJECT(rset->dlg), "destroy",
2340 G_CALLBACK(free_rsetting), rset);
2341
2342 gretl_dialog_keep_above(rset->dlg);
2343 gtk_widget_show_all(rset->dlg);
2344 }
2345
2346 static gboolean
range_dummy_callback(GtkWidget * w,struct range_setting * rset)2347 range_dummy_callback (GtkWidget *w, struct range_setting *rset)
2348 {
2349 GtkWidget *name_entry;
2350 char s1[OBSLEN], s2[OBSLEN];
2351 const gchar *vname;
2352 gchar *buf;
2353 int t1, t2;
2354 int err;
2355
2356 name_entry = g_object_get_data(G_OBJECT(rset->dlg), "name-entry");
2357 vname = gtk_entry_get_text(GTK_ENTRY(name_entry));
2358 if (vname == NULL || *vname == '\0') {
2359 gtk_widget_grab_focus(name_entry);
2360 return FALSE;
2361 }
2362
2363 /* FIXME USERIES vs SERIES? */
2364 err = gui_validate_varname(vname, GRETL_TYPE_USERIES, rset->dlg);
2365 if (err) {
2366 return FALSE;
2367 }
2368
2369 strcpy(s1, obs_button_get_string(rset->spin1));
2370 strcpy(s2, obs_button_get_string(rset->spin2));
2371
2372 t1 = obs_button_get_value(rset->spin1);
2373 t2 = obs_button_get_value(rset->spin2);
2374
2375 if (t2 == t1) {
2376 /* a singleton dummy */
2377 if (strchr(s1, '-')) {
2378 buf = g_strdup_printf("series %s = obs==\"%s\"", vname, s1);
2379 } else if (annual_data(dataset)) {
2380 buf = g_strdup_printf("series %s = obs==obsnum(%s)", vname, s1);
2381 } else if (rset->markers) {
2382 buf = g_strdup_printf("series %s = obs==\"%s\"", vname,
2383 dataset->S[t1]);
2384 } else {
2385 buf = g_strdup_printf("series %s = obs==%s", vname, s1);
2386 }
2387 } else {
2388 /* a range of 2 or more observations */
2389 if (strchr(s1, '-') || strchr(s2, '-')) {
2390 buf = g_strdup_printf("series %s = obs>=\"%s\" && obs<=\"%s\"",
2391 vname, s1, s2);
2392 } else if (annual_data(dataset)) {
2393 buf = g_strdup_printf("series %s = obs>=obsnum(%s) && obs<=obsnum(%s)",
2394 vname, s1, s2);
2395 } else {
2396 buf = g_strdup_printf("series %s = obs>=%s && obs<=%s",
2397 vname, s1, s2);
2398 }
2399 }
2400
2401 do_range_dummy_genr(buf);
2402 g_free(buf);
2403
2404 gtk_widget_destroy(rset->dlg);
2405
2406 return TRUE;
2407 }
2408
range_dummy_dialog(GtkAction * action,gpointer p)2409 void range_dummy_dialog (GtkAction *action, gpointer p)
2410 {
2411 struct range_setting *rset = NULL;
2412 GtkWidget *w, *vbox, *hbox;
2413 GtkWidget *label, *entry;
2414
2415 rset = rset_new(0, p, NULL, NULL, NULL, _("gretl: define dummy"), NULL);
2416 if (rset == NULL) return;
2417
2418 if (dataset_is_cross_section(dataset) &&
2419 dataset_has_markers(dataset)) {
2420 rset->markers = 1;
2421 }
2422
2423 vbox = gtk_dialog_get_content_area(GTK_DIALOG(rset->dlg));
2424
2425 hbox = obs_spinbox(rset, _("Set dummy range"),
2426 _("Start:"), _("End:"),
2427 dataset->t1, dataset->t2, dataset->t1,
2428 dataset->t1, dataset->t2, dataset->t2,
2429 SPIN_LABEL_ABOVE);
2430 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
2431
2432 /* label that will show the number of observations */
2433 rset->obslabel = gtk_label_new("");
2434 gtk_box_pack_start(GTK_BOX(vbox), rset->obslabel, FALSE, FALSE, 5);
2435 if (rset->markers) {
2436 gtk_label_set_justify(GTK_LABEL(rset->obslabel),
2437 GTK_JUSTIFY_CENTER);
2438 }
2439
2440 g_object_set_data(G_OBJECT(rset->spin1), "rset", rset);
2441 g_object_set_data(G_OBJECT(rset->spin2), "rset", rset);
2442
2443 /* entry for naming the dummy */
2444 label = gtk_label_new(_("Name of variable:"));
2445 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 5);
2446 entry = gtk_entry_new();
2447 gtk_entry_set_max_length(GTK_ENTRY(entry), VNAMELEN-1);
2448 gtk_entry_set_width_chars(GTK_ENTRY(entry), 20);
2449 gtk_box_pack_start(GTK_BOX(vbox), entry, FALSE, FALSE, 5);
2450 g_object_set_data(G_OBJECT(rset->dlg), "name-entry", entry);
2451 gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
2452
2453 /* buttons */
2454 hbox = gtk_dialog_get_action_area(GTK_DIALOG(rset->dlg));
2455 cancel_delete_button(hbox, rset->dlg);
2456 w = ok_button(hbox);
2457 g_signal_connect(G_OBJECT(w), "clicked",
2458 G_CALLBACK(range_dummy_callback), rset);
2459 gtk_widget_grab_default(w);
2460
2461 g_signal_connect(G_OBJECT(rset->dlg), "destroy",
2462 G_CALLBACK(free_rsetting), rset);
2463
2464 gretl_dialog_keep_above(rset->dlg);
2465 gtk_widget_show_all(rset->dlg);
2466 }
2467
panel_units_finalize(GtkButton * b,struct range_setting * rset)2468 static void panel_units_finalize (GtkButton *b, struct range_setting *rset)
2469 {
2470 *rset->t1 = spinner_get_int(rset->spin1);
2471 *rset->t2 = spinner_get_int(rset->spin2);
2472
2473 gtk_widget_destroy(rset->dlg);
2474 }
2475
2476 #define PNMAX 130
2477
sensitize_panel_options(GtkSpinButton * spin,GSList * group)2478 static void sensitize_panel_options (GtkSpinButton *spin,
2479 GSList *group)
2480 {
2481 struct range_setting *rset =
2482 g_object_get_data(G_OBJECT(spin), "rset");
2483 int ng = g_slist_length(group);
2484 GtkWidget *w, *w0 = NULL;
2485 int i, j, t1, t2, N;
2486 int fixit = 0;
2487
2488 t1 = spinner_get_int(rset->spin1);
2489 t2 = spinner_get_int(rset->spin2);
2490 N = t2 - t1 + 1;
2491
2492 for (i=0; i<ng; i++) {
2493 w = g_slist_nth_data(group, i);
2494 j = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w), "action"));
2495 if (j == 0) {
2496 w0 = w;
2497 } else if (j == 1 || j == 2) {
2498 gtk_widget_set_sensitive(w, N <= PNMAX);
2499 } else if (j == 3) {
2500 gtk_widget_set_sensitive(w, N <= 16);
2501 } else if (j == 4) {
2502 gtk_widget_set_sensitive(w, N <= 6);
2503 } else if (j == 5) {
2504 gtk_widget_set_sensitive(w, N <= 150);
2505 }
2506 if (button_is_active(w) && !gtk_widget_is_sensitive(w)) {
2507 fixit = 1;
2508 }
2509 }
2510
2511 if (fixit && w0 != NULL) {
2512 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w0), TRUE);
2513 }
2514 }
2515
panel_graph_dialog(int * t1,int * t2)2516 int panel_graph_dialog (int *t1, int *t2)
2517 {
2518 const char *opts[] = {
2519 N_("single graph: group means"),
2520 N_("single graph: groups overlaid (N <= %d)"),
2521 N_("single graph: groups in sequence (N <= %d)"),
2522 N_("multiple plots in grid (N <= 16)"),
2523 N_("multiple plots arranged vertically (N <= 6)"),
2524 N_("boxplots by group (N <= 150)"),
2525 N_("single boxplot")
2526 };
2527 struct range_setting *rset = NULL;
2528 GSList *group = NULL;
2529 GtkWidget *w, *vbox, *hbox;
2530 GtkWidget *button;
2531 gchar *title;
2532 int nunits = panel_sample_size(dataset);
2533 int i, deflt, nopts = 7;
2534 int radio_val = 0;
2535 int ret = GRETL_CANCEL;
2536
2537 title = g_strdup_printf("gretl: %s", _("panel plot"));
2538
2539 rset = rset_new(SMPL, NULL, NULL, t1, t2, title, NULL);
2540 g_free(title);
2541
2542 if (rset == NULL) {
2543 return ret;
2544 }
2545
2546 rset->opt = OPT_G; /* sampling for graphing only */
2547
2548 vbox = gtk_dialog_get_content_area(GTK_DIALOG(rset->dlg));
2549 w = gtk_label_new(_("panel plot"));
2550 gtk_box_pack_start(GTK_BOX(vbox), w, FALSE, FALSE, 5);
2551
2552 deflt = (nunits <= PNMAX)? 1 : 0;
2553
2554 for (i=0; i<nopts; i++) {
2555 if (i == 1 || i == 2) {
2556 gchar *label = g_strdup_printf(_(opts[i]), PNMAX);
2557
2558 button = gtk_radio_button_new_with_label(group, label);
2559 g_free(label);
2560 } else {
2561 button = gtk_radio_button_new_with_label(group, _(opts[i]));
2562 }
2563 gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0);
2564 if (i == deflt) {
2565 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (button), TRUE);
2566 radio_val = i;
2567 }
2568 g_signal_connect(G_OBJECT(button), "clicked",
2569 G_CALLBACK(set_radio_opt), &radio_val);
2570 g_object_set_data(G_OBJECT(button), "action",
2571 GINT_TO_POINTER(i));
2572 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
2573 if ((i == 1 || i == 2) && nunits > PNMAX) {
2574 gtk_widget_set_sensitive(button, FALSE);
2575 }
2576 if (i == 3 && nunits > 16) {
2577 gtk_widget_set_sensitive(button, FALSE);
2578 }
2579 if (i == 4 && nunits > 6) {
2580 gtk_widget_set_sensitive(button, FALSE);
2581 }
2582 if (i == 5 && (nunits > 150 || dataset->pd < 4)) {
2583 gtk_widget_set_sensitive(button, FALSE);
2584 }
2585 if (i == 4) {
2586 vbox_add_hsep(vbox);
2587 }
2588 }
2589
2590 vbox_add_hsep(vbox);
2591 hbox = panel_sample_spinbox(rset, 1);
2592 rset->obslabel = gtk_label_new("");
2593 w = gtk_hbox_new(FALSE, 5);
2594 gtk_box_pack_start(GTK_BOX(w), rset->obslabel, FALSE, FALSE, 5);
2595 gtk_box_pack_start(GTK_BOX(vbox), w, FALSE, FALSE, 5);
2596 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
2597 vbox_add_hsep(vbox);
2598
2599 g_object_set_data(G_OBJECT(rset->spin1), "rset", rset);
2600 g_object_set_data(G_OBJECT(rset->spin2), "rset", rset);
2601
2602 g_signal_connect(G_OBJECT(rset->spin1), "value-changed",
2603 G_CALLBACK(sensitize_panel_options),
2604 group);
2605 g_signal_connect(G_OBJECT(rset->spin2), "value-changed",
2606 G_CALLBACK(sensitize_panel_options),
2607 group);
2608
2609 /* buttons */
2610 hbox = gtk_dialog_get_action_area(GTK_DIALOG(rset->dlg));
2611 cancel_delete_button(hbox, rset->dlg);
2612 w = ok_validate_button(hbox, &ret, &radio_val);
2613 g_signal_connect(G_OBJECT(w), "clicked",
2614 G_CALLBACK(panel_units_finalize), rset);
2615 gtk_widget_grab_default(w);
2616
2617 g_signal_connect(G_OBJECT(rset->dlg), "destroy",
2618 G_CALLBACK(free_rsetting), rset);
2619 gretl_dialog_keep_above(rset->dlg);
2620 gtk_widget_show_all(rset->dlg);
2621
2622 return ret;
2623 }
2624
toggle_rset_use_dummy(GtkToggleButton * b,struct range_setting * rset)2625 static void toggle_rset_use_dummy (GtkToggleButton *b,
2626 struct range_setting *rset)
2627 {
2628 gboolean usedum = gtk_toggle_button_get_active(b);
2629
2630 if (usedum) {
2631 rset->opt |= OPT_O;
2632 rset->opt &= ~OPT_R;
2633 set_active_edit_name(NULL);
2634 } else {
2635 rset->opt |= OPT_R;
2636 rset->opt &= ~OPT_O;
2637 set_active_edit_name(rset->entry);
2638 }
2639
2640 gtk_widget_set_sensitive(rset->entry, !usedum);
2641 gtk_widget_set_sensitive(rset->combo, usedum);
2642 }
2643
toggle_replace_restrictions(GtkToggleButton * b,struct range_setting * rset)2644 static void toggle_replace_restrictions (GtkToggleButton *b,
2645 struct range_setting *rset)
2646 {
2647 if (gtk_toggle_button_get_active(b)) {
2648 rset->opt |= OPT_P;
2649 } else {
2650 rset->opt &= ~OPT_P;
2651 }
2652 }
2653
sample_restrict_dialog(GtkAction * action,gpointer p)2654 void sample_restrict_dialog (GtkAction *action, gpointer p)
2655 {
2656 const char *btxt =
2657 N_("Enter boolean condition for selecting cases:");
2658 struct range_setting *rset = NULL;
2659 GList *dumlist = NULL;
2660 GSList *group = NULL;
2661 int thisdum = 0;
2662 GtkWidget *w, *vbox, *hbox;
2663
2664 rset = rset_new(SMPLBOOL, p, NULL, NULL, NULL,
2665 _("gretl: restrict sample"), NULL);
2666
2667 if (rset == NULL) return;
2668
2669 vbox = gtk_dialog_get_content_area(GTK_DIALOG(rset->dlg));
2670
2671 dumlist = get_dummy_list(&thisdum);
2672
2673 if (dumlist != NULL) {
2674 /* radios for restriction/dummy */
2675 w = gtk_radio_button_new_with_label(NULL, _(btxt));
2676 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(w));
2677 } else {
2678 w = gtk_label_new(_(btxt));
2679 }
2680
2681 hbox = gtk_hbox_new(FALSE, 5);
2682 gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 5);
2683 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
2684
2685 /* text entry for restriction */
2686 if (dumlist != NULL) {
2687 hbox = gtk_hbox_new(FALSE, 5);
2688 }
2689 rset->entry = gtk_entry_new();
2690 gtk_entry_set_activates_default(GTK_ENTRY(rset->entry), TRUE);
2691 set_active_edit_name(rset->entry);
2692 g_signal_connect(G_OBJECT(GTK_EDITABLE(rset->entry)), "changed",
2693 G_CALLBACK(raise_and_focus_dialog), rset->dlg);
2694 if (dumlist != NULL) {
2695 gtk_box_pack_start(GTK_BOX(hbox), rset->entry, TRUE, TRUE, 5);
2696 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2697 } else {
2698 gtk_box_pack_start(GTK_BOX(vbox), rset->entry, FALSE, FALSE, 0);
2699 }
2700
2701 if (dumlist != NULL) {
2702 hbox = gtk_hbox_new(FALSE, 5);
2703 w = gtk_radio_button_new_with_label(group, _("Use dummy variable:"));
2704 gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 5);
2705 rset->combo = build_dummies_combo(dumlist, thisdum);
2706 gtk_box_pack_start(GTK_BOX(hbox), rset->combo, FALSE, FALSE, 5);
2707 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2708 g_signal_connect(G_OBJECT(w), "toggled",
2709 G_CALLBACK(toggle_rset_use_dummy), rset);
2710 gtk_widget_set_sensitive(rset->combo, FALSE);
2711 g_list_free(dumlist);
2712 }
2713
2714 if (dataset_is_subsampled(dataset)) {
2715 if (dumlist != NULL) {
2716 vbox_add_hsep(vbox);
2717 }
2718
2719 /* add to current sample restriction */
2720 hbox = gtk_hbox_new(FALSE, 5);
2721 w = gtk_radio_button_new_with_label(NULL, _("add to current restriction"));
2722 gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 5);
2723 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), TRUE);
2724 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2725
2726 /* replace current sample restriction */
2727 hbox = gtk_hbox_new(FALSE, 5);
2728 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(w));
2729 w = gtk_radio_button_new_with_label(group, _("replace current restriction"));
2730 gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 5);
2731 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), FALSE);
2732 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2733
2734 g_signal_connect(G_OBJECT(w), "toggled",
2735 G_CALLBACK(toggle_replace_restrictions), rset);
2736 }
2737
2738 if (!complex_subsampled()) {
2739 /* add checkbox for permanence of restriction */
2740 add_smpl_permanent_check(vbox, rset);
2741 }
2742
2743 /* buttons */
2744 hbox = gtk_dialog_get_action_area(GTK_DIALOG(rset->dlg));
2745 cancel_delete_button(hbox, rset->dlg);
2746 w = ok_button(hbox);
2747 g_signal_connect(G_OBJECT(w), "clicked",
2748 G_CALLBACK(set_sample_from_dialog), rset);
2749 gtk_widget_grab_default(w);
2750 context_help_button(hbox, SMPLBOOL);
2751
2752 g_signal_connect(G_OBJECT(rset->dlg), "destroy",
2753 G_CALLBACK(free_rsetting), rset);
2754 if (rset->entry != NULL) {
2755 gtk_widget_grab_focus(rset->entry);
2756 }
2757
2758 gtk_widget_show_all(rset->dlg);
2759 }
2760
chow_dumv_callback(GtkComboBox * box,int * dumv)2761 static void chow_dumv_callback (GtkComboBox *box, int *dumv)
2762 {
2763 gchar *vname = combo_box_get_active_text(box);
2764
2765 *dumv = series_index(dataset, vname);
2766 g_free(vname);
2767 }
2768
set_chow_subset(GtkToggleButton * b,gretlopt * popt)2769 static void set_chow_subset (GtkToggleButton *b, gretlopt *popt)
2770 {
2771 if (gtk_toggle_button_get_active(b)) {
2772 *popt |= OPT_L;
2773 } else {
2774 *popt &= ~OPT_L;
2775 }
2776 }
2777
configure_chow_dlg(GtkToggleButton * b,struct range_setting * rset)2778 static void configure_chow_dlg (GtkToggleButton *b, struct range_setting *rset)
2779 {
2780 gboolean s = gtk_toggle_button_get_active(b);
2781
2782 gtk_widget_set_sensitive(rset->spin1, !s);
2783
2784 if (s) {
2785 gtk_widget_set_sensitive(rset->combo, TRUE);
2786 chow_dumv_callback(GTK_COMBO_BOX(rset->combo), rset->t2);
2787 } else {
2788 *rset->t2 = 0;
2789 }
2790 }
2791
chow_dialog(int tmin,int tmax,int * t,int * dumv,gretlopt * popt,GtkWidget * parent)2792 int chow_dialog (int tmin, int tmax, int *t, int *dumv,
2793 gretlopt *popt, GtkWidget *parent)
2794 {
2795 const gchar *olabel = N_("Observation at which to split the sample:");
2796 const gchar *dlabel = N_("Name of dummy variable to use:");
2797 GtkWidget *tmp, *vbox, *hbox;
2798 GtkWidget *b1 = NULL, *b2 = NULL;
2799 struct range_setting *rset;
2800 GList *dumlist;
2801 int thisdum = 0;
2802 int ret = GRETL_CANCEL;
2803
2804 dumlist = get_dummy_list(&thisdum);
2805
2806 rset = rset_new(0, NULL, NULL, t, NULL, _("gretl: Chow test"),
2807 parent);
2808
2809 if (rset == NULL) {
2810 return ret;
2811 }
2812
2813 vbox = gtk_dialog_get_content_area(GTK_DIALOG(rset->dlg));
2814
2815 if (dumlist != NULL) {
2816 GSList *grp;
2817
2818 hbox = gtk_hbox_new(FALSE, 5);
2819 b1 = gtk_radio_button_new_with_label(NULL, _(olabel));
2820 gtk_box_pack_start(GTK_BOX(hbox), b1, FALSE, FALSE, 5);
2821 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
2822 grp = gtk_radio_button_get_group(GTK_RADIO_BUTTON(b1));
2823 b2 = gtk_radio_button_new_with_label(grp, _(dlabel));
2824 }
2825
2826 tmp = obs_spinbox(rset, (b1 != NULL)? NULL : _(olabel),
2827 NULL, NULL,
2828 tmin, tmax, *t,
2829 0, 0, 0,
2830 (b1 != NULL)? SPIN_LABEL_NONE : SPIN_LABEL_ABOVE);
2831
2832 gtk_box_pack_start(GTK_BOX(vbox), tmp, TRUE, TRUE, 0);
2833
2834 if (dumlist != NULL) {
2835 hbox = gtk_hbox_new(FALSE, 5);
2836 gtk_box_pack_start(GTK_BOX(hbox), b2, FALSE, FALSE, 5);
2837 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
2838 rset->combo = add_dummies_combo(dumlist, thisdum, NULL, vbox);
2839 gtk_widget_set_sensitive(rset->combo, FALSE);
2840 rset->t2 = dumv;
2841 g_signal_connect(b2, "toggled", G_CALLBACK(configure_chow_dlg), rset);
2842 g_signal_connect(G_OBJECT(rset->combo), "changed",
2843 G_CALLBACK(chow_dumv_callback), dumv);
2844 }
2845
2846 if (popt != NULL) {
2847 GtkWidget *cb;
2848
2849 hbox = gtk_hbox_new(FALSE, 5);
2850 cb = gtk_check_button_new_with_label(_("Test a subset of regressors"));
2851 gtk_box_pack_start(GTK_BOX(hbox), cb, FALSE, FALSE, 5);
2852 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
2853 g_signal_connect(cb, "toggled", G_CALLBACK(set_chow_subset), popt);
2854 }
2855
2856 /* buttons */
2857 hbox = gtk_dialog_get_action_area(GTK_DIALOG(rset->dlg));
2858 cancel_delete_button(hbox, rset->dlg);
2859 tmp = ok_button(hbox);
2860 g_signal_connect(G_OBJECT(tmp), "clicked",
2861 G_CALLBACK(set_ret_yes), &ret);
2862 g_signal_connect(G_OBJECT(tmp), "clicked",
2863 G_CALLBACK(set_obs_from_dialog), rset);
2864 gtk_widget_grab_default(tmp);
2865
2866 g_signal_connect(G_OBJECT(rset->dlg), "destroy",
2867 G_CALLBACK(free_rsetting), rset);
2868
2869 gretl_set_window_modal(rset->dlg);
2870 gtk_widget_show_all(rset->dlg);
2871
2872 return ret;
2873 }
2874
sync_pre_forecast(GtkWidget * w,struct range_setting * rset)2875 static void sync_pre_forecast (GtkWidget *w, struct range_setting *rset)
2876 {
2877 if (rset->p != NULL) {
2878 int t1 = obs_button_get_value(rset->spin1);
2879 GtkAdjustment *adj = GTK_ADJUSTMENT(rset->p);
2880
2881 if (gtk_adjustment_get_upper(adj) != t1) {
2882 gtk_adjustment_set_upper(adj, t1);
2883 if (gtk_adjustment_get_value(adj) > t1) {
2884 gtk_adjustment_set_value(adj, t1);
2885 gtk_adjustment_value_changed(adj);
2886 }
2887 gtk_adjustment_changed(adj);
2888 }
2889 }
2890 }
2891
adjust_fcast_t1(GtkWidget * w,struct range_setting * rset)2892 static void adjust_fcast_t1 (GtkWidget *w, struct range_setting *rset)
2893 {
2894 int t1 = obs_button_get_value(rset->spin1);
2895 int i = widget_get_int(w, "action");
2896
2897 if (rset->pmod == NULL) {
2898 return;
2899 }
2900
2901 if (i == 3) {
2902 int t1min = rset->pmod->t1 + rset->pmod->ncoeff;
2903
2904 if (t1 < t1min) {
2905 gtk_spin_button_set_value(GTK_SPIN_BUTTON(rset->spin1),
2906 (gdouble) t1min);
2907 g_object_set(rset->adj1, "lower", (gdouble) t1min, NULL);
2908 }
2909 } else if (i == 2) {
2910 double txmin;
2911
2912 g_object_get(rset->adj1, "lower", &txmin, NULL);
2913 if (txmin > *rset->t1) {
2914 g_object_set(rset->adj1, "lower", (gdouble) *rset->t1, NULL);
2915 }
2916 }
2917 }
2918
toggle_activate_fitvals(GtkAdjustment * adj,GtkWidget * w)2919 static void toggle_activate_fitvals (GtkAdjustment *adj, GtkWidget *w)
2920 {
2921 gtk_widget_set_sensitive(w, gtk_adjustment_get_value(adj) > 0);
2922 }
2923
toggle_graph_opt(GtkToggleButton * b,gretlopt * gopt)2924 static void toggle_graph_opt (GtkToggleButton *b, gretlopt *gopt)
2925 {
2926 if (button_is_active(b)) {
2927 *gopt |= OPT_E; /* error bars */
2928 } else {
2929 *gopt &= ~OPT_E;
2930 }
2931 }
2932
dialog_add_confidence_selector(GtkWidget * dlg,double * conf,gretlopt * gopt)2933 void dialog_add_confidence_selector (GtkWidget *dlg, double *conf,
2934 gretlopt *gopt)
2935 {
2936 GtkWidget *spin, *lbl, *cb;
2937 GtkWidget *vbox, *hbox;
2938 GtkWidget *hbox1 = NULL, *hbox2 = NULL;
2939 GtkAdjustment *adj;
2940
2941 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dlg));
2942
2943 lbl = gtk_label_new("1 - α =");
2944 adj = (GtkAdjustment *) gtk_adjustment_new(*conf, 0.60, 0.99,
2945 0.01, 0.1, 0);
2946 spin = gtk_spin_button_new(adj, 1, 2);
2947 g_signal_connect(GTK_SPIN_BUTTON(spin), "value-changed",
2948 G_CALLBACK(set_double_from_spinner), conf);
2949
2950 hbox = gtk_hbox_new(FALSE, 5);
2951 gtk_box_pack_start(GTK_BOX(hbox), lbl, FALSE, FALSE, 5);
2952 gtk_box_pack_start(GTK_BOX(hbox), spin, FALSE, FALSE, 5);
2953 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
2954
2955 if (gopt != NULL) {
2956 GSList *group;
2957 GtkWidget *r1, *r2;
2958
2959 r1 = gtk_radio_button_new_with_label(NULL, _("shaded area"));
2960 hbox1 = gtk_hbox_new(FALSE, 5);
2961 gtk_box_pack_start(GTK_BOX(hbox1), r1, FALSE, FALSE, 5);
2962 gtk_box_pack_start(GTK_BOX(vbox), hbox1, FALSE, FALSE, 0);
2963
2964 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(r1));
2965 r2 = gtk_radio_button_new_with_label(group, _("error bars"));
2966 hbox2 = gtk_hbox_new(FALSE, 5);
2967 gtk_box_pack_start(GTK_BOX(hbox2), r2, FALSE, FALSE, 5);
2968 gtk_box_pack_start(GTK_BOX(vbox), hbox2, FALSE, FALSE, 5);
2969 g_signal_connect(G_OBJECT(r2), "toggled",
2970 G_CALLBACK(toggle_graph_opt), gopt);
2971
2972 if (*gopt & OPT_E) {
2973 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(r2), TRUE);
2974 } else {
2975 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(r1), TRUE);
2976 }
2977 }
2978
2979 cb = g_object_get_data(G_OBJECT(dlg), "checkbox");
2980 if (cb != NULL) {
2981 gboolean ok = button_is_active(cb);
2982
2983 gtk_widget_set_sensitive(hbox, ok);
2984 sensitize_conditional_on(hbox, cb);
2985 if (hbox1 != NULL && hbox2 != NULL) {
2986 gtk_widget_set_sensitive(hbox1, ok);
2987 sensitize_conditional_on(hbox1, cb);
2988 gtk_widget_set_sensitive(hbox2, ok);
2989 sensitize_conditional_on(hbox2, cb);
2990 }
2991 }
2992 }
2993
2994 /* at present this is specific to the IRF dialog box */
2995
dialog_add_iters_spinner(GtkWidget * dlg,int * iters)2996 void dialog_add_iters_spinner (GtkWidget *dlg, int *iters)
2997 {
2998 GtkWidget *spin, *lbl, *cb;
2999 GtkWidget *vbox, *hbox;
3000 GtkAdjustment *adj;
3001
3002 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dlg));
3003
3004 lbl = gtk_label_new("bootstrap iterations");
3005 adj = (GtkAdjustment *) gtk_adjustment_new(*iters, 499, 999999,
3006 500, 500, 0);
3007 spin = gtk_spin_button_new(adj, 1, 0);
3008 g_signal_connect(GTK_SPIN_BUTTON(spin), "value-changed",
3009 G_CALLBACK(set_int_from_spinner), iters);
3010
3011 hbox = gtk_hbox_new(FALSE, 5);
3012 gtk_box_pack_start(GTK_BOX(hbox), lbl, FALSE, FALSE, 5);
3013 gtk_box_pack_start(GTK_BOX(hbox), spin, FALSE, FALSE, 5);
3014 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
3015
3016 cb = g_object_get_data(G_OBJECT(dlg), "checkbox");
3017 if (cb != NULL) {
3018 gboolean ok = button_is_active(cb);
3019
3020 gtk_widget_set_sensitive(hbox, ok);
3021 sensitize_conditional_on(hbox, cb);
3022 }
3023 }
3024
fcast_toggle_scope(GtkComboBox * cb,gretlopt * optp)3025 static void fcast_toggle_scope (GtkComboBox *cb, gretlopt *optp)
3026 {
3027 gint i = gtk_combo_box_get_active(cb);
3028
3029 if (i == 1) {
3030 *optp |= OPT_M;
3031 } else {
3032 *optp &= ~OPT_M;
3033 }
3034 }
3035
confidence_scope_selector(GtkWidget * dlg,gretlopt * optp)3036 static void confidence_scope_selector (GtkWidget *dlg, gretlopt *optp)
3037 {
3038 GtkWidget *vbox = gtk_dialog_get_content_area(GTK_DIALOG(dlg));
3039 GtkWidget *hbox = gtk_hbox_new(FALSE, 5);
3040 GtkWidget *lbl, *combo;
3041
3042 lbl = gtk_label_new(_("Show interval for"));
3043 gtk_box_pack_start(GTK_BOX(hbox), lbl, FALSE, FALSE, 5);
3044 combo = gtk_combo_box_text_new();
3045 combo_box_append_text(combo, _("actual Y"));
3046 combo_box_append_text(combo, _("mean Y"));
3047 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0);
3048 g_signal_connect(G_OBJECT(combo), "changed",
3049 G_CALLBACK(fcast_toggle_scope), optp);
3050 gtk_box_pack_start(GTK_BOX(hbox), combo, FALSE, FALSE, 5);
3051 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
3052 }
3053
toggle_opt_I(GtkToggleButton * b,gretlopt * optp)3054 static void toggle_opt_I (GtkToggleButton *b, gretlopt *optp)
3055 {
3056 if (gtk_toggle_button_get_active(b)) {
3057 *optp |= OPT_I;
3058 } else {
3059 *optp &= ~OPT_I;
3060 }
3061 }
3062
forecast_integrate_option(const MODEL * pmod,GtkWidget * vbox,gretlopt * optp)3063 static GtkWidget *forecast_integrate_option (const MODEL *pmod,
3064 GtkWidget *vbox,
3065 gretlopt *optp)
3066 {
3067 GtkWidget *button = NULL;
3068
3069 if (pmod != NULL) {
3070 GtkWidget *w, *tbl, *hbox;
3071 GSList *group;
3072 const char *s;
3073 int dv, dvp;
3074
3075 dv = gretl_model_get_depvar(pmod);
3076 is_standard_diff(dv, dataset, &dvp);
3077
3078 hbox = gtk_hbox_new(FALSE, 5);
3079 tbl = gtk_table_new(2, 2, FALSE);
3080 gtk_table_set_col_spacings(GTK_TABLE(tbl), 5);
3081
3082 w = gtk_label_new(_("Produce forecast for"));
3083 gtk_table_attach_defaults(GTK_TABLE(tbl), w, 0, 1, 0, 1);
3084
3085 s = dataset->varname[dv];
3086 w = gtk_radio_button_new_with_label(NULL, s);
3087 gtk_table_attach_defaults(GTK_TABLE(tbl), w, 1, 2, 0, 1);
3088
3089 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(w));
3090 s = dataset->varname[dvp];
3091 w = gtk_radio_button_new_with_label(group, s);
3092 g_signal_connect(G_OBJECT(w), "toggled",
3093 G_CALLBACK(toggle_opt_I), optp);
3094 gtk_table_attach_defaults(GTK_TABLE(tbl), w, 1, 2, 1, 2);
3095 button = w;
3096
3097 gtk_box_pack_start(GTK_BOX(hbox), tbl, FALSE, FALSE, 5);
3098 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
3099 vbox_add_hsep(vbox);
3100 }
3101
3102 /* FIXME else */
3103
3104 return button;
3105 }
3106
flip_sensitivity(GtkToggleButton * b,GtkWidget * w)3107 static void flip_sensitivity (GtkToggleButton *b, GtkWidget *w)
3108 {
3109 gtk_widget_set_sensitive(w, gtk_toggle_button_get_active(b));
3110 }
3111
snap_to_static(GtkToggleButton * b,GtkWidget * w)3112 static void snap_to_static (GtkToggleButton *b, GtkWidget *w)
3113 {
3114 gboolean s = gtk_toggle_button_get_active(b);
3115
3116 if (!s) {
3117 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), TRUE);
3118 }
3119 }
3120
3121 /* FIXME: Ideally this conditionality should be centralized in
3122 lib/src/forecast.c, and worked out in proper detail. Note
3123 that we don't need to worry here about estimators for which
3124 forecasts are not supported at all; we're just trying to
3125 screen out cases where forecast standard errors are not
3126 available.
3127 */
3128
fcast_errs_ok(MODEL * pmod)3129 static int fcast_errs_ok (MODEL *pmod)
3130 {
3131 if (pmod->ci == LOGIT || pmod->ci == PROBIT) {
3132 return 0;
3133 } else if (pmod->ci == NLS) {
3134 return gretl_model_get_int(pmod, "dynamic") == 0;
3135 } else if (pmod->ci == MIDASREG) {
3136 return gretl_model_get_int(pmod, "umidas") != 0;
3137 } else {
3138 return 1;
3139 }
3140 }
3141
3142 /* Note: the @pmod argument will be NULL if this dialog is
3143 called in relation to a system of equations.
3144 */
3145
forecast_dialog(int t1min,int t1max,int * t1,int t2min,int t2max,int * t2,int * k,int pmin,int pmax,int * p,int flags,gretlopt * optp,double * conf,MODEL * pmod,GtkWidget * parent)3146 int forecast_dialog (int t1min, int t1max, int *t1,
3147 int t2min, int t2max, int *t2,
3148 int *k, int pmin, int pmax, int *p,
3149 int flags, gretlopt *optp,
3150 double *conf, MODEL *pmod,
3151 GtkWidget *parent)
3152 {
3153 const char *pre_txt = N_("Number of pre-forecast observations "
3154 "to graph");
3155 const char *opts[] = {
3156 N_("automatic forecast (dynamic out of sample)"),
3157 N_("dynamic forecast"),
3158 N_("static forecast"),
3159 N_("recursive k-step ahead forecasts: k = "),
3160 };
3161 int nopts = 3;
3162 int deflt = 0;
3163 GtkWidget *tmp;
3164 GtkWidget *vbox, *hbox, *bbox;
3165 GtkWidget *sbutton = NULL;
3166 GtkWidget *ibutton = NULL;
3167 GtkWidget *button = NULL;
3168 struct range_setting *rset;
3169 int i, radio_val = 0;
3170 int ret = GRETL_CANCEL;
3171
3172 rset = rset_new(0, NULL, pmod, t1, t2, _("gretl: forecast"),
3173 parent);
3174 if (rset == NULL) {
3175 return ret;
3176 }
3177
3178 vbox = gtk_dialog_get_content_area(GTK_DIALOG(rset->dlg));
3179
3180 /* forecast range selection */
3181 tmp = obs_spinbox(rset, _("Forecast range:"),
3182 _("Start"), _("End"),
3183 t1min, t1max, *t1,
3184 t2min, t2max, *t2,
3185 SPIN_LABEL_INLINE);
3186 g_signal_connect(G_OBJECT(rset->adj1), "value-changed",
3187 G_CALLBACK(sync_pre_forecast), rset);
3188 gtk_box_pack_start(GTK_BOX(vbox), tmp, TRUE, TRUE, 5);
3189
3190 if (!dataset_is_time_series(dataset)) {
3191 /* only static forecast is available */
3192 deflt = 2;
3193 goto skip_ts_options;
3194 }
3195
3196 tmp = gtk_hseparator_new();
3197 gtk_box_pack_start(GTK_BOX(vbox), tmp, TRUE, TRUE, 0);
3198
3199 if (flags & FC_INTEGRATE_OK) {
3200 ibutton = forecast_integrate_option(pmod, vbox, optp);
3201 } else if (pmod != NULL && pmod->ci == OLS) {
3202 /* allow the "recursive" option */
3203 nopts++;
3204 }
3205 if (!(flags & (FC_AUTO_OK | FC_DYNAMIC_OK))) {
3206 /* default to static forecast */
3207 deflt = 2;
3208 }
3209
3210 /* forecast-type options */
3211 for (i=0; i<nopts; i++) {
3212 gboolean opt_ok = TRUE;
3213 GSList *group = NULL;
3214
3215 if (button != NULL) {
3216 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
3217 }
3218 hbox = gtk_hbox_new(FALSE, 5);
3219 button = gtk_radio_button_new_with_label(group, _(opts[i]));
3220 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5);
3221 if (i == 2) {
3222 /* keep a handle to the "static forecast" button */
3223 sbutton = button;
3224 }
3225
3226 if (i == 3 && k != NULL) {
3227 /* steps ahead for recursive forecast */
3228 GtkWidget *spin = gtk_spin_button_new_with_range(1, 50, 1);
3229
3230 g_signal_connect(G_OBJECT(spin), "value-changed",
3231 G_CALLBACK(set_int_from_spinner), k);
3232 gtk_box_pack_start(GTK_BOX(hbox), spin, FALSE, FALSE, 0);
3233 gtk_widget_set_sensitive(spin, deflt == 3);
3234 sensitize_conditional_on(spin, button);
3235 }
3236
3237 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
3238
3239 if (i == deflt) {
3240 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
3241 radio_val = i;
3242 }
3243 if (i < 2 && !(flags & FC_DYNAMIC_OK)) {
3244 /* disallow dynamic options */
3245 opt_ok = FALSE;
3246 }
3247 if (i == 0 && (flags & FC_AUTO_OK)) {
3248 opt_ok = TRUE;
3249 }
3250 if (i >= 2) {
3251 g_signal_connect(G_OBJECT(button), "clicked",
3252 G_CALLBACK(adjust_fcast_t1),
3253 rset);
3254 }
3255 g_signal_connect(G_OBJECT(button), "clicked",
3256 G_CALLBACK(set_radio_opt), &radio_val);
3257 g_object_set_data(G_OBJECT(button), "action",
3258 GINT_TO_POINTER(i));
3259 if (!opt_ok) {
3260 gtk_widget_set_sensitive(button, FALSE);
3261 if (ibutton != NULL) {
3262 /* integrate option makes dynamic option available */
3263 g_signal_connect(G_OBJECT(ibutton), "toggled",
3264 G_CALLBACK(flip_sensitivity),
3265 button);
3266 }
3267 }
3268 }
3269
3270 if (ibutton != NULL && sbutton != NULL && !(flags & FC_DYNAMIC_OK)) {
3271 g_signal_connect(G_OBJECT(ibutton), "toggled",
3272 G_CALLBACK(snap_to_static),
3273 sbutton);
3274 }
3275
3276 skip_ts_options:
3277
3278 /* pre-forecast obs spinner */
3279 tmp = gtk_hseparator_new();
3280 gtk_box_pack_start(GTK_BOX(vbox), tmp, TRUE, TRUE, 0);
3281 hbox = gtk_hbox_new(FALSE, 5);
3282 tmp = option_spinbox(p, _(pre_txt), pmin, pmax, 0, &rset->p);
3283 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
3284 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
3285 /* get the max pre-forecast obs right */
3286 gtk_adjustment_value_changed(GTK_ADJUSTMENT(rset->adj1));
3287
3288 /* show fitted values, pre-forecast? */
3289 hbox = gtk_hbox_new(FALSE, 5);
3290 tmp = gretl_option_check_button(_("Show fitted values for pre-forecast range"),
3291 optp, OPT_H);
3292 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
3293 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
3294 gtk_widget_set_sensitive(tmp, *p > 0);
3295 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tmp), (*optp & OPT_H));
3296 g_signal_connect(GTK_ADJUSTMENT(rset->p), "value-changed",
3297 G_CALLBACK(toggle_activate_fitvals), tmp);
3298
3299 if (pmod == NULL || fcast_errs_ok(pmod)) {
3300 /* Applicable only if forecast standard errors can be
3301 produced: offer selection of plotting style and
3302 alpha value for confidence intervals
3303 */
3304 static const char *strs[] = {
3305 N_("error bars"),
3306 N_("low and high lines"),
3307 N_("shaded area"),
3308 NULL
3309 };
3310 static gretlopt opts[] = {
3311 OPT_NONE,
3312 OPT_L,
3313 OPT_F
3314 };
3315 static combo_opts ci_opts;
3316 GtkWidget *combo;
3317 int deflt, fixit = 0;
3318
3319 if (*t2 - *t1 < 1) {
3320 /* one observation: can only do error bar */
3321 deflt = 0;
3322 fixit = 1;
3323 *optp &= ~OPT_L;
3324 *optp &= ~OPT_F;
3325 } else {
3326 deflt = (*optp & OPT_L)? 1 : (*optp & OPT_F)? 2 : 0;
3327 }
3328
3329 ci_opts.strs = strs;
3330 ci_opts.vals = opts;
3331 ci_opts.optp = optp;
3332
3333 tmp = gtk_hseparator_new();
3334 gtk_box_pack_start(GTK_BOX(vbox), tmp, TRUE, TRUE, 0);
3335
3336 hbox = gtk_hbox_new(FALSE, 0);
3337 tmp = gtk_label_new(_("Plot confidence interval using"));
3338 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
3339 combo = gretl_opts_combo(&ci_opts, deflt);
3340 gtk_box_pack_start(GTK_BOX(hbox), combo, FALSE, FALSE, 5);
3341 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
3342
3343 if (conf != NULL) {
3344 dialog_add_confidence_selector(rset->dlg, conf, NULL);
3345 if (!fixit && (flags & FC_MEAN_OK)) {
3346 confidence_scope_selector(rset->dlg, optp);
3347 if (gretl_is_simple_OLS(pmod)) {
3348 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 1);
3349 /* why were we doing the following? */
3350 /* fixit = 1; */
3351 }
3352 }
3353 }
3354
3355 if (fixit) {
3356 gtk_widget_set_sensitive(combo, FALSE);
3357 }
3358 }
3359
3360 /* buttons */
3361 bbox = gtk_dialog_get_action_area(GTK_DIALOG(rset->dlg));
3362 cancel_delete_button(bbox, rset->dlg);
3363 tmp = ok_validate_button(bbox, &ret, &radio_val);
3364 g_signal_connect(G_OBJECT(tmp), "clicked",
3365 G_CALLBACK(set_obs_from_dialog), rset);
3366 gtk_widget_grab_default(tmp);
3367 context_help_button(bbox, FCAST);
3368
3369 g_signal_connect(G_OBJECT(rset->dlg), "destroy",
3370 G_CALLBACK(free_rsetting), rset);
3371 gtk_widget_show_all(rset->dlg);
3372
3373 return ret;
3374 }
3375
simple_forecast_dialog(int * t1,int * t2,GtkWidget * parent)3376 int simple_forecast_dialog (int *t1, int *t2, GtkWidget *parent)
3377 {
3378 GtkWidget *vbox, *hbox;
3379 GtkWidget *tmp, *button;
3380 struct range_setting *rset;
3381 int ret = GRETL_CANCEL;
3382
3383 if (dataset->t2 == dataset->n - 1) {
3384 const char *msg = N_("No out-of-sample observations are "
3385 "available.\nShow \"forecast\" information "
3386 "for the estimation sample?");
3387 *t1 = dataset->t1;
3388 *t2 = dataset->t2;
3389 ret = yes_no_dialog(_("gretl: forecast"), _(msg), parent);
3390 return (ret == GRETL_NO)? GRETL_CANCEL : ret;
3391 }
3392
3393 rset = rset_new(0, NULL, NULL, t1, t2, _("gretl: forecast"),
3394 parent);
3395 if (rset == NULL) {
3396 return ret;
3397 }
3398
3399 *t1 = dataset->t2 + 1;
3400 *t2 = dataset->n - 1;
3401
3402 vbox = gtk_dialog_get_content_area(GTK_DIALOG(rset->dlg));
3403
3404 /* forecast range selection */
3405 tmp = obs_spinbox(rset, _("Forecast range:"),
3406 _("Start"), _("End"),
3407 *t1, dataset->n - 2, *t1,
3408 dataset->t2 + 2, *t2, *t2,
3409 SPIN_LABEL_INLINE);
3410 gtk_box_pack_start(GTK_BOX(vbox), tmp, TRUE, TRUE, 5);
3411
3412 /* buttons */
3413 hbox = gtk_dialog_get_action_area(GTK_DIALOG(rset->dlg));
3414 cancel_delete_button(hbox, rset->dlg);
3415 button = ok_validate_button(hbox, &ret, NULL);
3416 g_signal_connect(G_OBJECT(button), "clicked",
3417 G_CALLBACK(set_obs_from_dialog), rset);
3418 gtk_widget_grab_default(button);
3419
3420 g_signal_connect(G_OBJECT(rset->dlg), "destroy",
3421 G_CALLBACK(free_rsetting), rset);
3422 gtk_widget_show_all(rset->dlg);
3423
3424 return ret;
3425 }
3426
set_add_obs(GtkButton * b,int * n_add)3427 static void set_add_obs (GtkButton *b, int *n_add)
3428 {
3429 GtkWidget *spin = g_object_get_data(G_OBJECT(b), "spinner");
3430
3431 *n_add = spinner_get_int(spin);
3432 }
3433
add_obs_dialog(const char * blurb,int addmin,gretlopt opt,GtkWidget * parent)3434 int add_obs_dialog (const char *blurb, int addmin,
3435 gretlopt opt, GtkWidget *parent)
3436 {
3437 int step, panel = dataset_is_panel(dataset);
3438 GtkWidget *dlg, *vbox, *hbox;
3439 GtkWidget *spin, *tmp;
3440 int n_add = -1;
3441
3442 if (panel && !(opt & OPT_T)) {
3443 addmin = dataset->pd;
3444 step = dataset->pd;
3445 } else {
3446 step = 1;
3447 }
3448
3449 dlg = gretl_dialog_new(_("Add observations"), parent,
3450 GRETL_DLG_MODAL | GRETL_DLG_BLOCK);
3451
3452 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dlg));
3453
3454 if (blurb != NULL) {
3455 hbox = gtk_hbox_new(FALSE, 5);
3456 tmp = gtk_label_new(blurb);
3457 gtk_box_pack_start(GTK_BOX(hbox), tmp, TRUE, TRUE, 5);
3458 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
3459 }
3460
3461 hbox = gtk_hbox_new(FALSE, 5);
3462 tmp = gtk_label_new(_("Number of observations to add:"));
3463 gtk_box_pack_start(GTK_BOX(hbox), tmp, TRUE, TRUE, 5);
3464
3465 spin = gtk_spin_button_new_with_range(addmin, 10000, step);
3466 gtk_entry_set_activates_default(GTK_ENTRY(spin), TRUE);
3467 gtk_box_pack_start(GTK_BOX(hbox), spin, TRUE, TRUE, 5);
3468
3469 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
3470
3471 /* buttons */
3472 hbox = gtk_dialog_get_action_area(GTK_DIALOG(dlg));
3473 cancel_delete_button(hbox, dlg);
3474 tmp = ok_button(hbox);
3475 g_object_set_data(G_OBJECT(tmp), "spinner", spin);
3476 g_signal_connect(G_OBJECT(tmp), "clicked",
3477 G_CALLBACK(set_add_obs), &n_add);
3478 g_signal_connect(G_OBJECT(tmp), "clicked",
3479 G_CALLBACK(delete_widget), dlg);
3480 gtk_widget_grab_default(tmp);
3481
3482 gtk_widget_show_all(dlg);
3483
3484 return n_add;
3485 }
3486
set_var_from_combo(GtkWidget * w,GtkWidget * dlg)3487 static void set_var_from_combo (GtkWidget *w, GtkWidget *dlg)
3488 {
3489 GtkWidget *combo = g_object_get_data(G_OBJECT(dlg), "combo");
3490 int *selvar = g_object_get_data(G_OBJECT(dlg), "selvar");
3491 gchar *vname;
3492
3493 vname = combo_box_get_active_text(GTK_COMBO_BOX(combo));
3494 *selvar = series_index(dataset, vname);
3495 g_free(vname);
3496 }
3497
dialog_option_callback(GtkWidget * w,dialog_opts * opts)3498 static void dialog_option_callback (GtkWidget *w, dialog_opts *opts)
3499 {
3500 int i = widget_get_int(w, "i");
3501
3502 if (button_is_active(w)) {
3503 *opts->optp |= opts->vals[i];
3504 } else {
3505 *opts->optp &= ~(opts->vals[i]);
3506 }
3507 }
3508
dialog_add_opts(dialog_opts * opts,GtkWidget * vbox)3509 static void dialog_add_opts (dialog_opts *opts, GtkWidget *vbox)
3510 {
3511 if (opts->type == OPT_TYPE_RADIO) {
3512 GSList *group = NULL;
3513 GtkWidget *b, *v2, *hbox;
3514 int i;
3515
3516 v2 = gtk_vbox_new(FALSE, 0);
3517
3518 for (i=0; i<opts->n; i++) {
3519 b = gtk_radio_button_new_with_label(group, _(opts->strs[i]));
3520 gtk_box_pack_start(GTK_BOX(v2), b, TRUE, TRUE, 0);
3521 g_object_set_data(G_OBJECT(b), "i", GINT_TO_POINTER(i));
3522 g_signal_connect(G_OBJECT(b), "clicked",
3523 G_CALLBACK(dialog_option_callback), opts);
3524 gtk_widget_show(b);
3525 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(b));
3526 }
3527
3528 hbox = gtk_hbox_new(FALSE, 5);
3529 gtk_box_pack_start(GTK_BOX(hbox), v2, TRUE, TRUE, 10);
3530 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
3531 gtk_widget_show(hbox);
3532 gtk_widget_show(v2);
3533 } else if (opts->type == OPT_TYPE_CHECK) {
3534 GtkWidget *b, *hbox;
3535
3536 b = gtk_check_button_new_with_label(_(opts->strs[0]));
3537 hbox = gtk_hbox_new(FALSE, 5);
3538 gtk_box_pack_start(GTK_BOX(hbox), b, TRUE, FALSE, 0);
3539 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
3540 g_signal_connect(G_OBJECT(b), "clicked",
3541 G_CALLBACK(dialog_option_callback), opts);
3542 gtk_widget_show_all(hbox);
3543 } else {
3544 /* handle combo eventually? */
3545 dummy_call();
3546 }
3547 }
3548
select_var_from_list_with_opt(const int * list,const char * query,dialog_opts * opts,int hcode,GtkWidget * parent)3549 int select_var_from_list_with_opt (const int *list,
3550 const char *query,
3551 dialog_opts *opts,
3552 int hcode,
3553 GtkWidget *parent)
3554 {
3555 GtkWidget *tmp, *vbox, *hbox;
3556 GtkWidget *dlg, *combo;
3557 gchar *title;
3558 int i, selvar = -1;
3559
3560 title = g_strdup_printf("gretl: %s", _("select variable"));
3561
3562 dlg = gretl_dialog_new(title, parent, GRETL_DLG_BLOCK);
3563 g_free(title);
3564
3565 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dlg));
3566
3567 tmp = gtk_label_new(query);
3568 hbox = gtk_hbox_new(TRUE, 5);
3569 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
3570 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
3571
3572 combo = gtk_combo_box_text_new();
3573 for (i=1; i<=list[0]; i++) {
3574 combo_box_append_text(combo, dataset->varname[list[i]]);
3575 }
3576
3577 /* select last entry in list */
3578 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), list[0] - 1);
3579
3580 hbox = gtk_hbox_new(TRUE, 5);
3581 gtk_box_pack_start(GTK_BOX(hbox), combo, FALSE, FALSE, 5);
3582 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
3583
3584 g_object_set_data(G_OBJECT(dlg), "combo", combo);
3585 g_object_set_data(G_OBJECT(dlg), "selvar", &selvar);
3586
3587 if (opts != NULL) {
3588 dialog_add_opts(opts, vbox);
3589 }
3590
3591 /* buttons */
3592 hbox = gtk_dialog_get_action_area(GTK_DIALOG(dlg));
3593 cancel_delete_button(hbox, dlg);
3594 tmp = ok_button(hbox);
3595 g_signal_connect(G_OBJECT(tmp), "clicked",
3596 G_CALLBACK(set_var_from_combo), dlg);
3597 g_signal_connect(G_OBJECT(tmp), "clicked",
3598 G_CALLBACK(delete_widget), dlg);
3599 gtk_widget_grab_default(tmp);
3600 if (hcode) {
3601 context_help_button(hbox, hcode);
3602 }
3603
3604 gtk_widget_show_all(dlg);
3605
3606 return selvar;
3607 }
3608
select_var_from_list(const int * list,const char * query,GtkWidget * parent)3609 int select_var_from_list (const int *list, const char *query,
3610 GtkWidget *parent)
3611 {
3612 return select_var_from_list_with_opt(list, query, NULL, 0,
3613 parent);
3614 }
3615
3616 /* material relating to the data compaction dialog */
3617
3618 struct compaction_info {
3619 int *target_pd;
3620 int *repday;
3621 GtkWidget *monday_button;
3622 GtkWidget *sunday_button;
3623 GtkWidget *wkday_opt;
3624 };
3625
abort_compact(GtkWidget * w,gpointer data)3626 static void abort_compact (GtkWidget *w, gpointer data)
3627 {
3628 gint *method = (gint *) data;
3629
3630 *method = COMPACT_NONE;
3631 }
3632
set_compact_type(GtkWidget * w,gpointer data)3633 static void set_compact_type (GtkWidget *w, gpointer data)
3634 {
3635 gint *method = (gint *) data;
3636
3637 if (button_is_active(w)) {
3638 *method = widget_get_int(w, "action");
3639 }
3640 }
3641
set_target_pd(GtkWidget * w,gpointer data)3642 static void set_target_pd (GtkWidget *w, gpointer data)
3643 {
3644 struct compaction_info *cinfo = data;
3645 gboolean wtarg;
3646
3647 if (button_is_active(w)) {
3648 *cinfo->target_pd = widget_get_int(w, "action");
3649 }
3650
3651 wtarg = *cinfo->target_pd == 52;
3652
3653 if (cinfo->monday_button != NULL) {
3654 gtk_widget_set_sensitive(cinfo->monday_button, wtarg);
3655 }
3656 if (cinfo->sunday_button != NULL) {
3657 gtk_widget_set_sensitive(cinfo->sunday_button, wtarg);
3658 }
3659 if (cinfo->wkday_opt != NULL) {
3660 GtkWidget *combo = g_object_get_data(G_OBJECT(cinfo->wkday_opt),
3661 "combo");
3662
3663 gtk_widget_set_sensitive(cinfo->wkday_opt, wtarg);
3664 if (combo != NULL) {
3665 gtk_widget_set_sensitive(cinfo->wkday_opt, wtarg);
3666 }
3667 }
3668 }
3669
set_mon_start(GtkWidget * w,gpointer data)3670 static void set_mon_start (GtkWidget *w, gpointer data)
3671 {
3672 gint *ms = (gint *) data;
3673
3674 if (button_is_active(w)) {
3675 *ms = widget_get_int(w, "action");
3676 }
3677 }
3678
pd_buttons(GtkWidget * dlg,int spd,struct compaction_info * cinfo)3679 static void pd_buttons (GtkWidget *dlg, int spd, struct compaction_info *cinfo)
3680 {
3681 GtkWidget *button;
3682 GtkWidget *vbox;
3683 GSList *group = NULL;
3684 gint f[4] = {0};
3685 const char *fstr[4] = { NULL };
3686
3687 if (spd == 12) {
3688 /* monthly: to quarterly or annual */
3689 f[0] = 4;
3690 f[1] = 1;
3691 fstr[0] = N_("Quarterly");
3692 fstr[1] = N_("Annual");
3693 } else if (spd == 5 || spd == 7) {
3694 /* daily: to weekly or monthly */
3695 f[0] = 52;
3696 f[1] = 12;
3697 fstr[0] = N_("Weekly");
3698 fstr[1] = N_("Monthly");
3699 } else if (spd == 24) {
3700 /* hourly: to daily */
3701 f[0] = 7;
3702 f[1] = 5;
3703 f[2] = 6;
3704 fstr[0] = N_("Daily (7 days)");
3705 fstr[1] = N_("Daily (5 days)");
3706 fstr[2] = N_("Daily (6 days)");
3707 } else {
3708 return;
3709 }
3710 int i;
3711
3712 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dlg));
3713
3714 for (i=0; f[i]>0; i++) {
3715 button = gtk_radio_button_new_with_label(group, _(fstr[i]));
3716 gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0);
3717 if (i == 0) {
3718 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
3719 }
3720 g_signal_connect(G_OBJECT(button), "clicked",
3721 G_CALLBACK(set_target_pd), cinfo);
3722 g_object_set_data(G_OBJECT(button), "action",
3723 GINT_TO_POINTER(f[i]));
3724 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
3725 }
3726 }
3727
monday_buttons(GtkWidget * dlg,int * mon_start,struct compaction_info * cinfo)3728 static void monday_buttons (GtkWidget *dlg, int *mon_start,
3729 struct compaction_info *cinfo)
3730 {
3731 GtkWidget *button;
3732 GtkWidget *vbox;
3733 GSList *group;
3734
3735 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dlg));
3736
3737 button = gtk_radio_button_new_with_label(NULL, _("Week starts on Monday"));
3738 cinfo->monday_button = button;
3739 gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0);
3740 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (button), TRUE);
3741
3742 g_signal_connect(G_OBJECT(button), "clicked",
3743 G_CALLBACK(set_mon_start), mon_start);
3744 g_object_set_data(G_OBJECT(button), "action",
3745 GINT_TO_POINTER(1));
3746
3747 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON (button));
3748 button = gtk_radio_button_new_with_label(group, _("Week starts on Sunday"));
3749 cinfo->sunday_button = button;
3750 gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0);
3751
3752 g_signal_connect(G_OBJECT(button), "clicked",
3753 G_CALLBACK(set_mon_start), mon_start);
3754 g_object_set_data(G_OBJECT(button), "action",
3755 GINT_TO_POINTER(0));
3756 }
3757
3758 static const char *weekdays[] = {
3759 N_("Sunday"),
3760 N_("Monday"),
3761 N_("Tuesday"),
3762 N_("Wednesday"),
3763 N_("Thursday"),
3764 N_("Friday"),
3765 N_("Saturday")
3766 };
3767
select_repday(GtkComboBox * menu,int * repday)3768 gboolean select_repday (GtkComboBox *menu, int *repday)
3769 {
3770 int i = gtk_combo_box_get_active(menu);
3771
3772 *repday = (dataset->pd == 7)? i : i + 1;
3773
3774 return FALSE;
3775 }
3776
3777 enum {
3778 NO_METHODS_SET,
3779 SOME_METHODS_SET,
3780 ALL_METHODS_SET,
3781 SINGLE_SERIES,
3782 ALL_METHODS_SET_SAME
3783 };
3784
method_selected(int code,CompactMethod method)3785 static int method_selected (int code, CompactMethod method)
3786 {
3787 if (code == COMPACT_AVG && method == COMPACT_NONE) {
3788 return 1;
3789 } else {
3790 return code == method;
3791 }
3792 }
3793
spread_compaction_ok(int lf,int hf)3794 static int spread_compaction_ok (int lf, int hf)
3795 {
3796 if (lf == 1 && (hf == 4 || hf == 12)) {
3797 return 1;
3798 } else if (lf == 4 && hf == 12) {
3799 return 1;
3800 } else {
3801 return 0;
3802 }
3803 }
3804
compact_method_buttons(GtkWidget * dlg,CompactMethod * method,int current_pd,int methods_set,struct compaction_info * cinfo)3805 static void compact_method_buttons (GtkWidget *dlg, CompactMethod *method,
3806 int current_pd, int methods_set,
3807 struct compaction_info *cinfo)
3808 {
3809 const char *cstrs[] = {
3810 N_("Compact by averaging"),
3811 N_("Compact by summing"),
3812 N_("Use end-of-period values"),
3813 N_("Use start-of-period values"),
3814 N_("Spread to multiple series (MIDAS)")
3815 };
3816 int ccodes[] = {
3817 COMPACT_AVG,
3818 COMPACT_SUM,
3819 COMPACT_EOP,
3820 COMPACT_SOP,
3821 COMPACT_SPREAD
3822 };
3823 GtkWidget *button;
3824 GtkWidget *vbox;
3825 GSList *group = NULL;
3826 int spread_ok;
3827 int i;
3828
3829 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dlg));
3830
3831 if (methods_set == SOME_METHODS_SET) {
3832 GtkWidget *label;
3833
3834 label = gtk_label_new(_("Default method:"));
3835 gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);
3836 }
3837
3838 spread_ok = spread_compaction_ok(*cinfo->target_pd, current_pd);
3839
3840 for (i=0; i<5; i++) { /* was 4 */
3841 int code = ccodes[i];
3842
3843 button = gtk_radio_button_new_with_label(group, _(cstrs[i]));
3844 gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0);
3845 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (button),
3846 method_selected(code, *method));
3847 g_signal_connect(G_OBJECT(button), "clicked",
3848 G_CALLBACK(set_compact_type), method);
3849 g_object_set_data(G_OBJECT(button), "action",
3850 GINT_TO_POINTER(code));
3851 if (i > 0 && current_pd == 52) {
3852 gtk_widget_set_sensitive(button, FALSE);
3853 }
3854 if (code == COMPACT_SPREAD && !spread_ok) {
3855 gtk_widget_set_sensitive(button, FALSE);
3856 }
3857 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
3858 }
3859
3860 if (dated_daily_data(dataset) && cinfo->repday != NULL) {
3861 GtkWidget *hbox, *daymenu;
3862
3863 hbox = gtk_hbox_new(FALSE, 5);
3864 group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
3865 button = gtk_radio_button_new_with_label(group, _("Use representative day"));
3866 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
3867 g_signal_connect(G_OBJECT(button), "clicked",
3868 G_CALLBACK(set_compact_type), method);
3869 g_object_set_data(G_OBJECT(button), "action",
3870 GINT_TO_POINTER(COMPACT_WDAY));
3871 cinfo->wkday_opt = button;
3872
3873 daymenu = gtk_combo_box_text_new();
3874 for (i=0; i<7; i++) {
3875 if ((i == 0 && dataset->pd != 7) ||
3876 (i == 6 && dataset->pd == 5)) {
3877 continue;
3878 }
3879 combo_box_append_text(daymenu, _(weekdays[i]));
3880 }
3881 gtk_combo_box_set_active(GTK_COMBO_BOX(daymenu), 0);
3882 gtk_box_pack_start(GTK_BOX(hbox), daymenu, FALSE, FALSE, 5);
3883 g_signal_connect(G_OBJECT(daymenu), "changed",
3884 G_CALLBACK(select_repday), cinfo->repday);
3885 if (*method != COMPACT_WDAY) {
3886 gtk_widget_set_sensitive(daymenu, FALSE);
3887 }
3888
3889 sensitize_conditional_on(daymenu, button);
3890 g_object_set_data(G_OBJECT(button), "daymenu", daymenu);
3891
3892 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
3893 }
3894 }
3895
compact_methods_set(CompactMethod * method)3896 static int compact_methods_set (CompactMethod *method)
3897 {
3898 int i, nset = 0;
3899 int m = 0, mbak = -1;
3900 int all_same = 1;
3901 int ret = NO_METHODS_SET;
3902
3903 if (dataset->v == 2) {
3904 m = series_get_compact_method(dataset, 1);
3905 if (m != COMPACT_NONE) {
3906 *method = m;
3907 }
3908 return SINGLE_SERIES;
3909 }
3910
3911 for (i=1; i<dataset->v; i++) {
3912 m = series_get_compact_method(dataset, i);
3913 if (m != COMPACT_NONE) {
3914 nset++;
3915 }
3916 if (all_same && mbak >= 0 && m != mbak) {
3917 all_same = 0;
3918 }
3919 mbak = m;
3920 }
3921
3922 if (nset == dataset->v - 1) {
3923 if (all_same) {
3924 *method = m;
3925 ret = ALL_METHODS_SET_SAME;
3926 } else {
3927 ret = ALL_METHODS_SET;
3928 }
3929 } else if (nset > 0) {
3930 ret = SOME_METHODS_SET;
3931 }
3932
3933 return ret;
3934 }
3935
data_compact_dialog(int spd,int * target_pd,int * mon_start,CompactMethod * method,int * repday,GtkWidget * parent)3936 void data_compact_dialog (int spd, int *target_pd, int *mon_start,
3937 CompactMethod *method, int *repday,
3938 GtkWidget *parent)
3939 {
3940 GtkWidget *dlg, *tmp, *vbox, *hbox;
3941 int show_pd_buttons = 0;
3942 int show_monday_buttons = 0;
3943 int show_method_buttons = 0;
3944 int methods_set = NO_METHODS_SET;
3945 struct compaction_info cinfo;
3946 gchar *labelstr = NULL;
3947
3948 dlg = gretl_dialog_new(_("gretl: compact data"), parent,
3949 GRETL_DLG_BLOCK);
3950
3951 cinfo.target_pd = target_pd;
3952 cinfo.repday = repday;
3953 cinfo.monday_button = NULL;
3954 cinfo.sunday_button = NULL;
3955 cinfo.wkday_opt = NULL;
3956
3957 if (mon_start != NULL) {
3958 *mon_start = 1;
3959 }
3960
3961 if (*target_pd != 0) {
3962 /* importing series from database */
3963 labelstr = g_strdup_printf(_("You are adding a %s series to %s dataset"),
3964 (spd == 4)? _("quarterly") : _("monthly"),
3965 (*target_pd == 4)? _("a quarterly"): _("an annual"));
3966 } else {
3967 /* compacting the whole dataset */
3968 if (spd == 4) {
3969 *target_pd = 1;
3970 labelstr = g_strdup(_("Compact quarterly data to annual"));
3971 } else if (spd == 12) {
3972 /* the source data are monthly */
3973 labelstr = g_strdup(_("Compact monthly data to:"));
3974 *target_pd = 4;
3975 show_pd_buttons = 1;
3976 } else if (spd >= 5 && spd <= 7) {
3977 /* the source data are daily */
3978 if (dated_daily_data(dataset)) {
3979 labelstr = g_strdup(_("Compact daily data to:"));
3980 show_pd_buttons = 1;
3981 } else {
3982 labelstr = g_strdup(_("Compact daily data to weekly"));
3983 }
3984 *target_pd = 52;
3985 if (mon_start != NULL) {
3986 show_monday_buttons = 1;
3987 }
3988 } else if (dated_weekly_data(dataset)) {
3989 labelstr = g_strdup(_("Compact weekly data to monthly"));
3990 *target_pd = 12;
3991 } else if (spd == 24) {
3992 labelstr = g_strdup(_("Compact hourly data to:"));
3993 *target_pd = 7;
3994 show_pd_buttons = 1;
3995 }
3996 methods_set = compact_methods_set(method);
3997 }
3998
3999 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dlg));
4000
4001 tmp = gtk_label_new(labelstr);
4002 g_free(labelstr);
4003 gtk_box_pack_start(GTK_BOX(vbox), tmp, TRUE, TRUE, 0);
4004
4005 show_method_buttons = (methods_set != ALL_METHODS_SET);
4006
4007 /* Monthly data: give choice of going to quarterly or annual;
4008 Dated daily: give choice of going to weekly or monthly;
4009 Hourly data: give choice of days per week.
4010 */
4011 if (show_pd_buttons) {
4012 pd_buttons(dlg, spd, &cinfo);
4013 if (show_monday_buttons || show_method_buttons) {
4014 vbox_add_hsep(vbox);
4015 }
4016 }
4017
4018 /* 7-day daily data: give choice of when the week starts */
4019 if (show_monday_buttons) {
4020 monday_buttons(dlg, mon_start, &cinfo);
4021 if (show_method_buttons) {
4022 vbox_add_hsep(vbox);
4023 }
4024 }
4025
4026 /* per-variable compaction methods not all set already:
4027 give choice of default compaction method
4028 */
4029 if (show_method_buttons) {
4030 compact_method_buttons(dlg, method, spd, methods_set, &cinfo);
4031 }
4032
4033 /* buttons */
4034 hbox = gtk_dialog_get_action_area(GTK_DIALOG(dlg));
4035 tmp = cancel_button(hbox);
4036 g_signal_connect(G_OBJECT(tmp), "clicked",
4037 G_CALLBACK(abort_compact), method);
4038 g_signal_connect (G_OBJECT(tmp), "clicked",
4039 G_CALLBACK(delete_widget),
4040 G_OBJECT(dlg));
4041 tmp = ok_button(hbox);
4042 g_signal_connect(G_OBJECT(tmp), "clicked",
4043 G_CALLBACK(delete_widget),
4044 G_OBJECT(dlg));
4045 gtk_widget_grab_default(tmp);
4046 context_help_button(hbox, COMPACT);
4047
4048 gtk_widget_show_all(dlg);
4049 }
4050
abort_expand(GtkWidget * w,gpointer data)4051 static void abort_expand (GtkWidget *w, gpointer data)
4052 {
4053 int *newpd = (int *) data;
4054
4055 *newpd = -1;
4056 }
4057
set_expansion(GtkComboBox * cb,gpointer data)4058 static void set_expansion (GtkComboBox *cb, gpointer data)
4059 {
4060 int sel = gtk_combo_box_get_active(cb);
4061 int *newpd = (int *) data;
4062
4063 *newpd = sel == 0 ? 4 : 12;
4064 }
4065
4066 /* called from do_expand_data_set() in database.c */
4067
data_expand_dialog(int * newpd,GtkWidget * parent)4068 void data_expand_dialog (int *newpd, GtkWidget *parent)
4069 {
4070 GtkWidget *d, *tmp, *vbox, *hbox;
4071
4072 if (dataset->pd != 1 && dataset->pd != 4) {
4073 /* "can't happen" */
4074 return;
4075 }
4076
4077 d = gretl_dialog_new(_("gretl: expand data"), parent, GRETL_DLG_BLOCK);
4078 vbox = gtk_dialog_get_content_area(GTK_DIALOG(d));
4079
4080 /* top message, possibly with frequency selector */
4081 hbox = gtk_hbox_new(FALSE, 5);
4082 if (dataset->pd == 1) {
4083 GtkWidget *com;
4084
4085 tmp = gtk_label_new(_("Expand annual data to"));
4086 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
4087 com = gtk_combo_box_text_new();
4088 gtk_box_pack_start(GTK_BOX(hbox), com, FALSE, FALSE, 5);
4089 combo_box_append_text(com, _("quarterly"));
4090 combo_box_append_text(com, _("monthly"));
4091 gtk_combo_box_set_active(GTK_COMBO_BOX(com), 0);
4092 g_signal_connect(G_OBJECT(com), "changed",
4093 G_CALLBACK(set_expansion), newpd);
4094 } else if (dataset->pd == 4) {
4095 tmp = gtk_label_new(_("Expand quarterly data to monthly"));
4096 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
4097 }
4098 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
4099
4100 /* message to check the Help */
4101 hbox = gtk_hbox_new(FALSE, 5);
4102 tmp = gtk_label_new(_("Please read the Help before proceeding."));
4103 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
4104 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
4105
4106 /* buttons */
4107 hbox = gtk_dialog_get_action_area(GTK_DIALOG(d));
4108 tmp = cancel_button(hbox);
4109 g_signal_connect(G_OBJECT(tmp), "clicked",
4110 G_CALLBACK(abort_expand), newpd);
4111 g_signal_connect(G_OBJECT(tmp), "clicked",
4112 G_CALLBACK(delete_widget),
4113 G_OBJECT(d));
4114 tmp = ok_button(hbox);
4115 g_signal_connect(G_OBJECT(tmp), "clicked",
4116 G_CALLBACK(delete_widget),
4117 G_OBJECT(d));
4118 gtk_widget_grab_default(tmp);
4119 context_help_button(hbox, EXPAND); /* FIXME! */
4120
4121 gtk_widget_show_all(d);
4122 }
4123
set_radio_opt(GtkWidget * w,int * opt)4124 static void set_radio_opt (GtkWidget *w, int *opt)
4125 {
4126 *opt = widget_get_int(w, "action");
4127 }
4128
4129 /* Returns GRETL_CANCEL on cancel, otherwise the 0-based index of the radio
4130 option selected */
4131
real_radio_dialog(const char * title,const char * label,const char ** opts,int nopts,int deflt,int hcode,int * extravar,const char * extratxt,int spinmin,int spinmax,GtkWidget * parent)4132 int real_radio_dialog (const char *title, const char *label,
4133 const char **opts, int nopts, int deflt, int hcode,
4134 int *extravar, const char *extratxt,
4135 int spinmin, int spinmax, GtkWidget *parent)
4136 {
4137 GtkWidget *dialog;
4138 GtkWidget *vbox, *hbox, *tmp;
4139 GtkWidget *button = NULL;
4140 GSList *group = NULL;
4141 int radio_val = deflt;
4142 int i, ret = GRETL_CANCEL;
4143
4144 if (maybe_raise_dialog()) {
4145 return ret;
4146 }
4147
4148 dialog = gretl_dialog_new(title, parent, GRETL_DLG_BLOCK);
4149 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
4150
4151 if (label != NULL) {
4152 hbox = gtk_hbox_new(FALSE, 5);
4153 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
4154 gtk_widget_show(hbox);
4155 tmp = gtk_label_new(label);
4156 gtk_box_pack_start(GTK_BOX(hbox), tmp, TRUE, TRUE, 5);
4157 }
4158
4159 for (i=0; i<nopts; i++) {
4160 button = gtk_radio_button_new_with_label(group, _(opts[i]));
4161 gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0);
4162 g_object_set_data(G_OBJECT(button), "action", GINT_TO_POINTER(i));
4163 g_signal_connect(G_OBJECT(button), "clicked",
4164 G_CALLBACK(set_radio_opt), &radio_val);
4165 if (i == deflt) {
4166 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (button), TRUE);
4167 }
4168 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
4169 }
4170
4171 if (extravar != NULL) {
4172 if (spinmin == 0 && spinmax == 0) {
4173 /* must be checkbox */
4174 vbox_add_hsep(vbox);
4175 tmp = option_checkbox(extravar, extratxt);
4176 } else {
4177 /* create spinner */
4178 tmp = option_spinbox(extravar, extratxt, spinmin, spinmax, 0, NULL);
4179 }
4180 gtk_box_pack_start(GTK_BOX(vbox), tmp, TRUE, TRUE, 0);
4181 }
4182
4183 /* buttons */
4184 hbox = gtk_dialog_get_action_area(GTK_DIALOG(dialog));
4185 cancel_delete_button(hbox, dialog);
4186 tmp = ok_validate_button(hbox, &ret, &radio_val);
4187 g_signal_connect(G_OBJECT(tmp), "clicked",
4188 G_CALLBACK(delete_widget), dialog);
4189 gtk_widget_grab_default(tmp);
4190 if (hcode) {
4191 context_help_button(hbox, hcode);
4192 } else {
4193 gretl_dialog_keep_above(dialog);
4194 }
4195
4196 gtk_widget_show_all(dialog);
4197
4198 return ret;
4199 }
4200
radio_dialog(const char * title,const char * label,const char ** opts,int nopts,int deflt,int hcode,GtkWidget * parent)4201 int radio_dialog (const char *title, const char *label, const char **opts,
4202 int nopts, int deflt, int hcode, GtkWidget *parent)
4203 {
4204 return real_radio_dialog(title, label, opts, nopts, deflt, hcode,
4205 NULL, NULL, 0, 0, parent);
4206 }
4207
radio_dialog_with_spinner(const char * title,const char ** opts,int nopts,int deflt,int hcode,int * spinvar,const char * spintxt,int spinmin,int spinmax,GtkWidget * parent)4208 int radio_dialog_with_spinner (const char *title, const char **opts,
4209 int nopts, int deflt, int hcode,
4210 int *spinvar, const char *spintxt,
4211 int spinmin, int spinmax,
4212 GtkWidget *parent)
4213 {
4214 return real_radio_dialog(title, NULL, opts, nopts, deflt, hcode,
4215 spinvar, spintxt, spinmin, spinmax,
4216 parent);
4217 }
4218
radio_dialog_with_check(const char * title,const char * label,const char ** opts,int nopts,int deflt,int hcode,int * checkvar,const char * checktxt,GtkWidget * parent)4219 int radio_dialog_with_check (const char *title, const char *label,
4220 const char **opts, int nopts, int deflt,
4221 int hcode, int *checkvar, const char *checktxt,
4222 GtkWidget *parent)
4223 {
4224 return real_radio_dialog(title, label, opts, nopts, deflt, hcode,
4225 checkvar, checktxt, 0, 0, parent);
4226 }
4227
4228 /* selections in relation to kernel density estimation */
4229
bw_set(GtkWidget * w,gpointer p)4230 static void bw_set (GtkWidget *w, gpointer p)
4231 {
4232 double *bw = (double *) p;
4233
4234 *bw = gtk_spin_button_get_value(GTK_SPIN_BUTTON(w));
4235 }
4236
density_dialog(int vnum,double * bw)4237 int density_dialog (int vnum, double *bw)
4238 {
4239 GtkWidget *dialog;
4240 GtkWidget *button;
4241 GtkWidget *vbox;
4242 GtkWidget *hbox;
4243 GtkWidget *tmp;
4244 GSList *group;
4245 int radio_val = 0;
4246 int ret = GRETL_CANCEL;
4247
4248 dialog = gretl_dialog_new(_("density estimation options"), NULL,
4249 GRETL_DLG_BLOCK);
4250
4251 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
4252
4253 /* kernel option buttons */
4254
4255 button = gtk_radio_button_new_with_label(NULL, _("Gaussian kernel"));
4256 gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0);
4257 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
4258
4259 g_signal_connect(G_OBJECT(button), "clicked",
4260 G_CALLBACK(set_radio_opt), &radio_val);
4261 g_object_set_data(G_OBJECT(button), "action",
4262 GINT_TO_POINTER(0));
4263
4264 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
4265 button = gtk_radio_button_new_with_label(group, _("Epanechnikov kernel"));
4266 gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0);
4267 g_signal_connect(G_OBJECT(button), "clicked",
4268 G_CALLBACK(set_radio_opt), &radio_val);
4269 g_object_set_data(G_OBJECT(button), "action",
4270 GINT_TO_POINTER(1));
4271
4272 /* separator */
4273 vbox_add_hsep(vbox);
4274
4275 /* bandwidth adjustment */
4276
4277 hbox = gtk_hbox_new(FALSE, 5);
4278 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
4279
4280 tmp = gtk_label_new(_("bandwidth adjustment factor:"));
4281 gtk_box_pack_start(GTK_BOX(hbox), tmp, TRUE, TRUE, 5);
4282
4283 tmp = gtk_spin_button_new_with_range(0.25, 4.0, .05);
4284 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tmp), 1.0);
4285 gtk_entry_set_activates_default(GTK_ENTRY(tmp), TRUE);
4286 g_signal_connect(G_OBJECT(tmp), "value-changed",
4287 G_CALLBACK(bw_set),
4288 bw);
4289 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
4290
4291 /* buttons */
4292 hbox = gtk_dialog_get_action_area(GTK_DIALOG(dialog));
4293 cancel_delete_button(hbox, dialog);
4294 tmp = ok_validate_button(hbox, &ret, &radio_val);
4295 g_signal_connect(G_OBJECT(tmp), "clicked",
4296 G_CALLBACK(delete_widget),
4297 dialog);
4298 gtk_widget_grab_default(tmp);
4299 context_help_button(hbox, KERNEL_DENSITY);
4300
4301 gtk_widget_show_all(dialog);
4302
4303 return ret;
4304 }
4305
paste_data_dialog(int * append)4306 int paste_data_dialog (int *append)
4307 {
4308 GtkWidget *dialog;
4309 GtkWidget *vbox;
4310 GtkWidget *hbox;
4311 GtkWidget *tmp;
4312 int ret = GRETL_CANCEL;
4313
4314 dialog = gretl_dialog_new(_("paste data from clipboard"), NULL,
4315 GRETL_DLG_BLOCK);
4316
4317 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
4318 hbox = gtk_hbox_new(FALSE, 5);
4319 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
4320
4321 tmp = gtk_label_new(_("Try pasting data from clipboard?"));
4322 gtk_box_pack_start(GTK_BOX(hbox), tmp, TRUE, TRUE, 5);
4323
4324 if (dataset != NULL && dataset->v > 0) {
4325 /* clear/append buttons, if applicable */
4326 GtkWidget *button;
4327 GSList *group;
4328
4329 hbox = gtk_hbox_new(FALSE, 5);
4330 button = gtk_radio_button_new_with_label(NULL, _("Clear current dataset first"));
4331 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 10);
4332 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
4333 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
4334 g_signal_connect(G_OBJECT(button), "clicked",
4335 G_CALLBACK(set_radio_opt), append);
4336 g_object_set_data(G_OBJECT(button), "action",
4337 GINT_TO_POINTER(0));
4338
4339 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
4340 hbox = gtk_hbox_new(FALSE, 5);
4341 button = gtk_radio_button_new_with_label(group, _("Try appending to current dataset"));
4342 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 10);
4343 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
4344 g_signal_connect(G_OBJECT(button), "clicked",
4345 G_CALLBACK(set_radio_opt), append);
4346 g_object_set_data(G_OBJECT(button), "action",
4347 GINT_TO_POINTER(1));
4348 }
4349
4350 /* buttons */
4351 hbox = gtk_dialog_get_action_area(GTK_DIALOG(dialog));
4352 cancel_delete_button(hbox, dialog);
4353 tmp = ok_validate_button(hbox, &ret, NULL);
4354 g_signal_connect(G_OBJECT(tmp), "clicked",
4355 G_CALLBACK(delete_widget),
4356 dialog);
4357 gtk_widget_grab_default(tmp);
4358
4359 gtk_widget_show_all(dialog);
4360
4361 return ret;
4362 }
4363
option_spin_set(GtkWidget * w,int * ivar)4364 static void option_spin_set (GtkWidget *w, int *ivar)
4365 {
4366 *ivar = spinner_get_int(w);
4367 }
4368
dialog_blurb_box(const char * text)4369 static GtkWidget *dialog_blurb_box (const char *text)
4370 {
4371 GtkWidget *hbox;
4372 GtkWidget *label;
4373
4374 hbox = gtk_hbox_new(FALSE, 5);
4375 label = gtk_label_new(text);
4376 gtk_widget_show(label);
4377 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
4378
4379 return hbox;
4380 }
4381
option_spinbox(int * spinvar,const char * spintxt,int spinmin,int spinmax,int ci,gpointer p)4382 static GtkWidget *option_spinbox (int *spinvar, const char *spintxt,
4383 int spinmin, int spinmax,
4384 int ci, gpointer p)
4385 {
4386 GtkWidget *hbox;
4387 GtkWidget *label;
4388 GtkWidget *button;
4389 GtkAdjustment *adj;
4390 int step = (ci == FREQ)? 2 : 1;
4391
4392 hbox = gtk_hbox_new(FALSE, 5);
4393
4394 if (spintxt != NULL) {
4395 label = gtk_label_new(spintxt);
4396 gtk_widget_show(label);
4397 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
4398 }
4399
4400 adj = (GtkAdjustment *) gtk_adjustment_new(*spinvar, spinmin, spinmax,
4401 step, step, 0);
4402 button = gtk_spin_button_new(adj, 1, 0);
4403 gtk_entry_set_activates_default(GTK_ENTRY(button), TRUE);
4404 gtk_widget_show(button);
4405 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5);
4406
4407 g_signal_connect(G_OBJECT(button), "value-changed",
4408 G_CALLBACK(option_spin_set), spinvar);
4409
4410 if (p != NULL) {
4411 GtkAdjustment **pobj = (GtkAdjustment **) p;
4412
4413 *pobj = adj;
4414 }
4415
4416 g_object_set_data(G_OBJECT(hbox), "spin-button", button);
4417
4418 return hbox;
4419 }
4420
option_check_set(GtkWidget * w,int * checkvar)4421 static void option_check_set (GtkWidget *w, int *checkvar)
4422 {
4423 *checkvar = button_is_active(w);
4424 }
4425
option_checkbox(int * checkvar,const char * checktxt)4426 static GtkWidget *option_checkbox (int *checkvar, const char *checktxt)
4427 {
4428 GtkWidget *hbox;
4429 GtkWidget *button;
4430
4431 hbox = gtk_hbox_new(FALSE, 5);
4432 button = gtk_check_button_new_with_label(checktxt);
4433 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5);
4434 gtk_widget_show(button);
4435
4436 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), *checkvar);
4437 g_signal_connect(G_OBJECT(button), "toggled",
4438 G_CALLBACK(option_check_set), checkvar);
4439
4440 return hbox;
4441 }
4442
4443 static GtkWidget *check_extra;
4444 static int check_extra_pos;
4445
4446 /* Mechanism to set an extra selector widget, linked
4447 to the check button at position @i in a checks
4448 dialog. The extra widget is placed following
4449 button @i and its sensitivity is conditional
4450 on button @i being checked.
4451 */
4452
set_checks_dialog_extra(int i,GtkWidget * extra)4453 void set_checks_dialog_extra (int i, GtkWidget *extra)
4454 {
4455 check_extra_pos = i;
4456 check_extra = extra;
4457 }
4458
set_checks_opt(GtkWidget * w,int * active)4459 static void set_checks_opt (GtkWidget *w, int *active)
4460 {
4461 int i = widget_get_int(w, "optnum");
4462
4463 active[i] = button_is_active(w);
4464 }
4465
checks_dialog_add_checks(GtkWidget * dialog,GtkWidget * vbox,const char ** opts,int nchecks,int * active,int check_min,int check_max)4466 static void checks_dialog_add_checks (GtkWidget *dialog, GtkWidget *vbox,
4467 const char **opts, int nchecks,
4468 int *active, int check_min,
4469 int check_max)
4470 {
4471 GtkWidget *prev_button = NULL;
4472 GtkWidget *hbox, *button;
4473 int nc0 = 0, nc1 = 0;
4474 int i;
4475
4476 if (check_min >= 0 && check_max > check_min && check_max <= nchecks) {
4477 nc0 = check_min;
4478 nc1 = check_max;
4479 }
4480
4481 if (nc1 > 0) {
4482 g_object_set_data(G_OBJECT(dialog), "active", active);
4483 widget_set_int(dialog, "check-min", check_min);
4484 widget_set_int(dialog, "check-max", check_max);
4485 }
4486
4487 for (i=0; i<nchecks; i++) {
4488 if (nc1 > 0 && i == nc0) {
4489 /* mark start of the "must check one" area */
4490 vbox_add_hsep(vbox);
4491 }
4492
4493 button = gtk_check_button_new_with_label(_(opts[i]));
4494 hbox = gtk_hbox_new(FALSE, 0);
4495 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5);
4496 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
4497
4498 if (active[i] < 0) {
4499 gtk_widget_set_sensitive(button, FALSE);
4500 } else {
4501 if (active[i] > 0) {
4502 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
4503 }
4504 g_signal_connect(G_OBJECT(button), "clicked",
4505 G_CALLBACK(set_checks_opt), active);
4506 g_object_set_data(G_OBJECT(button), "optnum",
4507 GINT_TO_POINTER(i));
4508 }
4509
4510 if (check_extra != NULL && i == check_extra_pos) {
4511 /* insert the "extra" widget under @button */
4512 gtk_box_pack_start(GTK_BOX(vbox), check_extra, TRUE, TRUE, 0);
4513 gtk_widget_set_sensitive(check_extra, active[i]);
4514 sensitize_conditional_on(check_extra, button);
4515 /* and erase the "extra" specification */
4516 check_extra = NULL;
4517 check_extra_pos = -1;
4518 } else if (prev_button != NULL && strstr(opts[i], "Perron-Qu")) {
4519 gtk_widget_set_sensitive(button, active[0]);
4520 sensitize_conditional_on(button, prev_button);
4521 }
4522
4523 prev_button = button;
4524
4525 if (i+1 == nc1) {
4526 /* mark end of the "must check one" area */
4527 vbox_add_hsep(vbox);
4528 }
4529 }
4530
4531 if (nchecks == 1) {
4532 /* add handle for switching sensitivity */
4533 g_object_set_data(G_OBJECT(dialog), "checkbox", button);
4534 }
4535 }
4536
checks_dialog_add_radios(GtkWidget * vbox,const char ** opts,int nradios,int * rvar)4537 static void checks_dialog_add_radios (GtkWidget *vbox, const char **opts,
4538 int nradios, int *rvar)
4539 {
4540 GtkWidget *hbox, *button = NULL;
4541 GSList *group = NULL;
4542 int i;
4543
4544 for (i=0; i<nradios; i++) {
4545 button = gtk_radio_button_new_with_label(group, _(opts[i]));
4546 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
4547 hbox = gtk_hbox_new(FALSE, 0);
4548 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5);
4549 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
4550 g_object_set_data(G_OBJECT(button), "action",
4551 GINT_TO_POINTER(i));
4552 g_signal_connect(G_OBJECT(button), "clicked",
4553 G_CALLBACK(set_radio_opt), rvar);
4554 if (rvar != NULL && *rvar == i) {
4555 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
4556 }
4557 }
4558 }
4559
checks_dialog_ok(GtkButton * button,GtkWidget * dialog)4560 static void checks_dialog_ok (GtkButton *button, GtkWidget *dialog)
4561 {
4562 int nc0 = widget_get_int(dialog, "check-min");
4563 int nc1 = widget_get_int(dialog, "check-max");
4564 int done = 1;
4565
4566 if (nc1 > 0) {
4567 /* in case at least one option needs to be selected,
4568 check that this is so */
4569 int *active = g_object_get_data(G_OBJECT(dialog), "active");
4570 int i;
4571
4572 done = 0;
4573 for (i=nc0; i<nc1; i++) {
4574 if (active[i]) {
4575 done = 1;
4576 break;
4577 }
4578 }
4579 }
4580
4581 if (done) {
4582 int *retptr = g_object_get_data(G_OBJECT(button), "retptr");
4583
4584 if (retptr != NULL) {
4585 /* signal the all clear */
4586 *retptr = 0;
4587 }
4588 gtk_widget_destroy(dialog);
4589 } else {
4590 /* Right now this is used only for ADF test, in which case
4591 "no model" is a more specific message than "no action"
4592 or "no option". But if we use this for other dialogs this
4593 message may not be appropriate.
4594 */
4595 warnbox(_("No model is specified"));
4596 }
4597 }
4598
4599 /*
4600 Notes:
4601
4602 @nchecks is the number of check buttons.
4603
4604 @check_min and @check_max: if @check_max is > 0, it indicates
4605 that at least one check button with index greater than or
4606 equal to @check_min and less than @check_max must be selected,
4607 or else the the dialog would give a null result.
4608
4609 This is used to flag a warning to the user if OK is pressed with
4610 "nothing selected".
4611 */
4612
4613 GtkWidget *
build_checks_dialog(const char * title,const char * blurb,const char ** opts,int nchecks,int * active,int check_min,int check_max,int nradios,int * rvar,int * spinvar,const char * spintxt,int spinmin,int spinmax,int hcode,GtkWidget * parent,int * ret)4614 build_checks_dialog (const char *title, const char *blurb,
4615 const char **opts,
4616 int nchecks, int *active,
4617 int check_min, int check_max,
4618 int nradios, int *rvar,
4619 int *spinvar, const char *spintxt,
4620 int spinmin, int spinmax,
4621 int hcode, GtkWidget *parent,
4622 int *ret)
4623 {
4624 GtkWidget *dialog, *tmp;
4625 GtkWidget *vbox, *hbox, *okb;
4626 int radios_first = 0;
4627
4628 if (maybe_raise_dialog()) {
4629 return NULL;
4630 }
4631
4632 dialog = gretl_dialog_new(title, parent, GRETL_DLG_BLOCK);
4633 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
4634
4635 if (nradios < 0) {
4636 /* negative value for nradios says put the radios first */
4637 radios_first = 1;
4638 nradios = -nradios;
4639 }
4640
4641 /* create upper label if wanted */
4642 if (blurb != NULL) {
4643 tmp = dialog_blurb_box(blurb);
4644 gtk_box_pack_start(GTK_BOX(vbox), tmp, TRUE, TRUE, 5);
4645 }
4646
4647 /* create spinner if wanted */
4648 if (spinvar != NULL) {
4649 tmp = option_spinbox(spinvar, spintxt, spinmin, spinmax, hcode, NULL);
4650 gtk_box_pack_start(GTK_BOX(vbox), tmp, TRUE, TRUE, 5);
4651 }
4652
4653 /* create leading radio buttons, if any */
4654 if (radios_first) {
4655 checks_dialog_add_radios(vbox, opts, nradios, rvar);
4656 opts += nradios;
4657 }
4658
4659 /* create check buttons, if any */
4660 if (nchecks > 0) {
4661 if (radios_first) {
4662 gtk_box_pack_start(GTK_BOX(vbox), gtk_hseparator_new(), TRUE, TRUE, 5);
4663 }
4664 checks_dialog_add_checks(dialog, vbox, opts, nchecks, active,
4665 check_min, check_max);
4666 opts += nchecks;
4667 }
4668
4669 /* create trailing radio buttons, if any */
4670 if (nradios > 0 && !radios_first) {
4671 if (nchecks > 0) {
4672 gtk_box_pack_start(GTK_BOX(vbox), gtk_hseparator_new(), TRUE, TRUE, 5);
4673 }
4674 checks_dialog_add_radios(vbox, opts, nradios, rvar);
4675 }
4676
4677 /* buttons */
4678 hbox = gtk_dialog_get_action_area(GTK_DIALOG(dialog));
4679 cancel_delete_button(hbox, dialog);
4680 okb = ok_button(hbox);
4681 if (ret != NULL) {
4682 g_object_set_data(G_OBJECT(okb), "retptr", ret);
4683 }
4684 g_signal_connect(G_OBJECT(okb), "clicked",
4685 G_CALLBACK(checks_dialog_ok),
4686 dialog);
4687 gtk_widget_grab_default(okb);
4688 if (hcode && hcode != FREQ) {
4689 context_help_button(hbox, hcode);
4690 }
4691
4692 if (!hcode) {
4693 gretl_dialog_keep_above(dialog);
4694 }
4695
4696 return dialog;
4697 }
4698
4699 /* general purpose dialog offering check-button options and/or
4700 a spinner with numerical values */
4701
checks_dialog(const char * title,const char * blurb,const char ** opts,int nchecks,int * active,int check_min,int check_max,int nradios,int * rvar,int * spinvar,const char * spintxt,int spinmin,int spinmax,int hcode,GtkWidget * parent)4702 int checks_dialog (const char *title, const char *blurb,
4703 const char **opts,
4704 int nchecks, int *active,
4705 int check_min, int check_max,
4706 int nradios, int *rvar,
4707 int *spinvar, const char *spintxt,
4708 int spinmin, int spinmax,
4709 int hcode, GtkWidget *parent)
4710 {
4711 GtkWidget *dlg;
4712 int ret = GRETL_CANCEL;
4713
4714 dlg = build_checks_dialog(title, blurb, opts,
4715 nchecks, active,
4716 check_min, check_max,
4717 nradios, rvar,
4718 spinvar, spintxt,
4719 spinmin, spinmax,
4720 hcode, parent, &ret);
4721
4722 if (dlg != NULL) {
4723 gtk_widget_show_all(dlg);
4724 }
4725
4726 return ret;
4727 }
4728
checks_only_dialog(const char * title,const char * blurb,const char ** opts,int nopts,int * active,int hcode,GtkWidget * parent)4729 int checks_only_dialog (const char *title, const char *blurb,
4730 const char **opts, int nopts, int *active,
4731 int hcode, GtkWidget *parent)
4732 {
4733 GtkWidget *dlg;
4734 int ret = -1;
4735
4736 dlg = build_checks_dialog(title, blurb,
4737 opts, nopts, active, 0, 0,
4738 0, NULL, /* no radios */
4739 NULL, NULL, /* no spinners */
4740 0, 0, hcode, parent, &ret);
4741
4742 if (dlg != NULL) {
4743 gtk_widget_show_all(dlg);
4744 }
4745
4746 return ret;
4747 }
4748
spin_dialog(const char * title,const char * blurb,int * spinvar,const char * spintxt,int spinmin,int spinmax,int hcode,GtkWidget * parent)4749 int spin_dialog (const char *title, const char *blurb,
4750 int *spinvar, const char *spintxt,
4751 int spinmin, int spinmax, int hcode,
4752 GtkWidget *parent)
4753 {
4754 return checks_dialog(title, blurb,
4755 NULL, 0, NULL, 0, 0, /* no checks */
4756 0, NULL, /* no radios */
4757 spinvar, spintxt, spinmin, spinmax,
4758 hcode, parent);
4759 }
4760
pergm_set_bartlett(GtkToggleButton * button,gretlopt * opt)4761 static void pergm_set_bartlett (GtkToggleButton *button, gretlopt *opt)
4762 {
4763 if (gtk_toggle_button_get_active(button)) {
4764 *opt |= OPT_O;
4765 } else {
4766 *opt &= ~OPT_O;
4767 }
4768 }
4769
pergm_set_log_scale(GtkToggleButton * button,gretlopt * opt)4770 static void pergm_set_log_scale (GtkToggleButton *button, gretlopt *opt)
4771 {
4772 if (gtk_toggle_button_get_active(button)) {
4773 *opt |= OPT_L;
4774 } else {
4775 *opt &= ~OPT_L;
4776 }
4777 }
4778
pergm_set_axis(GtkComboBox * combo,gretlopt * opt)4779 static void pergm_set_axis (GtkComboBox *combo, gretlopt *opt)
4780 {
4781 int val = gtk_combo_box_get_active(combo);
4782
4783 if (val == 0) {
4784 *opt &= ~OPT_R;
4785 *opt &= ~OPT_D;
4786 } else if (val == 1) {
4787 *opt &= ~OPT_D;
4788 *opt |= OPT_R;
4789 } else {
4790 *opt &= ~OPT_R;
4791 *opt |= OPT_D;
4792 }
4793 }
4794
pergm_set_bandwidth(GtkSpinButton * spin,int * bw)4795 static void pergm_set_bandwidth (GtkSpinButton *spin, int *bw)
4796 {
4797 *bw = gtk_spin_button_get_value_as_int(spin);
4798 }
4799
pergm_dialog(gretlopt * opt,int * spinval,int spinmin,int spinmax,GtkWidget * parent)4800 int pergm_dialog (gretlopt *opt, int *spinval, int spinmin, int spinmax,
4801 GtkWidget *parent)
4802 {
4803 GtkWidget *dialog, *vbox, *hbox;
4804 GtkWidget *button, *spin, *w;
4805 GSList *group;
4806 int ret = GRETL_CANCEL;
4807
4808 if (maybe_raise_dialog()) {
4809 return ret;
4810 }
4811
4812 dialog = gretl_dialog_new(_("gretl: periodogram"), parent,
4813 GRETL_DLG_BLOCK);
4814 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
4815
4816 /* sample vs Bartlett radios, with Bartlett spinner */
4817
4818 button = gtk_radio_button_new_with_label(NULL, _("Sample periodogram"));
4819 hboxit(button, vbox);
4820
4821 hbox = gtk_hbox_new(FALSE, 5);
4822 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
4823 button = gtk_radio_button_new_with_label(group, _("Bartlett window, bandwidth:"));
4824 g_signal_connect(G_OBJECT(button), "toggled",
4825 G_CALLBACK(pergm_set_bartlett), opt);
4826 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5);
4827
4828 spin = gtk_spin_button_new_with_range(spinmin, spinmax, 1);
4829 gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin), *spinval);
4830 g_signal_connect(G_OBJECT(spin), "value-changed",
4831 G_CALLBACK(pergm_set_bandwidth), spinval);
4832 gtk_widget_set_sensitive(spin, FALSE);
4833 sensitize_conditional_on(spin, button);
4834 gtk_box_pack_start(GTK_BOX(hbox), spin, FALSE, FALSE, 5);
4835 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
4836
4837 /* Log scale checkbox */
4838 button = gtk_check_button_new_with_label(_("log scale"));
4839 g_signal_connect(G_OBJECT(button), "toggled",
4840 G_CALLBACK(pergm_set_log_scale), opt);
4841 hboxit(button, vbox);
4842
4843 /* frequency axis selector */
4844 hbox = gtk_hbox_new(FALSE, 5);
4845 w = gtk_label_new(_("frequency axis scale:"));
4846 gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 5);
4847 w = gtk_combo_box_text_new();
4848 combo_box_append_text(w, _("data-based"));
4849 combo_box_append_text(w, _("radians"));
4850 combo_box_append_text(w, _("degrees"));
4851 gtk_combo_box_set_active(GTK_COMBO_BOX(w), 0);
4852 g_signal_connect(G_OBJECT(w), "changed",
4853 G_CALLBACK(pergm_set_axis), opt);
4854 gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 5);
4855 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
4856
4857 /* buttons */
4858 hbox = gtk_dialog_get_action_area(GTK_DIALOG(dialog));
4859 cancel_delete_button(hbox, dialog);
4860 button = ok_validate_button(hbox, &ret, NULL);
4861 g_signal_connect(G_OBJECT(button), "clicked",
4862 G_CALLBACK(delete_widget),
4863 dialog);
4864 gtk_widget_grab_default(button);
4865 context_help_button(hbox, PERGM);
4866
4867 gtk_widget_show_all(dialog);
4868
4869 return ret;
4870 }
4871
set_response_yes(GtkButton * b,int * ret)4872 static void set_response_yes (GtkButton *b, int *ret)
4873 {
4874 *ret = GRETL_YES;
4875 }
4876
yes_no_help_dialog(const char * msg,int hcode,int deflt)4877 int yes_no_help_dialog (const char *msg, int hcode, int deflt)
4878 {
4879 GtkWidget *dlg;
4880 GtkWidget *vbox, *hbox, *tmp;
4881 GtkWidget *button = NULL;
4882 int ret = GRETL_NO;
4883
4884 dlg = gretl_dialog_new("gretl", NULL, GRETL_DLG_BLOCK);
4885 #if GTK_MAJOR_VERSION < 3
4886 gtk_dialog_set_has_separator(GTK_DIALOG(dlg), FALSE);
4887 #endif
4888
4889 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dlg));
4890
4891 tmp = dialog_blurb_box(msg);
4892 gtk_box_pack_start(GTK_BOX(vbox), tmp, TRUE, TRUE, 5);
4893
4894 hbox = gtk_dialog_get_action_area(GTK_DIALOG(dlg));
4895
4896 /* Yes button */
4897 button = gtk_button_new_from_stock(GTK_STOCK_YES);
4898 g_signal_connect(G_OBJECT(button), "clicked",
4899 G_CALLBACK(set_response_yes), &ret);
4900 g_signal_connect(G_OBJECT(button), "clicked",
4901 G_CALLBACK(delete_widget), dlg);
4902 gtk_widget_set_can_default(button, TRUE);
4903 gtk_container_add(GTK_CONTAINER(hbox), button);
4904 gtk_widget_set_can_default(button, TRUE);
4905 if (deflt == GRETL_YES) {
4906 gtk_widget_grab_default(button);
4907 } else {
4908 gtk_widget_set_can_default(button, FALSE);
4909 }
4910
4911 /* No button */
4912 button = gtk_button_new_from_stock(GTK_STOCK_NO);
4913 gtk_container_add(GTK_CONTAINER(hbox), button);
4914 g_signal_connect(G_OBJECT(button), "clicked",
4915 G_CALLBACK(delete_widget), dlg);
4916 if (deflt == GRETL_NO) {
4917 gtk_widget_set_can_default(button, TRUE);
4918 gtk_widget_grab_default(button);
4919 }
4920
4921 /* Help button */
4922 context_help_button(hbox, hcode);
4923
4924 gtk_widget_show_all(dlg);
4925
4926 return ret;
4927 }
4928
4929 /* mechanism for adjusting properties of frequency plot */
4930
4931 struct freqdist_info {
4932 int *nbins;
4933 double *fmin;
4934 double *fwid;
4935 double xmin;
4936 double xmax;
4937 GtkWidget *spin[3];
4938 };
4939
freq_info_set(GtkWidget * w,struct freqdist_info * f)4940 static gboolean freq_info_set (GtkWidget *w, struct freqdist_info *f)
4941 {
4942 int snum = widget_get_int(w, "snum");
4943 double val = gtk_spin_button_get_value(GTK_SPIN_BUTTON(w));
4944
4945 if (snum == 0) {
4946 /* numbins */
4947 *f->nbins = (int) val;
4948 } else if (snum == 1) {
4949 /* minval */
4950 *f->fmin = val;
4951 } else {
4952 /* bin width */
4953 *f->fwid = val;
4954 }
4955
4956 /* update complementary fields */
4957
4958 if (snum == 0 && gtk_widget_is_sensitive(f->spin[0])) {
4959 *f->fwid = (f->xmax - f->xmin) / (*f->nbins - 1);
4960 gtk_spin_button_set_value(GTK_SPIN_BUTTON(f->spin[2]), *f->fwid);
4961 *f->fmin = f->xmin - 0.5 * (*f->fwid);
4962 if (f->xmin >= 0.0 && *f->fmin < 0) {
4963 *f->fmin = 0.0;
4964 }
4965 gtk_spin_button_set_value(GTK_SPIN_BUTTON(f->spin[1]), *f->fmin);
4966 } else if (snum == 2 && gtk_widget_is_sensitive(f->spin[2])) {
4967 *f->nbins = ceil((f->xmax - *f->fmin) / *f->fwid);
4968 gtk_spin_button_set_value(GTK_SPIN_BUTTON(f->spin[0]), *f->nbins);
4969 }
4970
4971 return FALSE;
4972 }
4973
freq_set_dist(GtkWidget * w,int * dist)4974 static void freq_set_dist (GtkWidget *w, int *dist)
4975 {
4976 int fopt = widget_get_int(w, "fopt");
4977
4978 if (button_is_active(w)) {
4979 if (fopt == 0) *dist = D_NONE;
4980 else if (fopt == 1) *dist = D_NORMAL;
4981 else if (fopt == 2) *dist = D_GAMMA;
4982 }
4983 }
4984
freq_info_control(GtkWidget * w,struct freqdist_info * f)4985 static void freq_info_control (GtkWidget *w, struct freqdist_info *f)
4986 {
4987 int snum = widget_get_int(w, "snum");
4988
4989 if (button_is_active(w)) {
4990 gtk_widget_set_sensitive(f->spin[0], snum == 0);
4991 gtk_widget_set_sensitive(f->spin[1], snum == 1);
4992 gtk_widget_set_sensitive(f->spin[2], snum == 1);
4993 }
4994 }
4995
revise_finfo(GtkWidget * w,struct freqdist_info * f)4996 static void revise_finfo (GtkWidget *w, struct freqdist_info *f)
4997 {
4998 if (!gtk_widget_is_sensitive(f->spin[0])) {
4999 *f->nbins = 0;
5000 } else {
5001 *f->fmin = NADBL;
5002 *f->fwid = NADBL;
5003 }
5004 }
5005
freq_set_plot(GtkToggleButton * b,int * plot)5006 static void freq_set_plot (GtkToggleButton *b, int *plot)
5007 {
5008 *plot = gtk_toggle_button_get_active(b);
5009 }
5010
freq_dialog(const char * title,const char * blurb,int * nbins,int nbmax,double * f0,double * fwid,double xmin,double xmax,int * dist,int * plot)5011 int freq_dialog (const char *title, const char *blurb,
5012 int *nbins, int nbmax, double *f0, double *fwid,
5013 double xmin, double xmax, int *dist, int *plot)
5014 {
5015 struct freqdist_info finfo;
5016 GtkWidget *dialog, *rb;
5017 GtkWidget *vbox, *hbox;
5018 GtkWidget *tmp, *okb;
5019 GSList *group = NULL;
5020 int show_bin_opts;
5021 int show_dist_opts;
5022 int i, ret = GRETL_CANCEL;
5023
5024 if (maybe_raise_dialog()) {
5025 return ret;
5026 }
5027
5028 dialog = gretl_dialog_new(title, NULL, GRETL_DLG_BLOCK);
5029
5030 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
5031
5032 finfo.nbins = nbins;
5033 finfo.fmin = f0;
5034 finfo.fwid = fwid;
5035 finfo.xmax = xmax;
5036 finfo.xmin = xmin;
5037
5038 show_bin_opts = nbins != NULL;
5039 show_dist_opts = nbmax > 15;
5040
5041 /* upper label */
5042 tmp = dialog_blurb_box(blurb);
5043 gtk_box_pack_start(GTK_BOX(vbox), tmp, TRUE, TRUE, 5);
5044
5045 if (show_bin_opts) {
5046 const char *strs[] = {
5047 N_("Number of bins:"),
5048 N_("Minimum value, left bin:"),
5049 N_("Bin width:")
5050 };
5051 GtkWidget *tbl;
5052 GtkAdjustment *adj;
5053 double f0min, f0max, f0step;
5054 double wmin, wmax, wstep;
5055
5056 tbl = gtk_table_new(3, 2, FALSE);
5057 gtk_table_set_col_spacings(GTK_TABLE(tbl), 5);
5058 gtk_table_set_row_spacings(GTK_TABLE(tbl), 5);
5059
5060 *f0 = xmin - 0.5 * (*fwid);
5061 if (xmin >= 0.0 && *f0 < 0) {
5062 *f0 = 0.0;
5063 }
5064
5065 f0min = xmin - 0.2 * (xmax - xmin);
5066 f0max = xmin - 0.01 * (*fwid);
5067 f0step = .001;
5068
5069 wmin = (xmax - xmin) / nbmax;
5070 wmax = (xmax - xmin) / 3.0;
5071 wstep = 0.001;
5072
5073 for (i=0; i<3; i++) {
5074 int dig = (i == 0)? 0 : 3;
5075
5076 if (i < 2) {
5077 rb = gtk_radio_button_new_with_label(group, _(strs[i]));
5078 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(rb));
5079 gtk_table_attach_defaults(GTK_TABLE(tbl), rb, 0, 1, i, i+1);
5080 g_object_set_data(G_OBJECT(rb), "snum", GINT_TO_POINTER(i));
5081 g_signal_connect(G_OBJECT(rb), "clicked",
5082 G_CALLBACK(freq_info_control), &finfo);
5083 } else {
5084 tmp = gtk_label_new(_(strs[i]));
5085 gtk_table_attach_defaults(GTK_TABLE(tbl), tmp, 0, 1, i, i+1);
5086 }
5087
5088 if (i == 0) {
5089 adj = (GtkAdjustment *) gtk_adjustment_new(*nbins, 3, nbmax,
5090 2, 2, 0);
5091 } else if (i == 1) {
5092 adj = (GtkAdjustment *) gtk_adjustment_new(*f0, f0min, f0max,
5093 f0step, 10.0 * f0step, 0);
5094 } else {
5095 adj = (GtkAdjustment *) gtk_adjustment_new(*fwid, wmin, wmax,
5096 wstep, 10.0 * wstep, 0);
5097 }
5098
5099 finfo.spin[i] = gtk_spin_button_new(adj, 1, dig);
5100 gtk_entry_set_activates_default(GTK_ENTRY(finfo.spin[i]), TRUE);
5101 gtk_table_attach_defaults(GTK_TABLE(tbl), finfo.spin[i], 1, 2, i, i+1);
5102 g_object_set_data(G_OBJECT(finfo.spin[i]), "snum",
5103 GINT_TO_POINTER(i));
5104 g_signal_connect(G_OBJECT(finfo.spin[i]), "value-changed",
5105 G_CALLBACK(freq_info_set), &finfo);
5106 if (i > 0) {
5107 gtk_widget_set_sensitive(finfo.spin[i], FALSE);
5108 }
5109 }
5110
5111 gtk_container_add(GTK_CONTAINER(vbox), tbl);
5112
5113 if (show_dist_opts) {
5114 vbox_add_hsep(vbox);
5115 group = NULL;
5116 }
5117 }
5118
5119 if (show_dist_opts) {
5120 /* if var has negative values, don't show Gamma dist option */
5121 const char *dist_opts[] = {
5122 N_("Show data only"),
5123 N_("Test against normal distribution"),
5124 N_("Test against gamma distribution")
5125 };
5126 int imax = (xmin < 0)? 2 : 3;
5127
5128 for (i=0; i<imax; i++) {
5129 hbox = gtk_hbox_new(FALSE, 5);
5130 rb = gtk_radio_button_new_with_label(group, _(dist_opts[i]));
5131 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(rb));
5132 g_object_set_data(G_OBJECT(rb), "fopt", GINT_TO_POINTER(i));
5133 g_signal_connect(G_OBJECT(rb), "clicked",
5134 G_CALLBACK(freq_set_dist), dist);
5135 gtk_container_add(GTK_CONTAINER(hbox), rb);
5136 gtk_container_add(GTK_CONTAINER(vbox), hbox);
5137 }
5138 }
5139
5140 /* show plot option */
5141 vbox_add_hsep(vbox);
5142 hbox = gtk_hbox_new(FALSE, 5);
5143 tmp = gtk_check_button_new_with_label(_("show plot"));
5144 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tmp), *plot);
5145 g_signal_connect(G_OBJECT(tmp), "toggled",
5146 G_CALLBACK(freq_set_plot), plot);
5147 gtk_container_add(GTK_CONTAINER(hbox), tmp);
5148 gtk_container_add(GTK_CONTAINER(vbox), hbox);
5149
5150 /* buttons */
5151 hbox = gtk_dialog_get_action_area(GTK_DIALOG(dialog));
5152 cancel_delete_button(hbox, dialog);
5153 okb = ok_validate_button(hbox, &ret, NULL);
5154 if (nbins != NULL) {
5155 g_signal_connect(G_OBJECT(okb), "clicked",
5156 G_CALLBACK(revise_finfo), &finfo);
5157 }
5158 g_signal_connect(G_OBJECT(okb), "clicked",
5159 G_CALLBACK(delete_widget), dialog);
5160 gtk_widget_grab_default(okb);
5161 if (nbins != NULL) {
5162 context_help_button(hbox, FREQ);
5163 } else {
5164 gretl_dialog_keep_above(dialog);
5165 }
5166
5167 gtk_widget_show_all(dialog);
5168
5169 return ret;
5170 }
5171
5172 struct mtab_info {
5173 GtkWidget *ch0; /* column head default */
5174 GtkWidget *se0; /* stderr (vs t-stat) selector */
5175 GtkWidget *pv0; /* p-values checkbox */
5176 GtkWidget *as0; /* asterisks checkbox */
5177 GtkWidget *fig; /* figures spinner */
5178 GtkWidget *dec; /* decimal places option */
5179 };
5180
mtab_reset_callback(GtkWidget * w,struct mtab_info * mti)5181 static void mtab_reset_callback (GtkWidget *w,
5182 struct mtab_info *mti)
5183 {
5184 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mti->ch0), TRUE);
5185 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mti->se0), TRUE);
5186 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mti->pv0), FALSE);
5187 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mti->as0), TRUE);
5188
5189 gtk_spin_button_set_value(GTK_SPIN_BUTTON(mti->fig), 4);
5190 gtk_combo_box_set_active(GTK_COMBO_BOX(mti->dec), 0);
5191 }
5192
model_table_set_format(GtkComboBox * combo,char * fmt)5193 static void model_table_set_format (GtkComboBox *combo, char *fmt)
5194 {
5195 if (gtk_combo_box_get_active(combo) == 0) {
5196 *fmt = 'g';
5197 } else {
5198 *fmt = 'f';
5199 }
5200 }
5201
model_table_spin_config(GtkComboBox * combo,GtkSpinButton * spin)5202 static void model_table_spin_config (GtkComboBox *combo, GtkSpinButton *spin)
5203 {
5204 if (gtk_combo_box_get_active(combo) == 0) {
5205 gtk_spin_button_set_range(spin, 2, 6);
5206 } else {
5207 gtk_spin_button_set_range(spin, 0, 6);
5208 }
5209 }
5210
model_table_set_figs(GtkSpinButton * spin,int * figs)5211 static void model_table_set_figs (GtkSpinButton *spin, int *figs)
5212 {
5213 *figs = gtk_spin_button_get_value(spin);
5214 }
5215
5216 /* Sets option indices for column headings type and standard errors
5217 versus t-stats, also the number of significant figures to show.
5218 Returns GRETL_CANCEL on cancel, otherwise 0.
5219 */
5220
model_table_dialog(int * colhead_opt,int * se_opt,int * pv_opt,int * ast_opt,int * figs,char * fmt,GtkWidget * parent)5221 int model_table_dialog (int *colhead_opt, int *se_opt, int *pv_opt,
5222 int *ast_opt, int *figs, char *fmt,
5223 GtkWidget *parent)
5224 {
5225 struct mtab_info mti = {0};
5226 const char *col_opts[] = {
5227 "(1), (2), (3), ...",
5228 "I, II, III, ...",
5229 "A, B, C, ...",
5230 N_("Use model names")
5231 };
5232 const char *se_opts[] = {
5233 N_("Show standard errors in parentheses"),
5234 N_("Show t-statistics in parentheses")
5235 };
5236 GtkWidget *dialog;
5237 GtkWidget *vbox, *hbox, *tmp;
5238 GtkWidget *spin, *button = NULL;
5239 GSList *group = NULL;
5240 int i, ret = GRETL_CANCEL;
5241
5242 if (maybe_raise_dialog()) {
5243 return ret;
5244 }
5245
5246 dialog = gretl_dialog_new("gretl", parent, GRETL_DLG_BLOCK);
5247
5248 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
5249
5250 hbox = gtk_hbox_new(FALSE, 5);
5251 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
5252 tmp = gtk_label_new(_("model table options"));
5253 gtk_box_pack_start(GTK_BOX(hbox), tmp, TRUE, TRUE, 5);
5254
5255 vbox_add_hsep(vbox);
5256
5257 hbox = gtk_hbox_new(FALSE, 5);
5258 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
5259 tmp = gtk_label_new(_("column headings"));
5260 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
5261
5262 /* column heading options */
5263 for (i=0; i<4; i++) {
5264 if (i == 3) {
5265 button = gtk_radio_button_new_with_label(group, _(col_opts[i]));
5266 } else {
5267 button = gtk_radio_button_new_with_label(group, col_opts[i]);
5268 }
5269 gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0);
5270 if (i == 0) {
5271 mti.ch0 = button;
5272 }
5273 if (i == *colhead_opt) {
5274 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
5275 }
5276 g_signal_connect(G_OBJECT(button), "clicked",
5277 G_CALLBACK(set_radio_opt), colhead_opt);
5278 g_object_set_data(G_OBJECT(button), "action",
5279 GINT_TO_POINTER(i));
5280 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
5281 }
5282
5283 vbox_add_hsep(vbox);
5284
5285 /* standard error / t-ratios option */
5286 group = NULL;
5287 for (i=0; i<2; i++) {
5288 button = gtk_radio_button_new_with_label(group, _(se_opts[i]));
5289 gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0);
5290 if (i == *se_opt) {
5291 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
5292 }
5293 if (i == 0) {
5294 mti.se0 = button;
5295 }
5296 g_signal_connect(G_OBJECT(button), "clicked",
5297 G_CALLBACK(set_radio_opt), se_opt);
5298 g_object_set_data(G_OBJECT(button), "action",
5299 GINT_TO_POINTER(i));
5300 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
5301 }
5302
5303 vbox_add_hsep(vbox);
5304
5305 /* show p-values box */
5306 mti.pv0 = button =
5307 gtk_check_button_new_with_label(_("Show p-values"));
5308 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), *pv_opt);
5309 g_signal_connect(G_OBJECT(button), "clicked",
5310 G_CALLBACK(option_check_set), pv_opt);
5311 gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0);
5312
5313 /* show asterisks box */
5314 mti.as0 =button =
5315 gtk_check_button_new_with_label(_("Show significance asterisks"));
5316 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), *ast_opt);
5317 g_signal_connect(G_OBJECT(button), "clicked",
5318 G_CALLBACK(option_check_set), ast_opt);
5319 gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0);
5320 vbox_add_hsep(vbox);
5321
5322 /* spinner for number of digits */
5323 hbox = gtk_hbox_new(FALSE, 5);
5324 tmp = gtk_label_new(_("Show"));
5325 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
5326 spin = gtk_spin_button_new_with_range((*fmt == 'g')? 2 : 0, 6, 1);
5327 gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin), *figs);
5328 g_signal_connect(G_OBJECT(GTK_SPIN_BUTTON(spin)), "value-changed",
5329 G_CALLBACK(model_table_set_figs), figs);
5330 gtk_box_pack_start(GTK_BOX(hbox), spin, FALSE, FALSE, 0);
5331 mti.fig = spin;
5332
5333 /* selector for significant figs vs decimal places */
5334 mti.dec = tmp = gtk_combo_box_text_new();
5335 combo_box_append_text(tmp, _("significant figures"));
5336 combo_box_append_text(tmp, _("decimal places"));
5337 if (*fmt == 'g') {
5338 gtk_combo_box_set_active(GTK_COMBO_BOX(tmp), 0);
5339 } else {
5340 gtk_combo_box_set_active(GTK_COMBO_BOX(tmp), 1);
5341 }
5342 g_signal_connect(G_OBJECT(GTK_COMBO_BOX(tmp)), "changed",
5343 G_CALLBACK(model_table_set_format), fmt);
5344 g_signal_connect(G_OBJECT(GTK_COMBO_BOX(tmp)), "changed",
5345 G_CALLBACK(model_table_spin_config), spin);
5346 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
5347 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
5348
5349 /* buttons */
5350 hbox = gtk_dialog_get_action_area(GTK_DIALOG(dialog));
5351 button = gtk_button_new_with_label(_("Reset"));
5352 gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
5353 g_signal_connect(G_OBJECT(button), "clicked",
5354 G_CALLBACK(mtab_reset_callback), &mti);
5355 cancel_delete_button(hbox, dialog);
5356 tmp = ok_validate_button(hbox, &ret, NULL);
5357 g_signal_connect(G_OBJECT(tmp), "clicked",
5358 G_CALLBACK(delete_widget), dialog);
5359 gtk_widget_grab_default(tmp);
5360
5361 gretl_dialog_keep_above(dialog);
5362 gtk_widget_show_all(dialog);
5363
5364 return ret;
5365 }
5366
msgbox(const char * msg,int msgtype,GtkWidget * parent)5367 void msgbox (const char *msg, int msgtype, GtkWidget *parent)
5368 {
5369 const gchar *titles[] = {
5370 N_("gretl: error"),
5371 N_("gretl: warning"),
5372 N_("gretl: information")
5373 };
5374 const gchar *title;
5375 gchar *trmsg = NULL;
5376 GtkWidget *dialog;
5377 GtkWindow *pwin;
5378
5379 if (msg == NULL) {
5380 return;
5381 }
5382
5383 if (!g_utf8_validate(msg, -1, NULL)) {
5384 /* it's possible we have an OS string from strerror() that is
5385 not UTF-8 encoded */
5386 gsize bytes;
5387
5388 trmsg = g_locale_to_utf8(msg, -1, NULL, &bytes, NULL);
5389 }
5390
5391 if (parent == NULL) {
5392 parent = get_focus_window();
5393 if (parent == NULL && mdata != NULL) {
5394 parent = mdata->main;
5395 }
5396 #if 0
5397 fprintf(stderr, "Revised msgbox parent = %p\n", (void *) parent);
5398 #endif
5399 }
5400 pwin = parent != NULL ? GTK_WINDOW(parent) : NULL;
5401
5402 dialog = gtk_message_dialog_new(pwin,
5403 0, /* or GTK_DIALOG_DESTROY_WITH_PARENT? */
5404 msgtype,
5405 GTK_BUTTONS_CLOSE,
5406 "%s",
5407 (trmsg != NULL)? trmsg : msg);
5408
5409 title = (msgtype == GTK_MESSAGE_ERROR)? titles[0] :
5410 (msgtype == GTK_MESSAGE_WARNING)? titles[1] : titles[2];
5411
5412 gtk_window_set_title(GTK_WINDOW(dialog), _(title));
5413 gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE);
5414
5415 gtk_dialog_run(GTK_DIALOG(dialog));
5416
5417 gtk_widget_destroy(dialog);
5418
5419 if (trmsg != NULL) {
5420 g_free(trmsg);
5421 }
5422 }
5423
errbox(const char * err)5424 void errbox (const char *err)
5425 {
5426 char msg[MAXLEN];
5427
5428 *msg = '\0';
5429
5430 if (strlen(err) >= MAXLEN) {
5431 strncat(msg, err, MAXLEN - 4);
5432 strcat(msg, "...");
5433 } else {
5434 strcpy(msg, err);
5435 }
5436
5437 msgbox(msg, GTK_MESSAGE_ERROR, NULL);
5438 }
5439
errbox_printf(const char * template,...)5440 void errbox_printf (const char *template, ...)
5441 {
5442 char msg[MAXLEN];
5443 va_list args;
5444
5445 if (template == NULL) {
5446 msgbox("Error", 1, NULL);
5447 return;
5448 }
5449
5450 va_start(args, template);
5451 vsnprintf(msg, MAXLEN, template, args);
5452 va_end(args);
5453
5454 msgbox(msg, GTK_MESSAGE_ERROR, NULL);
5455 }
5456
infobox(const char * info)5457 void infobox (const char *info)
5458 {
5459 char msg[MAXLEN];
5460
5461 *msg = '\0';
5462
5463 if (strlen(info) >= MAXLEN) {
5464 strncat(msg, info, MAXLEN - 4);
5465 strcat(msg, "...");
5466 } else {
5467 strcpy(msg, info);
5468 }
5469
5470 msgbox(msg, GTK_MESSAGE_INFO, NULL);
5471 }
5472
infobox_printf(const char * template,...)5473 void infobox_printf (const char *template, ...)
5474 {
5475 char msg[MAXLEN];
5476 va_list args;
5477
5478 va_start(args, template);
5479 vsnprintf(msg, MAXLEN, template, args);
5480 va_end(args);
5481
5482 msgbox(msg, GTK_MESSAGE_INFO, NULL);
5483 }
5484
warnbox(const char * warn)5485 void warnbox (const char *warn)
5486 {
5487 char msg[MAXLEN];
5488
5489 *msg = '\0';
5490
5491 if (strlen(warn) >= MAXLEN) {
5492 strncat(msg, warn, MAXLEN - 4);
5493 strcat(msg, "...");
5494 } else {
5495 strcpy(msg, warn);
5496 }
5497
5498 msgbox(msg, GTK_MESSAGE_WARNING, NULL);
5499 }
5500
warnbox_printf(const char * template,...)5501 void warnbox_printf (const char *template, ...)
5502 {
5503 char msg[MAXLEN];
5504 va_list args;
5505
5506 va_start(args, template);
5507 vsnprintf(msg, MAXLEN, template, args);
5508 va_end(args);
5509
5510 msgbox(msg, GTK_MESSAGE_WARNING, NULL);
5511 }
5512
maybe_warn(void)5513 void maybe_warn (void)
5514 {
5515 if (check_gretl_warning()) {
5516 msgbox(gretl_warnmsg_get(), GTK_MESSAGE_WARNING, NULL);
5517 }
5518 }
5519
file_read_errbox(const char * fname)5520 void file_read_errbox (const char *fname)
5521 {
5522 const char *msg = gretl_errmsg_get();
5523
5524 if (*msg != '\0') {
5525 errbox(msg);
5526 } else {
5527 errbox_printf(_("Couldn't open %s"), fname);
5528 }
5529 }
5530
file_write_errbox(const char * fname)5531 void file_write_errbox (const char *fname)
5532 {
5533 const char *msg = gretl_errmsg_get();
5534
5535 if (*msg != '\0') {
5536 errbox(msg);
5537 } else {
5538 errbox_printf(_("Couldn't write to %s"), fname);
5539 }
5540 }
5541
5542 static void
name_entry_finalize(GtkWidget * w,GtkWidget * dlg)5543 name_entry_finalize (GtkWidget *w, GtkWidget *dlg)
5544 {
5545 GtkWidget *entry = g_object_get_data(G_OBJECT(dlg), "entry");
5546 char *name = g_object_get_data(G_OBJECT(dlg), "name");
5547 GretlType type = widget_get_int(dlg, "type");
5548 const gchar *txt = gtk_entry_get_text(GTK_ENTRY(entry));
5549
5550 if (gui_validate_varname(txt, type, dlg) == 0) {
5551 strcpy(name, txt);
5552 gtk_widget_destroy(dlg);
5553 }
5554 }
5555
activate_show(GtkToggleButton * b,int * show)5556 static void activate_show (GtkToggleButton *b, int *show)
5557 {
5558 *show = button_is_active(b);
5559 }
5560
5561 /* don't do this for types lacking a GUI representation */
5562 #define do_show_check(t) (t != GRETL_TYPE_STRING && t != GRETL_TYPE_ARRAY)
5563
object_name_entry_dialog(char * name,GretlType type,const char * labeltxt,int * show,GtkWidget * parent)5564 int object_name_entry_dialog (char *name, GretlType type,
5565 const char *labeltxt, int *show,
5566 GtkWidget *parent)
5567 {
5568 GtkWidget *dlg, *tmp, *vbox, *hbox;
5569 GtkWidget *entry;
5570 int ret = GRETL_CANCEL;
5571
5572 dlg = gretl_dialog_new(_("gretl: name variable"), parent,
5573 GRETL_DLG_BLOCK);
5574
5575 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dlg));
5576
5577 if (labeltxt != NULL) {
5578 hbox = gtk_hbox_new(FALSE, 5);
5579 tmp = gtk_label_new(_(labeltxt));
5580 gtk_label_set_justify(GTK_LABEL(tmp), GTK_JUSTIFY_CENTER);
5581 gtk_box_pack_start(GTK_BOX(hbox), tmp, TRUE, FALSE, 0);
5582 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
5583 }
5584
5585 hbox = gtk_hbox_new(FALSE, 5);
5586 entry = gtk_entry_new();
5587 gtk_entry_set_width_chars(GTK_ENTRY(entry), VNAMELEN - 1);
5588 gtk_entry_set_max_length(GTK_ENTRY(entry), VNAMELEN - 1);
5589 gtk_entry_set_text(GTK_ENTRY(entry), name);
5590 gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
5591 gtk_editable_select_region(GTK_EDITABLE(entry), 0, -1);
5592 gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
5593 gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, FALSE, 5);
5594 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
5595
5596 if (show != NULL && do_show_check(type)) {
5597 const char *label = (type == GRETL_TYPE_DOUBLE)?
5598 N_("show scalars window") :
5599 N_("show icons window");
5600
5601 hbox = gtk_hbox_new(FALSE, 5);
5602 tmp = gtk_check_button_new_with_label(_(label));
5603 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
5604 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
5605 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tmp), *show);
5606 g_signal_connect(G_OBJECT(tmp), "toggled",
5607 G_CALLBACK(activate_show), show);
5608 }
5609
5610 /* links */
5611 g_object_set_data(G_OBJECT(dlg), "entry", entry);
5612 g_object_set_data(G_OBJECT(dlg), "name", name);
5613 g_object_set_data(G_OBJECT(dlg), "type", GINT_TO_POINTER(type));
5614
5615 /* buttons */
5616 hbox = gtk_dialog_get_action_area(GTK_DIALOG(dlg));
5617 tmp = cancel_delete_button(hbox, dlg);
5618 tmp = ok_validate_button(hbox, &ret, NULL);
5619 g_signal_connect(G_OBJECT(tmp), "clicked",
5620 G_CALLBACK(name_entry_finalize), dlg);
5621 gtk_widget_grab_default(tmp);
5622
5623 gretl_dialog_keep_above(dlg);
5624 gtk_widget_show_all(dlg);
5625
5626 return ret;
5627 }
5628
5629 /* apparatus for setting custom format for TeX tabular model output */
5630
5631 struct rbin {
5632 GtkWidget *b[2];
5633 };
5634
5635 struct tex_formatter {
5636 GtkWidget *custom;
5637 GtkWidget *show[3];
5638 GtkAdjustment *adj[4];
5639 GtkWidget *spin[4];
5640 struct rbin radio[4];
5641 };
5642
activate_row(GtkWidget * w,struct tex_formatter * tf)5643 static void activate_row (GtkWidget *w, struct tex_formatter *tf)
5644 {
5645 int i = widget_get_int(w, "row");
5646 int s = button_is_active(w);
5647
5648 if (tf->spin[i] != NULL) {
5649 gtk_widget_set_sensitive(tf->spin[i], s);
5650 gtk_widget_set_sensitive(tf->radio[i].b[0], s);
5651 gtk_widget_set_sensitive(tf->radio[i].b[1], s);
5652 }
5653 }
5654
toggle_tex_custom(GtkWidget * w,struct tex_formatter * tf)5655 static void toggle_tex_custom (GtkWidget *w, struct tex_formatter *tf)
5656 {
5657 int s = button_is_active(w);
5658 int i;
5659
5660 if (tf->spin[0] != NULL) {
5661 for (i=0; i<4; i++) {
5662 if (i < 3) {
5663 gtk_widget_set_sensitive(tf->show[i], s);
5664 }
5665 gtk_widget_set_sensitive(tf->spin[i], s);
5666 gtk_widget_set_sensitive(tf->radio[i].b[0], s);
5667 gtk_widget_set_sensitive(tf->radio[i].b[1], s);
5668 }
5669 }
5670 }
5671
record_tex_format(GtkWidget * w,struct tex_formatter * tf)5672 static gboolean record_tex_format (GtkWidget *w, struct tex_formatter *tf)
5673 {
5674 if (button_is_active(tf->custom)) {
5675 char c, bit[8], fmt[32];
5676 int i, p;
5677
5678 *fmt = '\0';
5679
5680 for (i=0; i<4; i++) {
5681 if (i == 0 || button_is_active(tf->show[i-1])) {
5682 p = (int) gtk_spin_button_get_value(GTK_SPIN_BUTTON(tf->spin[i]));
5683 if (button_is_active(tf->radio[i].b[1])) {
5684 c = 'g';
5685 } else {
5686 c = 'f';
5687 }
5688 sprintf(bit, "%%.%d%c", p, c);
5689 strcat(fmt, bit);
5690 }
5691 if (i < 3) {
5692 strcat(fmt, "|");
5693 }
5694 }
5695 set_tex_param_format(fmt);
5696 } else {
5697 /* chose standard (default) format */
5698 set_tex_param_format(NULL);
5699 }
5700
5701 return FALSE;
5702 }
5703
get_tex_prec(const char * s)5704 static int get_tex_prec (const char *s)
5705 {
5706 int p = 4;
5707
5708 if (s != NULL) {
5709 s = strchr(s, '.');
5710 if (s != NULL) {
5711 p = atoi(s + 1);
5712 }
5713 }
5714
5715 return p;
5716 }
5717
get_tex_conv(const char * s)5718 static char get_tex_conv (const char *s)
5719 {
5720 char c = 'f';
5721 int n = strlen(s);
5722
5723 if (n > 1) {
5724 c = s[n - 1];
5725 }
5726
5727 return c;
5728 }
5729
5730 /* callback from model-window menu */
5731
tex_format_dialog(GtkAction * action,gpointer data)5732 void tex_format_dialog (GtkAction *action, gpointer data)
5733 {
5734 windata_t *vwin = (windata_t *) data;
5735 const char *labels[] = {
5736 N_("Coefficient"),
5737 N_("Standard error"),
5738 N_("t-ratio"),
5739 N_("p-value")
5740 };
5741 struct tex_formatter tf;
5742 GtkWidget *dlg, *tbl;
5743 GtkWidget *tmp, *hbox;
5744 GtkWidget *vbox, *dvbox;
5745 GSList *group;
5746 int i, nset = 0;
5747
5748 for (i=0; i<4; i++) {
5749 const char *fmt = tex_column_format(i);
5750
5751 tf.spin[i] = NULL;
5752 if (*fmt) nset++;
5753 }
5754
5755 dlg = gretl_dialog_new(_("gretl: TeX tabular format"),
5756 vwin_toplevel(vwin),
5757 GRETL_DLG_BLOCK);
5758
5759 dvbox = gtk_dialog_get_content_area(GTK_DIALOG(dlg));
5760
5761 hbox = gtk_hbox_new(FALSE, 5);
5762 vbox = gtk_vbox_new(FALSE, 0);
5763 tmp = gtk_radio_button_new_with_label(NULL, _("Standard format"));
5764 gtk_box_pack_start(GTK_BOX(vbox), tmp, TRUE, TRUE, 5);
5765 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(tmp));
5766 tmp = tf.custom = gtk_radio_button_new_with_label(group, _("Custom format"));
5767 g_signal_connect(G_OBJECT(tmp), "clicked",
5768 G_CALLBACK(toggle_tex_custom), &tf);
5769
5770 gtk_box_pack_start(GTK_BOX(vbox), tmp, TRUE, TRUE, 0);
5771 gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 5);
5772 gtk_box_pack_start(GTK_BOX(dvbox), hbox, TRUE, TRUE, 0);
5773 gtk_widget_show_all(hbox);
5774
5775 vbox_add_hsep(dvbox);
5776
5777 tbl = gtk_table_new(11, 2, FALSE);
5778 gtk_table_set_row_spacings(GTK_TABLE(tbl), 5);
5779 gtk_table_set_col_spacings(GTK_TABLE(tbl), 5);
5780
5781 for (i=0; i<4; i++) {
5782 const char *curr = tex_column_format(i);
5783 int p = get_tex_prec(curr);
5784 char c = get_tex_conv(curr);
5785 int shown = (i == 0 || curr[0] != 0 || nset == 0);
5786 int j = i * 3;
5787
5788 hbox = gtk_hbox_new(FALSE, 5);
5789 tmp = gtk_label_new(_(labels[i]));
5790 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
5791 gtk_table_attach_defaults(GTK_TABLE(tbl), hbox, 0, 2, j, j+1);
5792
5793 /* "show" check button */
5794 if (i > 0) {
5795 tmp = tf.show[i-1] = gtk_check_button_new();
5796 gtk_table_attach_defaults(GTK_TABLE(tbl), tmp, 0, 1, j+1, j+2);
5797 g_object_set_data(G_OBJECT(tmp), "row", GINT_TO_POINTER(i));
5798 g_signal_connect(G_OBJECT(tmp), "clicked",
5799 G_CALLBACK(activate_row), &tf);
5800 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tmp), shown);
5801 }
5802
5803 /* spinner for precision */
5804 hbox = gtk_hbox_new(FALSE, 5);
5805 tmp = gtk_label_new(_("Show"));
5806 tf.adj[i] = (GtkAdjustment *) gtk_adjustment_new(p, 0, 15, 1, 1, 0);
5807 tf.spin[i] = gtk_spin_button_new(tf.adj[i], 1, 0);
5808 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
5809 gtk_box_pack_start(GTK_BOX(hbox), tf.spin[i], FALSE, FALSE, 5);
5810
5811 /* decimal places versus significant figures */
5812 vbox = gtk_vbox_new(FALSE, 0);
5813 tf.radio[i].b[0] = gtk_radio_button_new_with_label(NULL, _("decimal places"));
5814 gtk_box_pack_start(GTK_BOX(vbox), tf.radio[i].b[0], TRUE, TRUE, 5);
5815 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(tf.radio[i].b[0]));
5816 tf.radio[i].b[1] = gtk_radio_button_new_with_label(group, _("significant figures"));
5817 gtk_box_pack_start(GTK_BOX(vbox), tf.radio[i].b[1], TRUE, TRUE, 0);
5818 gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 5);
5819
5820 if (c == 'g') {
5821 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tf.radio[i].b[1]), TRUE);
5822 }
5823
5824 gtk_table_attach_defaults(GTK_TABLE(tbl), hbox, 1, 2, j+1, j+2);
5825
5826 gtk_widget_set_sensitive(tf.spin[i], shown);
5827 gtk_widget_set_sensitive(tf.radio[i].b[0], shown);
5828 gtk_widget_set_sensitive(tf.radio[i].b[1], shown);
5829
5830 if (i < 3) {
5831 tmp = gtk_hseparator_new();
5832 gtk_table_attach_defaults(GTK_TABLE(tbl), tmp, 0, 2, j+2, j+3);
5833 }
5834 }
5835
5836 gtk_box_pack_start(GTK_BOX(dvbox), tbl, TRUE, TRUE, 0);
5837 gtk_widget_show_all(tbl);
5838
5839 if (tex_using_custom_tabular()) {
5840 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tf.custom), TRUE);
5841 } else {
5842 toggle_tex_custom(tf.custom, &tf);
5843 }
5844
5845 /* buttons */
5846 hbox = gtk_dialog_get_action_area(GTK_DIALOG(dlg));
5847 cancel_delete_button(hbox, dlg);
5848 tmp = ok_button(hbox);
5849 g_signal_connect(G_OBJECT(tmp), "clicked",
5850 G_CALLBACK(record_tex_format), &tf);
5851 g_signal_connect(G_OBJECT(tmp), "clicked",
5852 G_CALLBACK(delete_widget), dlg);
5853 gtk_widget_grab_default(tmp);
5854
5855 gtk_widget_show_all(hbox);
5856
5857 gretl_dialog_keep_above(dlg);
5858 gtk_widget_show(dlg);
5859 }
5860
5861 struct hc_opts {
5862 GtkWidget *dialog;
5863 GtkWidget *cbutton;
5864 GtkWidget *entry;
5865 char *targ;
5866 int retval;
5867 };
5868
hc_ok_callback(GtkWidget * w,struct hc_opts * h)5869 static void hc_ok_callback (GtkWidget *w, struct hc_opts *h)
5870 {
5871 if (button_is_active(h->cbutton)) {
5872 const gchar *s = gtk_entry_get_text(GTK_ENTRY(h->entry));
5873 int v = current_series_index(dataset, s);
5874
5875 if (v < 1) {
5876 h->retval = GRETL_CANCEL;
5877 if (*s == '\0') {
5878 warnbox(_("Please specify a cluster variable"));
5879 } else {
5880 errbox_printf(_("'%s' is not a known series"), s);
5881 }
5882 return;
5883 }
5884 *h->targ = '\0';
5885 strncat(h->targ, s, VNAMELEN - 1);
5886 h->retval = 1;
5887 } else {
5888 h->retval = 0;
5889 }
5890
5891 gtk_widget_destroy(h->dialog);
5892 }
5893
hc_config_dialog(char * vname,gretlopt opt,gboolean robust_conf,GtkWidget * parent)5894 int hc_config_dialog (char *vname, gretlopt opt, gboolean robust_conf,
5895 GtkWidget *parent)
5896 {
5897 struct hc_opts opts;
5898 GtkWidget *dialog;
5899 GtkWidget *vbox, *hbox;
5900 GtkWidget *b1, *b2, *entry;
5901 GSList *group = NULL;
5902
5903 if (maybe_raise_dialog()) {
5904 return GRETL_CANCEL;
5905 }
5906
5907 opts.retval = GRETL_CANCEL;
5908 opts.targ = vname;
5909
5910 opts.dialog = dialog = gretl_dialog_new(NULL, parent, GRETL_DLG_BLOCK);
5911 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
5912
5913 hbox = gtk_hbox_new(FALSE, 5);
5914 if (robust_conf) {
5915 /* regular HCCME option */
5916 b1 = gtk_radio_button_new_with_label(NULL,
5917 _("Select from Regular HCCME options"));
5918 } else {
5919 b1 = gtk_radio_button_new_with_label(NULL, "QML");
5920 }
5921 gtk_box_pack_start(GTK_BOX(hbox), b1, FALSE, FALSE, 5);
5922 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
5923
5924
5925 /* cluster-robust option */
5926 hbox = gtk_hbox_new(FALSE, 5);
5927 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(b1));
5928 opts.cbutton = b2 = gtk_radio_button_new_with_label(group, _("Cluster by"));
5929 gtk_box_pack_start(GTK_BOX(hbox), b2, FALSE, FALSE, 5);
5930 opts.entry = entry = gtk_entry_new();
5931 gtk_entry_set_max_length(GTK_ENTRY(entry), VNAMELEN);
5932 gtk_entry_set_width_chars(GTK_ENTRY(entry), VNAMELEN + 2);
5933 gtk_entry_set_text(GTK_ENTRY(entry), vname);
5934 gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
5935 sensitize_conditional_on(entry, b2);
5936 gtk_container_add(GTK_CONTAINER(hbox), entry);
5937 gtk_container_add(GTK_CONTAINER(vbox), hbox);
5938
5939 if ((opt & OPT_C) && *vname != '\0') {
5940 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b2), TRUE);
5941 } else {
5942 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b1), TRUE);
5943 gtk_widget_set_sensitive(entry, FALSE);
5944 }
5945
5946 /* buttons */
5947 hbox = gtk_dialog_get_action_area(GTK_DIALOG(dialog));
5948 cancel_delete_button(hbox, dialog);
5949 b1 = ok_button(hbox);
5950 g_signal_connect(G_OBJECT(b1), "clicked",
5951 G_CALLBACK(hc_ok_callback), &opts);
5952 gtk_widget_grab_default(b1);
5953 context_help_button(hbox, CLUSTER);
5954
5955 gtk_widget_show_all(dialog);
5956
5957 return opts.retval;
5958 }
5959
5960 #ifndef G_OS_WIN32
5961
dont_delete(void)5962 static gint dont_delete (void)
5963 {
5964 return TRUE;
5965 }
5966
5967 #endif
5968
real_output_policy_dlg(const char ** opts,int deflt,int toolbar,GtkWidget * parent)5969 static int real_output_policy_dlg (const char **opts,
5970 int deflt,
5971 int toolbar,
5972 GtkWidget *parent)
5973 {
5974 GtkWidget *dialog;
5975 GtkWidget *vbox, *hbox, *tmp;
5976 GtkWidget *button = NULL;
5977 GSList *group = NULL;
5978 int radio_val = deflt;
5979 int hcode = 0;
5980 int i, ret = GRETL_CANCEL;
5981
5982 if (maybe_raise_dialog()) {
5983 return ret;
5984 }
5985
5986 dialog = gretl_dialog_new(NULL, parent, GRETL_DLG_BLOCK);
5987 #ifdef G_OS_WIN32
5988 gtk_window_set_deletable(GTK_WINDOW(dialog), FALSE);
5989 #else
5990 /* the function above may well not work */
5991 g_signal_connect(G_OBJECT(dialog), "delete-event",
5992 G_CALLBACK(dont_delete), NULL);
5993 #endif
5994
5995 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
5996
5997 hbox = gtk_hbox_new(FALSE, 5);
5998 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
5999 if (toolbar) {
6000 tmp = gtk_label_new(_("New script output:"));
6001 } else {
6002 tmp = gtk_label_new(_("New script output should:"));
6003 }
6004 gtk_box_pack_start(GTK_BOX(hbox), tmp, TRUE, TRUE, 5);
6005
6006 for (i=0; i<3; i++) {
6007 button = gtk_radio_button_new_with_label(group, _(opts[i]));
6008 gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0);
6009 g_object_set_data(G_OBJECT(button), "action", GINT_TO_POINTER(i));
6010 g_signal_connect(G_OBJECT(button), "clicked",
6011 G_CALLBACK(set_radio_opt), &radio_val);
6012 if (i == deflt) {
6013 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (button), TRUE);
6014 }
6015 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
6016 }
6017
6018 if (!toolbar) {
6019 hbox = gtk_hbox_new(FALSE, 5);
6020 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
6021 tmp = gtk_image_new_from_stock(GRETL_STOCK_PIN,
6022 GTK_ICON_SIZE_MENU);
6023 gtk_box_pack_start(GTK_BOX(hbox), tmp, TRUE, TRUE, 5);
6024 tmp = gtk_label_new("Note that you can change this policy via the\n"
6025 "\"Stickiness\" button in the script output window.");
6026 gtk_box_pack_start(GTK_BOX(hbox), tmp, TRUE, TRUE, 5);
6027 }
6028
6029 /* buttons */
6030 hbox = gtk_dialog_get_action_area(GTK_DIALOG(dialog));
6031 tmp = ok_validate_button(hbox, &ret, &radio_val);
6032 g_signal_connect(G_OBJECT(tmp), "clicked",
6033 G_CALLBACK(delete_widget), dialog);
6034 gtk_widget_grab_default(tmp);
6035 if (hcode) {
6036 context_help_button(hbox, hcode);
6037 } else {
6038 gretl_dialog_keep_above(dialog);
6039 }
6040
6041 gtk_widget_show_all(dialog);
6042
6043 return ret;
6044 }
6045
output_policy_dialog(windata_t * source,windata_t * target,int toolbar)6046 int output_policy_dialog (windata_t *source,
6047 windata_t *target,
6048 int toolbar)
6049 {
6050 int orig = get_script_output_policy();
6051 int resp, deflt, policy;
6052
6053 /* convert to zero-based? */
6054 deflt = (orig == OUTPUT_POLICY_UNSET)? orig : orig - 1;
6055
6056 if (!toolbar) {
6057 /* not called via output window toolbar */
6058 const char *opts[] = {
6059 N_("Replace previous output"),
6060 N_("Add to previous output"),
6061 N_("Go to a new window")
6062 };
6063
6064 resp = real_output_policy_dlg(opts, deflt, toolbar,
6065 vwin_toplevel(source));
6066 } else {
6067 const char *opts[] = {
6068 N_("Replaces output in this window"),
6069 N_("Adds to output in this window"),
6070 N_("Always goes to a new window")
6071 };
6072
6073 resp = real_output_policy_dlg(opts, deflt, toolbar,
6074 vwin_toplevel(source));
6075 }
6076
6077 /* convert policy back to 1-based */
6078 policy = (resp == GRETL_CANCEL)? (deflt + 1) : resp + 1;
6079
6080 set_script_output_policy(policy, target);
6081
6082 return policy;
6083 }
6084
auto_pc_name(const char * vname,int idxvals)6085 static gchar *auto_pc_name (const char *vname, int idxvals)
6086 {
6087 char pcname[VNAMELEN];
6088
6089 pcname[0] = '\0';
6090
6091 if (idxvals) {
6092 strcat(pcname, "i_");
6093 strncat(pcname, vname, VNAMELEN - 4);
6094 } else {
6095 strcat(pcname, "pc_");
6096 strncat(pcname, vname, VNAMELEN - 5);
6097 }
6098
6099 return g_strdup(pcname);
6100 }
6101
6102 struct pc_change_info {
6103 GtkWidget *dialog;
6104 GtkWidget *entry;
6105 GtkWidget *logcheck;
6106 const int *varlist;
6107 int *ctrl;
6108 };
6109
6110 struct index_vals_info {
6111 GtkWidget *dialog;
6112 GtkWidget *entry;
6113 GtkWidget *spin;
6114 const int *varlist;
6115 };
6116
pc_change_get_vname(GtkWidget * dialog,GtkWidget * entry)6117 static gchar *pc_change_get_vname (GtkWidget *dialog,
6118 GtkWidget *entry)
6119 {
6120 gchar *newname = entry_box_get_trimmed_text(entry);
6121
6122 if (newname == NULL || *newname == '\0') {
6123 gtk_widget_grab_focus(entry);
6124 g_free(newname);
6125 return NULL;
6126 } else {
6127 int err = gui_validate_varname(newname,
6128 GRETL_TYPE_SERIES,
6129 dialog);
6130 if (err) {
6131 gtk_widget_grab_focus(entry);
6132 g_free(newname);
6133 return NULL;
6134 }
6135 }
6136
6137 return newname;
6138 }
6139
do_pc_change(GtkWidget * w,struct pc_change_info * pci)6140 static void do_pc_change (GtkWidget *w, struct pc_change_info *pci)
6141 {
6142 gchar *lhname = NULL;
6143 int autoname = 0;
6144 int err = 0;
6145
6146 if (pci->entry != NULL) {
6147 lhname = pc_change_get_vname(pci->dialog, pci->entry);
6148 if (lhname == NULL) {
6149 return;
6150 }
6151 } else {
6152 autoname = 1;
6153 }
6154
6155 if (!err) {
6156 int use_logs = 0;
6157 int i, ctrl = 0;
6158
6159 if (pci->ctrl != NULL) {
6160 ctrl = *pci->ctrl;
6161 }
6162
6163 if (pci->logcheck != NULL &&
6164 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(pci->logcheck))) {
6165 use_logs = 1;
6166 }
6167
6168 for (i=1; i<=pci->varlist[0] && !err; i++) {
6169 const char *vname = dataset->varname[pci->varlist[i]];
6170 gchar *genline = NULL;
6171
6172 if (autoname) {
6173 lhname = auto_pc_name(vname, 0);
6174 }
6175 if (ctrl == 0) {
6176 /* period to period rate */
6177 if (use_logs) {
6178 genline = g_strdup_printf("series %s=100*log(%s/%s(-1))",
6179 lhname, vname, vname);
6180 } else {
6181 genline = g_strdup_printf("series %s=100*(%s/%s(-1)-1)",
6182 lhname, vname, vname);
6183 }
6184 } else if (ctrl == 1) {
6185 /* annualized */
6186 if (use_logs) {
6187 int mult = dataset->pd * 100;
6188 genline = g_strdup_printf("series %s=%d*log(%s/%s(-1))",
6189 lhname, mult, vname, vname);
6190 } else {
6191 genline = g_strdup_printf("series %s=100*((%s/%s(-1))^%d-1)",
6192 lhname, vname, vname, dataset->pd);
6193 }
6194 } else {
6195 /* year on year */
6196 if (use_logs) {
6197 genline = g_strdup_printf("series %s=100*log(%s/%s(-%d))",
6198 lhname, vname, vname, dataset->pd);
6199 } else {
6200 genline = g_strdup_printf("series %s=100*(%s/%s(-%d)-1)",
6201 lhname, vname, vname, dataset->pd);
6202 }
6203 }
6204
6205 err = gui_run_genr(genline, dataset, OPT_NONE, NULL);
6206
6207 if (err) {
6208 gui_errmsg(err);
6209 } else {
6210 add_command_to_stack(genline, 0);
6211 refresh_data();
6212 }
6213
6214 g_free(genline);
6215 if (autoname) {
6216 g_free(lhname);
6217 lhname = NULL;
6218 }
6219 }
6220 }
6221
6222 if (!autoname) {
6223 g_free(lhname);
6224 }
6225
6226 if (!err) {
6227 gtk_widget_destroy(pci->dialog);
6228 }
6229 }
6230
index_values_callback(GtkWidget * w,struct index_vals_info * ixi)6231 static void index_values_callback (GtkWidget *w,
6232 struct index_vals_info *ixi)
6233 {
6234 gchar *lhname = NULL;
6235 int autoname = 0;
6236 int err = 0;
6237
6238 if (ixi->entry != NULL) {
6239 lhname = pc_change_get_vname(ixi->dialog, ixi->entry);
6240 if (lhname == NULL) {
6241 return;
6242 }
6243 } else {
6244 autoname = 1;
6245 }
6246
6247 if (!err) {
6248 char obsstr[OBSLEN];
6249 int i, t1;
6250
6251 t1 = spinner_get_int(ixi->spin);
6252 ntolabel(obsstr, t1, dataset);
6253
6254 for (i=1; i<=ixi->varlist[0] && !err; i++) {
6255 const char *vname = dataset->varname[ixi->varlist[i]];
6256 gchar *genline = NULL;
6257
6258 if (autoname) {
6259 lhname = auto_pc_name(vname, 1);
6260 }
6261 genline = g_strdup_printf("series %s=100*%s/%s[%s]",
6262 lhname, vname, vname, obsstr);
6263 err = gui_run_genr(genline, dataset, OPT_NONE, NULL);
6264 if (err) {
6265 gui_errmsg(err);
6266 } else {
6267 add_command_to_stack(genline, 0);
6268 refresh_data();
6269 }
6270 g_free(genline);
6271 if (autoname) {
6272 g_free(lhname);
6273 lhname = NULL;
6274 }
6275 }
6276 }
6277
6278 if (!autoname) {
6279 g_free(lhname);
6280 }
6281
6282 if (!err) {
6283 gtk_widget_destroy(ixi->dialog);
6284 }
6285 }
6286
percent_change_dialog(const int * list)6287 static void percent_change_dialog (const int *list)
6288 {
6289 struct pc_change_info pci;
6290 GtkWidget *dialog;
6291 GtkWidget *vbox, *hbox, *tmp;
6292 GtkWidget *button = NULL;
6293 gchar *msg;
6294 int radioval = 1;
6295
6296 if (maybe_raise_dialog()) {
6297 return;
6298 }
6299
6300 dialog = gretl_dialog_new(NULL, NULL, GRETL_DLG_BLOCK);
6301 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
6302
6303 pci.dialog = dialog;
6304 pci.varlist = list;
6305 pci.ctrl = NULL;
6306
6307 hbox = gtk_hbox_new(FALSE, 5);
6308 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
6309 if (list[0] == 1) {
6310 msg = g_strdup_printf(_("percent change in %s"),
6311 dataset->varname[list[1]]);
6312 } else {
6313 msg = g_strdup_printf(_("percent changes"));
6314 }
6315 tmp = gtk_label_new(msg);
6316 g_free(msg);
6317 gtk_box_pack_start(GTK_BOX(hbox), tmp, TRUE, TRUE, 5);
6318
6319 if (pci.varlist[0] == 1) {
6320 hbox = gtk_hbox_new(FALSE, 5);
6321 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
6322 msg = g_strdup_printf(_("Enter name for new variable\n"
6323 "(max. %d characters)"),
6324 VNAMELEN - 1);
6325 tmp = gtk_label_new(msg);
6326 g_free(msg);
6327 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
6328
6329 hbox = gtk_hbox_new(FALSE, 5);
6330 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
6331 pci.entry = tmp = gtk_entry_new();
6332 gtk_entry_set_max_length(GTK_ENTRY(tmp), 32);
6333 gtk_entry_set_width_chars(GTK_ENTRY(tmp), 32);
6334 gtk_entry_set_activates_default(GTK_ENTRY(tmp), TRUE);
6335 gtk_box_pack_start(GTK_BOX(hbox), tmp, TRUE, TRUE, 5);
6336 } else {
6337 pci.entry = NULL;
6338 }
6339
6340 if (quarterly_or_monthly(dataset)) {
6341 const char *q_opts[] = {
6342 N_("Quarterly"),
6343 N_("Quarterly, annualized"),
6344 N_("Year on year")
6345 };
6346 const char *m_opts[] = {
6347 N_("Monthly"),
6348 N_("Monthly, annualized"),
6349 N_("Year on year")
6350 };
6351 const char **opts;
6352 GSList *group = NULL;
6353 int i;
6354
6355 opts = dataset->pd == 4 ? q_opts : m_opts;
6356
6357 for (i=0; i<3; i++) {
6358 button = gtk_radio_button_new_with_label(group, _(opts[i]));
6359 gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0);
6360 g_object_set_data(G_OBJECT(button), "action", GINT_TO_POINTER(i));
6361 g_signal_connect(G_OBJECT(button), "clicked",
6362 G_CALLBACK(set_radio_opt), &radioval);
6363 if (i == 1) {
6364 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (button), TRUE);
6365 }
6366 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
6367 }
6368 pci.ctrl = &radioval;
6369 }
6370
6371 /* add option of calculating via logs */
6372 hbox = gtk_hbox_new(FALSE, 5);
6373 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
6374 pci.logcheck = gtk_check_button_new_with_label(_("Calculate using logs"));
6375 gtk_box_pack_start(GTK_BOX(hbox), pci.logcheck, TRUE, TRUE, 5);
6376
6377 /* buttons */
6378 hbox = gtk_dialog_get_action_area(GTK_DIALOG(dialog));
6379 cancel_delete_button(hbox, dialog);
6380 tmp = ok_button(hbox);
6381 g_signal_connect(G_OBJECT(tmp), "clicked",
6382 G_CALLBACK(do_pc_change), &pci);
6383 gtk_widget_grab_default(tmp);
6384
6385 gretl_dialog_keep_above(dialog);
6386 gtk_widget_show_all(dialog);
6387 }
6388
index_values_dialog(const int * list)6389 static void index_values_dialog (const int *list)
6390 {
6391 struct index_vals_info ixi;
6392 GtkAdjustment *adj;
6393 GtkWidget *dialog;
6394 GtkWidget *vbox, *hbox, *tmp;
6395 gchar *msg;
6396
6397 if (maybe_raise_dialog()) {
6398 return;
6399 }
6400
6401 dialog = gretl_dialog_new(NULL, NULL, GRETL_DLG_BLOCK);
6402 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
6403
6404 ixi.dialog = dialog;
6405 ixi.varlist = list;
6406 ixi.spin = NULL;
6407
6408 hbox = gtk_hbox_new(FALSE, 5);
6409 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
6410 if (list[0] == 1) {
6411 msg = g_strdup_printf(_("100-based index of %s"),
6412 dataset->varname[list[1]]);
6413 } else {
6414 msg = g_strdup_printf(_("100-based indices"));
6415 }
6416 tmp = gtk_label_new(msg);
6417 g_free(msg);
6418 gtk_box_pack_start(GTK_BOX(hbox), tmp, TRUE, TRUE, 5);
6419
6420 if (ixi.varlist[0] == 1) {
6421 hbox = gtk_hbox_new(FALSE, 5);
6422 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
6423 msg = g_strdup_printf(_("Enter name for new variable\n"
6424 "(max. %d characters)"),
6425 VNAMELEN - 1);
6426 tmp = gtk_label_new(msg);
6427 g_free(msg);
6428 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
6429
6430 hbox = gtk_hbox_new(FALSE, 5);
6431 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
6432 ixi.entry = tmp = gtk_entry_new();
6433 gtk_entry_set_max_length(GTK_ENTRY(tmp), 32);
6434 gtk_entry_set_width_chars(GTK_ENTRY(tmp), 32);
6435 gtk_entry_set_activates_default(GTK_ENTRY(tmp), TRUE);
6436 gtk_box_pack_start(GTK_BOX(hbox), tmp, TRUE, TRUE, 5);
6437 } else {
6438 ixi.entry = NULL;
6439 }
6440
6441 /* selection of base period for index via spin button */
6442 hbox = gtk_hbox_new(FALSE, 5);
6443 adj = (GtkAdjustment *) gtk_adjustment_new(dataset->t1, 0,
6444 dataset->n - 1,
6445 1, 1, 0);
6446 ixi.spin = obs_button_new(adj, dataset, OBS_BUTTON_T1);
6447 gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(_("Base period:")),
6448 FALSE, FALSE, 5);
6449 gtk_box_pack_start(GTK_BOX(hbox), ixi.spin, FALSE, FALSE, 0);
6450 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
6451
6452 /* buttons */
6453 hbox = gtk_dialog_get_action_area(GTK_DIALOG(dialog));
6454 cancel_delete_button(hbox, dialog);
6455 tmp = ok_button(hbox);
6456 g_signal_connect(G_OBJECT(tmp), "clicked",
6457 G_CALLBACK(index_values_callback), &ixi);
6458 gtk_widget_grab_default(tmp);
6459
6460 gretl_dialog_keep_above(dialog);
6461 gtk_widget_show_all(dialog);
6462 }
6463
single_percent_change_dialog(int v,int idxvals)6464 void single_percent_change_dialog (int v, int idxvals)
6465 {
6466 int list[2] = {1, v};
6467
6468 if (idxvals) {
6469 index_values_dialog(list);
6470 } else {
6471 percent_change_dialog(list);
6472 }
6473 }
6474
multi_percent_change_dialog(int idxvals)6475 void multi_percent_change_dialog (int idxvals)
6476 {
6477 int *list = main_window_selection_as_list();
6478
6479 if (list != NULL) {
6480 if (idxvals) {
6481 index_values_dialog(list);
6482 } else {
6483 percent_change_dialog(list);
6484 }
6485 free(list);
6486 }
6487 }
6488
6489 struct midas_sync {
6490 int *ptype;
6491 int *minlag;
6492 int *maxlag;
6493 GtkWidget *kspin;
6494 GtkWidget *l0spin;
6495 GtkWidget *l1spin;
6496 };
6497
set_midas_ptype(GtkComboBox * w,struct midas_sync * msync)6498 static void set_midas_ptype (GtkComboBox *w, struct midas_sync *msync)
6499 {
6500 int pt = gtk_combo_box_get_active(w);
6501 int fixval = 0;
6502
6503 if (pt == MIDAS_BETA1) {
6504 fixval = 1;
6505 } else if (pt == MIDAS_BETA0) {
6506 fixval = 2;
6507 } else if (pt == MIDAS_BETAN) {
6508 fixval = 3;
6509 } else if (pt == MIDAS_U) {
6510 int l0 = spinner_get_int(msync->l0spin);
6511 int l1 = spinner_get_int(msync->l1spin);
6512 int k = l1 - l0 + 1;
6513
6514 fixval = k;
6515 }
6516
6517 if (fixval) {
6518 gtk_spin_button_set_value(GTK_SPIN_BUTTON(msync->kspin), fixval);
6519 }
6520 gtk_widget_set_sensitive(msync->kspin, fixval == 0);
6521
6522 *msync->ptype = pt;
6523 }
6524
set_midas_lag(GtkSpinButton * w,struct midas_sync * msync)6525 static void set_midas_lag (GtkSpinButton *w, struct midas_sync *msync)
6526 {
6527 int l0, l1, val = gtk_spin_button_get_value_as_int(w);
6528
6529 if (GTK_WIDGET(w) == msync->l0spin) {
6530 l0 = val;
6531 if (spinner_get_int(msync->l1spin) < l0) {
6532 gtk_spin_button_set_value(GTK_SPIN_BUTTON(msync->l1spin), l0);
6533 }
6534 *msync->minlag = l0;
6535 } else {
6536 l1 = val;
6537 if (spinner_get_int(msync->l0spin) > l1) {
6538 gtk_spin_button_set_value(GTK_SPIN_BUTTON(msync->l0spin), l1);
6539 }
6540 *msync->maxlag = l1;
6541 }
6542 }
6543
midas_term_dialog(const char * name,int m,int * minlag,int * maxlag,int * ptype,int * ncoef,gboolean no_beta1,GtkWidget * parent)6544 int midas_term_dialog (const char *name, int m,
6545 int *minlag, int *maxlag,
6546 int *ptype, int *ncoef,
6547 gboolean no_beta1,
6548 GtkWidget *parent)
6549 {
6550 const char *opts[] = {
6551 N_("Unrestricted (U-MIDAS)"),
6552 N_("Normalized exponential Almon"),
6553 N_("Normalized beta (zero last lag)"),
6554 N_("Normalized beta (non-zero last lag)"),
6555 N_("Almon polynomial"),
6556 N_("Normalized beta, one parameter")
6557 };
6558 struct midas_sync msync;
6559 GtkWidget *dialog, *combo;
6560 GtkWidget *vbox, *hbox, *tmp;
6561 gchar *msg;
6562 int i, np, hcode = MIDAS_PARM;
6563 int ret = GRETL_CANCEL;
6564
6565 if (maybe_raise_dialog()) {
6566 return ret;
6567 }
6568
6569 dialog = gretl_dialog_new("gretl: MIDAS term", parent, GRETL_DLG_BLOCK);
6570 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
6571
6572 msync.ptype = ptype;
6573 msync.minlag = minlag;
6574 msync.maxlag = maxlag;
6575
6576 /* label */
6577 hbox = gtk_hbox_new(FALSE, 5);
6578 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
6579 msg = g_strdup_printf(_("High-frequency regressor %s"), name);
6580 tmp = gtk_label_new(msg);
6581 g_free(msg);
6582 gtk_box_pack_start(GTK_BOX(hbox), tmp, TRUE, TRUE, 5);
6583
6584 np = G_N_ELEMENTS(opts);
6585 if (no_beta1) {
6586 np--;
6587 }
6588
6589 /* param type selection */
6590 hbox = gtk_hbox_new(FALSE, 5);
6591 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
6592 tmp = gtk_label_new(_("Parameterization"));
6593 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
6594 combo = gtk_combo_box_text_new();
6595 gtk_box_pack_start(GTK_BOX(hbox), combo, FALSE, FALSE, 5);
6596 for (i=0; i<np; i++) {
6597 combo_box_append_text(combo, opts[i]);
6598 }
6599 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), *ptype);
6600
6601 /* number of coefficients */
6602 hbox = gtk_hbox_new(FALSE, 5);
6603 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
6604 tmp = gtk_label_new(_("Number of parameters"));
6605 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
6606 msync.kspin = tmp = gtk_spin_button_new_with_range(1, 10, 1);
6607 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tmp), *ncoef);
6608 g_signal_connect(G_OBJECT(tmp), "value-changed",
6609 G_CALLBACK(set_int_from_spinner), ncoef);
6610 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
6611
6612 /* minimum and maximum lags */
6613 hbox = gtk_hbox_new(FALSE, 5);
6614 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
6615 tmp = gtk_label_new(_("Lags"));
6616 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
6617 msync.l0spin = tmp = gtk_spin_button_new_with_range(-100, 100, 1);
6618 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tmp), *minlag);
6619 g_signal_connect(G_OBJECT(tmp), "value-changed",
6620 G_CALLBACK(set_midas_lag), &msync);
6621 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
6622 tmp = gtk_label_new(_("to"));
6623 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
6624 msync.l1spin = tmp = gtk_spin_button_new_with_range(-100, 100, 1);
6625 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tmp), *maxlag);
6626 g_signal_connect(G_OBJECT(tmp), "value-changed",
6627 G_CALLBACK(set_midas_lag), &msync);
6628 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
6629
6630 /* set param-type callback */
6631 g_signal_connect(G_OBJECT(combo), "changed",
6632 G_CALLBACK(set_midas_ptype), &msync);
6633 /* and trigger it to ensure kspin is right */
6634 set_midas_ptype(GTK_COMBO_BOX(combo), &msync);
6635
6636 /* buttons */
6637 hbox = gtk_dialog_get_action_area(GTK_DIALOG(dialog));
6638 cancel_delete_button(hbox, dialog);
6639 tmp = ok_validate_button(hbox, &ret, NULL);
6640 g_signal_connect(G_OBJECT(tmp), "clicked",
6641 G_CALLBACK(delete_widget), dialog);
6642 gtk_widget_grab_default(tmp);
6643 if (hcode) {
6644 context_help_button(hbox, hcode);
6645 } else {
6646 gretl_dialog_keep_above(dialog);
6647 }
6648
6649 gtk_widget_show_all(dialog);
6650
6651 return ret;
6652 }
6653
6654 struct dbnomics_info {
6655 int *retval;
6656 char **pcode;
6657 GtkWidget *entry;
6658 GtkWidget *dlg;
6659 };
6660
dbn_callback(GtkWidget * w,struct dbnomics_info * di)6661 static void dbn_callback (GtkWidget *w, struct dbnomics_info *di)
6662 {
6663 const char *s = gtk_entry_get_text(GTK_ENTRY(di->entry));
6664
6665 if (s != NULL && *s != '\0') {
6666 *di->retval = 0;
6667 *di->pcode = gretl_strdup(s);
6668 gtk_widget_destroy(di->dlg);
6669 } else {
6670 gtk_widget_grab_focus(di->entry);
6671 }
6672 }
6673
dbnomics_dialog(char ** dbcode,GtkWidget * parent)6674 int dbnomics_dialog (char **dbcode, GtkWidget *parent)
6675 {
6676 struct dbnomics_info di = {0};
6677 GtkWidget *dialog, *entry;
6678 GtkWidget *vbox, *hbox, *tmp;
6679 int hcode = DBNHELP;
6680 int ret = GRETL_CANCEL;
6681
6682 if (maybe_raise_dialog()) {
6683 return ret;
6684 }
6685
6686 dialog = gretl_dialog_new("gretl: dbnomics access", parent, GRETL_DLG_BLOCK);
6687 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
6688
6689 di.retval = &ret;
6690 di.pcode = dbcode;
6691 di.dlg = dialog;
6692
6693 hbox = gtk_hbox_new(FALSE, 5);
6694 tmp = gtk_label_new(_("series code:"));
6695 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
6696
6697 di.entry = entry = gtk_entry_new();
6698 gtk_entry_set_max_length(GTK_ENTRY(entry), 128);
6699 gtk_entry_set_width_chars(GTK_ENTRY(entry), 48);
6700
6701 gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, FALSE, 5);
6702 gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
6703 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
6704
6705 /* buttons */
6706 hbox = gtk_dialog_get_action_area(GTK_DIALOG(dialog));
6707 cancel_delete_button(hbox, dialog);
6708 tmp = ok_button(hbox);
6709 g_signal_connect(G_OBJECT(tmp), "clicked",
6710 G_CALLBACK(dbn_callback), &di);
6711 gtk_widget_grab_default(tmp);
6712 if (hcode) {
6713 context_help_button(hbox, hcode);
6714 } else {
6715 gretl_dialog_keep_above(dialog);
6716 }
6717
6718 gtk_widget_show_all(dialog);
6719
6720 return ret;
6721 }
6722
6723 /* geoplot GUI helper functions */
6724
6725 static const char *palettes[] = {
6726 "default", "blues", "oranges", "green-to-red"
6727 };
6728
6729 struct geoplot_info {
6730 int *retval;
6731 gretl_bundle *bundle;
6732 int *payload_id;
6733 int *palette_id;
6734 gchar **pplname;
6735 GtkWidget *payload_combo;
6736 GtkWidget *palette_combo;
6737 GtkWidget *border_check;
6738 GtkWidget *logscale_check;
6739 GtkWidget *linewidth_spin;
6740 GtkWidget *height_spin;
6741 GtkWidget *dlg;
6742 };
6743
geoplot_callback(GtkWidget * w,struct geoplot_info * gi)6744 static void geoplot_callback (GtkWidget *w, struct geoplot_info *gi)
6745 {
6746 int border, logscale, height;
6747 double lwidth;
6748
6749 if (gtk_widget_is_sensitive(gi->payload_combo)) {
6750 gchar *payload = NULL;
6751 int palnum = 0;
6752
6753 payload = combo_box_get_active_text(gi->payload_combo);
6754 palnum = gtk_combo_box_get_active(GTK_COMBO_BOX(gi->palette_combo));
6755
6756 if (payload != NULL && strcmp(payload, "none")) {
6757 *gi->payload_id = current_series_index(dataset, payload);
6758 if (palnum > 0) {
6759 gretl_bundle_set_string(gi->bundle, "palette",
6760 palettes[palnum]);
6761 }
6762 }
6763 /* record the user's choices */
6764 g_free(*gi->pplname);
6765 *gi->pplname = payload;
6766 *gi->palette_id = palnum;
6767 }
6768
6769 border = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gi->border_check));
6770 logscale = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gi->logscale_check));
6771 height = gtk_spin_button_get_value(GTK_SPIN_BUTTON(gi->height_spin));
6772
6773 gretl_bundle_set_int(gi->bundle, "border", border);
6774 gretl_bundle_set_int(gi->bundle, "logscale", logscale);
6775 gretl_bundle_set_int(gi->bundle, "height", height);
6776
6777 lwidth = gtk_spin_button_get_value(GTK_SPIN_BUTTON(gi->linewidth_spin));
6778 lwidth = nearbyint(10*lwidth) / 10;
6779 if (lwidth != 1.0) {
6780 gretl_bundle_set_scalar(gi->bundle, "linewidth", lwidth);
6781 }
6782
6783 *gi->retval = 0;
6784 gtk_widget_destroy(gi->dlg);
6785 }
6786
sensitize_map_controls(GtkComboBox * combo,struct geoplot_info * gi)6787 static void sensitize_map_controls (GtkComboBox *combo,
6788 struct geoplot_info *gi)
6789 {
6790 gchar *s = combo_box_get_active_text(combo);
6791 int active = strcmp(s, "none");
6792
6793 gtk_widget_set_sensitive(gi->palette_combo, active);
6794 gtk_widget_set_sensitive(gi->logscale_check, active);
6795 gtk_spin_button_set_range(GTK_SPIN_BUTTON(gi->linewidth_spin),
6796 active ? 0.0 : 0.1, 2.0);
6797 }
6798
6799 /* If we have a previously selected @payload, and it's a
6800 member of the current @plist, select it again by default.
6801 */
6802
maybe_reinstate_selection(GList * plist,const gchar * payload,int * selpos)6803 static void maybe_reinstate_selection (GList *plist,
6804 const gchar *payload,
6805 int *selpos)
6806 {
6807 GList *tmp = g_list_first(plist);
6808 int i = 0;
6809
6810 while (tmp != NULL) {
6811 if (!strcmp((gchar *) tmp->data, payload)) {
6812 *selpos = 1;
6813 break;
6814 }
6815 tmp = tmp->next;
6816 i++;
6817 }
6818 }
6819
map_options_dialog(GList * plist,int selpos,gretl_bundle * b,int * payload_id)6820 int map_options_dialog (GList *plist, int selpos, gretl_bundle *b,
6821 int *payload_id)
6822 {
6823 static gchar *payload = NULL;
6824 static int palette_id = 0;
6825 struct geoplot_info gi = {0};
6826 GtkWidget *dialog, *com1, *com2;
6827 GtkWidget *vbox, *hbox, *tmp;
6828 GtkWidget *bc, *ls, *hs, *lw;
6829 double lw_min = 0.0;
6830 int i, ret = GRETL_CANCEL;
6831
6832 if (maybe_raise_dialog()) {
6833 return ret;
6834 }
6835
6836 dialog = gretl_dialog_new(_("gretl: display map"), NULL, GRETL_DLG_BLOCK);
6837 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
6838
6839 gi.retval = &ret;
6840 gi.bundle = b;
6841 gi.payload_id = payload_id;
6842 gi.palette_id = &palette_id;
6843 gi.pplname = &payload;
6844 gi.dlg = dialog;
6845
6846 /* want a payload? */
6847 hbox = gtk_hbox_new(FALSE, 5);
6848 tmp = gtk_label_new(_("series to plot:"));
6849 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
6850 gi.payload_combo = com1 = gtk_combo_box_text_new();
6851 gtk_box_pack_start(GTK_BOX(hbox), com1, FALSE, FALSE, 5);
6852 if (plist != NULL) {
6853 if (payload != NULL) {
6854 maybe_reinstate_selection(plist, payload, &selpos);
6855 }
6856 set_combo_box_strings_from_list(com1, plist);
6857 gtk_combo_box_set_active(GTK_COMBO_BOX(com1), selpos);
6858 } else {
6859 combo_box_append_text(com1, _("none"));
6860 gtk_combo_box_set_active(GTK_COMBO_BOX(com1), 0);
6861 }
6862 gtk_widget_set_sensitive(hbox, plist != NULL);
6863 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
6864
6865 /* palette? */
6866 hbox = gtk_hbox_new(FALSE, 5);
6867 tmp = gtk_label_new(_("palette:"));
6868 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
6869 gi.palette_combo = com2 = gtk_combo_box_text_new();
6870 gtk_box_pack_start(GTK_BOX(hbox), com2, FALSE, FALSE, 5);
6871 for (i=0; i<G_N_ELEMENTS(palettes); i++) {
6872 combo_box_append_text(com2, palettes[i]);
6873 }
6874 gtk_combo_box_set_active(GTK_COMBO_BOX(com2), palette_id);
6875 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
6876 gtk_widget_set_sensitive(com2, selpos ? 1 : 0);
6877 gtk_widget_set_sensitive(hbox, plist != NULL);
6878
6879 /* logscale? */
6880 hbox = gtk_hbox_new(FALSE, 5);
6881 ls = gtk_check_button_new_with_label(_("Log scale"));
6882 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ls), FALSE);
6883 gi.logscale_check = ls;
6884 gtk_box_pack_start(GTK_BOX(hbox), ls, FALSE, FALSE, 5);
6885 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
6886 gtk_widget_set_sensitive(ls, selpos ? 1 : 0);
6887
6888 /* border? */
6889 hbox = gtk_hbox_new(FALSE, 5);
6890 bc = gtk_check_button_new_with_label(_("draw border around map"));
6891 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bc), TRUE);
6892 gi.border_check = bc;
6893 gtk_box_pack_start(GTK_BOX(hbox), bc, FALSE, FALSE, 5);
6894 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
6895
6896 /* feature outlines? */
6897 hbox = gtk_hbox_new(FALSE, 5);
6898 tmp = gtk_label_new(_("Feature border width:"));
6899 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
6900 if (gtk_combo_box_get_active(GTK_COMBO_BOX(com1)) == 0) {
6901 /* no payload selected */
6902 lw_min = 0.1;
6903 }
6904 lw = gtk_spin_button_new_with_range(lw_min, 2.0, 0.1);
6905 gtk_spin_button_set_value(GTK_SPIN_BUTTON(lw), 1.0);
6906 gi.linewidth_spin = lw;
6907 gtk_box_pack_start(GTK_BOX(hbox), lw, FALSE, FALSE, 5);
6908 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
6909
6910 /* height in pixels? */
6911 hbox = gtk_hbox_new(FALSE, 5);
6912 tmp = gtk_label_new(_("height in pixels:"));
6913 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
6914 hs = gtk_spin_button_new_with_range(300, 1000, 50);
6915 gtk_spin_button_set_value(GTK_SPIN_BUTTON(hs), 600);
6916 gi.height_spin = hs;
6917 gtk_box_pack_start(GTK_BOX(hbox), hs, FALSE, FALSE, 5);
6918 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
6919
6920 /* inter-connect controls */
6921 g_signal_connect(G_OBJECT(gi.payload_combo), "changed",
6922 G_CALLBACK(sensitize_map_controls), &gi);
6923
6924 /* buttons */
6925 hbox = gtk_dialog_get_action_area(GTK_DIALOG(dialog));
6926 cancel_delete_button(hbox, dialog);
6927 tmp = ok_button(hbox);
6928 g_signal_connect(G_OBJECT(tmp), "clicked",
6929 G_CALLBACK(geoplot_callback), &gi);
6930 gtk_widget_grab_default(tmp);
6931 context_help_button(hbox, MAPHELP);
6932
6933 gtk_widget_show_all(dialog);
6934
6935 return ret;
6936 }
6937
6938 struct tdisagg_info {
6939 int v; /* target series ID */
6940 int s; /* expansion factor */
6941 GtkWidget *name_entry; /* entry box for output name */
6942 GtkWidget *agg_combo; /* aggregation type */
6943 GtkWidget *cl_combo; /* chow-lin methods */
6944 GtkWidget *det_combo; /* chow-lin deterministics */
6945 GtkWidget *cov_combo; /* chow-lin covariates */
6946 GtkWidget *dn_combo; /* denton methods */
6947 GtkWidget *dp_combo; /* denton preliminary series */
6948 GtkWidget *plot_check; /* sanity-check plot? */
6949 GtkWidget *reg_check; /* regression results? */
6950 GtkWidget *dlg;
6951 };
6952
do_tdisagg(GtkWidget * w,struct tdisagg_info * tdi)6953 static void do_tdisagg (GtkWidget *w, struct tdisagg_info *tdi)
6954 {
6955 PRN *prn = NULL;
6956 GString *GSB = NULL;
6957 GString *GSC = NULL;
6958 gchar *agg, *xname = NULL;
6959 const gchar *yname, *str;
6960 int discard_x = 0;
6961 int idx, err;
6962
6963 GSB = g_string_new(NULL);
6964 GSC = g_string_new(NULL);
6965
6966 if (tdi->name_entry != NULL) {
6967 yname = gtk_entry_get_text(GTK_ENTRY(tdi->name_entry));
6968 } else {
6969 yname = dataset->varname[tdi->v];
6970 }
6971
6972 agg = combo_box_get_active_text(tdi->agg_combo);
6973 g_string_printf(GSB, "_(aggtype=\"%s\"", agg);
6974 g_free(agg);
6975
6976 if (gtk_widget_is_sensitive(tdi->cl_combo)) {
6977 idx = gtk_combo_box_get_active(GTK_COMBO_BOX(tdi->cl_combo));
6978 str = idx == 1 ? "fernandez" : "chow-lin";
6979 g_string_append_printf(GSB, ", method=\"%s\"", str);
6980 idx = gtk_combo_box_get_active(GTK_COMBO_BOX(tdi->det_combo));
6981 g_string_append_printf(GSB, ", det=%d", idx);
6982 if (gtk_widget_is_sensitive(tdi->cov_combo)) {
6983 xname = combo_box_get_active_text(tdi->cov_combo);
6984 discard_x = strcmp(xname, _("none")) == 0;
6985 }
6986 } else {
6987 idx = gtk_combo_box_get_active(GTK_COMBO_BOX(tdi->dn_combo));
6988 str = idx == 1 ? "denton-afd" : "denton-pfd";
6989 g_string_append_printf(GSB, ", method=\"%s\"", str);
6990 xname = combo_box_get_active_text(tdi->dp_combo);
6991 discard_x = strcmp(xname, _("constant")) == 0;
6992 }
6993
6994 if (xname != NULL) {
6995 if (discard_x || current_series_index(dataset, xname) < 0) {
6996 g_free(xname);
6997 xname = NULL;
6998 }
6999 }
7000
7001 if (button_is_active(tdi->plot_check)) {
7002 g_string_append(GSB, ", plot=1");
7003 }
7004 if (gtk_widget_is_sensitive(tdi->reg_check) &&
7005 button_is_active(tdi->reg_check)) {
7006 g_string_append(GSB, ", verbose=2");
7007 bufopen(&prn);
7008 }
7009 g_string_append(GSB, ")");
7010
7011 g_string_printf(GSC, "series %s = tdisagg(%s, %s, %d, %s)",
7012 yname, dataset->varname[tdi->v],
7013 xname != NULL ? xname : "null", tdi->s, GSB->str);
7014
7015 err = generate(GSC->str, dataset, GRETL_TYPE_ANY, OPT_NONE, prn);
7016 if (err) {
7017 gui_errmsg(err);
7018 gretl_print_destroy(prn);
7019 } else {
7020 lib_command_strcpy(GSC->str);
7021 record_command_verbatim();
7022 mark_dataset_as_modified();
7023 populate_varlist();
7024 if (prn != NULL) {
7025 view_buffer(prn, 78, 400, "tdisagg", PRINT, NULL);
7026 }
7027 }
7028
7029 g_string_free(GSC, TRUE);
7030 g_string_free(GSB, TRUE);
7031
7032 gtk_widget_destroy(tdi->dlg);
7033 }
7034
sensitize_chowlin(struct tdisagg_info * tdi,gboolean s)7035 static void sensitize_chowlin (struct tdisagg_info *tdi,
7036 gboolean s)
7037 {
7038 gtk_widget_set_sensitive(tdi->cl_combo, s);
7039 gtk_widget_set_sensitive(tdi->det_combo, s);
7040 if (tdi->cov_combo != NULL) {
7041 gtk_widget_set_sensitive(tdi->cov_combo, s);
7042 }
7043 }
7044
sensitize_denton(struct tdisagg_info * tdi,gboolean s)7045 static void sensitize_denton (struct tdisagg_info *tdi,
7046 gboolean s)
7047 {
7048 gtk_widget_set_sensitive(tdi->dn_combo, s);
7049 gtk_widget_set_sensitive(tdi->dp_combo, s);
7050 }
7051
tdisagg_switch_method(GtkToggleButton * tb,struct tdisagg_info * tdi)7052 static void tdisagg_switch_method (GtkToggleButton *tb,
7053 struct tdisagg_info *tdi)
7054 {
7055 gboolean s = gtk_toggle_button_get_active(tb);
7056
7057 sensitize_chowlin(tdi, s);
7058 sensitize_denton(tdi, !s);
7059 gtk_widget_set_sensitive(tdi->reg_check, s);
7060 }
7061
plausible_covariate_list(int v)7062 static GList *plausible_covariate_list (int v)
7063 {
7064 GList *list = NULL;
7065 int i;
7066
7067 for (i=dataset->v-1; i>0; i--) {
7068 if (i == v) {
7069 continue;
7070 }
7071 if (gretl_isstoch(dataset->t1, dataset->t2, dataset->Z[i])) {
7072 list = g_list_append(list, (gpointer) dataset->varname[i]);
7073 }
7074 }
7075
7076 return list;
7077 }
7078
td_pattern(const double * x,int t1,int t2,int pd)7079 static int td_pattern (const double *x, int t1, int t2, int pd)
7080 {
7081 int t, i, err = 0;
7082
7083 for (t=t1; t<=t2 && !err; t+=pd) {
7084 /* the first obs per period must be valid */
7085 if (na(x[t])) {
7086 err = E_MISSDATA;
7087 }
7088 /* subsequent values must be NA or the same
7089 as the first */
7090 for (i=1; i<pd; i++) {
7091 if (!na(x[t+i]) && x[t+i] != x[t+i-1]) {
7092 err = E_DATA;
7093 }
7094 }
7095 }
7096
7097 return err;
7098 }
7099
7100 /* Try to figure the expansion factor for temporal
7101 disaggregation candidate series @v. Return 0 if
7102 this doesn't work.
7103 */
7104
tdisagg_expansion(int v)7105 static int tdisagg_expansion (int v)
7106 {
7107 int opd = series_get_orig_pd(dataset, v);
7108 int s = 0;
7109
7110 if (opd > 0) {
7111 /* series is pre-approved */
7112 s = dataset->pd / opd;
7113 } else {
7114 const double *x = dataset->Z[v];
7115 int t1 = dataset->t1;
7116 int t2 = dataset->t2;
7117 int pd = dataset->pd;
7118 int sub, err;
7119
7120 series_adjust_sample(x, &t1, &t2);
7121 date_maj_min(t1, dataset, NULL, &sub);
7122 if (sub > 1) {
7123 /* advance to first sub-period */
7124 t1 += pd - sub + 1;
7125 }
7126 err = td_pattern(x, t1, t2, pd);
7127 if (err && pd == 12) {
7128 /* monthly dataset: try for quarterly series */
7129 pd = 3;
7130 err = td_pattern(x, t1, t2, pd);
7131 }
7132 if (!err) {
7133 s = pd;
7134 } else if (err == E_DATA) {
7135 errbox_printf(_("The series %s seems to be of the same frequency "
7136 "as the current dataset"), dataset->varname[v]);
7137 } else {
7138 gui_errmsg(err);
7139 }
7140 }
7141
7142 return s;
7143 }
7144
tdisagg_dialog(int v)7145 void tdisagg_dialog (int v)
7146 {
7147 const char *aggs[] = {
7148 "sum", "avg", "first", "last"
7149 };
7150 struct tdisagg_info tdi = {0};
7151 GtkWidget *dialog, *com, *hbox;
7152 GtkWidget *vbox, *tmp;
7153 GtkWidget *rb1, *rb2;
7154 GtkWidget *entry;
7155 GList *xlist = NULL;
7156 GSList *group = NULL;
7157 int i, s;
7158
7159 if (maybe_raise_dialog()) {
7160 return;
7161 }
7162
7163 s = tdisagg_expansion(v);
7164 if (s == 0) {
7165 return;
7166 }
7167
7168 dialog = gretl_dialog_new("gretl: temporal disaggregation",
7169 NULL, GRETL_DLG_BLOCK);
7170 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
7171
7172 tdi.dlg = dialog;
7173 tdi.v = v;
7174 tdi.s = s;
7175
7176 xlist = plausible_covariate_list(v);
7177
7178 /* output name */
7179 hbox = gtk_hbox_new(FALSE, 5);
7180 tmp = gtk_label_new(_("Output name:"));
7181 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
7182 tdi.name_entry = entry = gtk_entry_new();
7183 gtk_entry_set_max_length(GTK_ENTRY(entry), 31);
7184 gtk_entry_set_width_chars(GTK_ENTRY(entry), 16);
7185 gtk_entry_set_text(GTK_ENTRY(entry), dataset->varname[v]);
7186 gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, FALSE, 5);
7187 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
7188 tmp = gtk_hseparator_new();
7189 gtk_box_pack_start(GTK_BOX(vbox), tmp, FALSE, FALSE, 5);
7190
7191 /* aggregation type */
7192 hbox = gtk_hbox_new(FALSE, 5);
7193 tmp = gtk_label_new(_("Aggregation type:"));
7194 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
7195 tdi.agg_combo = com = gtk_combo_box_text_new();
7196 gtk_box_pack_start(GTK_BOX(hbox), com, FALSE, FALSE, 5);
7197 for (i=0; i<4; i++) {
7198 combo_box_append_text(com, aggs[i]);
7199 }
7200 gtk_combo_box_set_active(GTK_COMBO_BOX(com), 0);
7201 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
7202 tmp = gtk_hseparator_new();
7203 gtk_box_pack_start(GTK_BOX(vbox), tmp, FALSE, FALSE, 5);
7204
7205 /* Regression vs Denton radio buttons */
7206 rb1 = gtk_radio_button_new_with_label(group, _("Regression based"));
7207 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(rb1));
7208 rb2 = gtk_radio_button_new_with_label(group, "Denton");
7209
7210 /* Regression */
7211 hbox = gtk_hbox_new(FALSE, 5);
7212 gtk_box_pack_start(GTK_BOX(hbox), rb1, FALSE, FALSE, 5);
7213 tdi.cl_combo = com = gtk_combo_box_text_new();
7214 gtk_box_pack_start(GTK_BOX(hbox), com, FALSE, FALSE, 5);
7215 combo_box_append_text(com, "Chow-Lin");
7216 combo_box_append_text(com, "Fernández");
7217 gtk_combo_box_set_active(GTK_COMBO_BOX(com), 0);
7218 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
7219
7220 hbox = gtk_hbox_new(FALSE, 5);
7221 tmp = gtk_label_new(_("Deterministic terms:"));
7222 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
7223 tdi.det_combo = com = gtk_combo_box_text_new();
7224 gtk_box_pack_start(GTK_BOX(hbox), com, FALSE, FALSE, 5);
7225 combo_box_append_text(com, _("none"));
7226 combo_box_append_text(com, _("constant"));
7227 combo_box_append_text(com, _("constant plus trend"));
7228 gtk_combo_box_set_active(GTK_COMBO_BOX(com), 1);
7229 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
7230
7231 xlist = g_list_prepend(xlist, (gpointer) _("none"));
7232 hbox = gtk_hbox_new(FALSE, 5);
7233 tmp = gtk_label_new(_("Covariate:"));
7234 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
7235 tdi.cov_combo = com = gtk_combo_box_text_new();
7236 set_combo_box_strings_from_list(com, xlist);
7237 gtk_box_pack_start(GTK_BOX(hbox), com, FALSE, FALSE, 5);
7238 gtk_combo_box_set_active(GTK_COMBO_BOX(com), 0);
7239 gtk_widget_set_sensitive(com, g_list_length(xlist) > 1);
7240 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
7241
7242 tmp = gtk_hseparator_new();
7243 gtk_box_pack_start(GTK_BOX(vbox), tmp, FALSE, FALSE, 5);
7244
7245 /* denton radio */
7246 hbox = gtk_hbox_new(FALSE, 5);
7247 gtk_box_pack_start(GTK_BOX(hbox), rb2, FALSE, FALSE, 5);
7248 tdi.dn_combo = com = gtk_combo_box_text_new();
7249 gtk_box_pack_start(GTK_BOX(hbox), com, FALSE, FALSE, 5);
7250 combo_box_append_text(com, _("proportional"));
7251 combo_box_append_text(com, _("additive"));
7252 gtk_combo_box_set_active(GTK_COMBO_BOX(com), 0);
7253 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
7254
7255 xlist = g_list_prepend(xlist, (gpointer) "constant");
7256 hbox = gtk_hbox_new(FALSE, 5);
7257 tmp = gtk_label_new(_("Preliminary series:"));
7258 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
7259 tdi.dp_combo = com = gtk_combo_box_text_new();
7260 set_combo_box_strings_from_list(com, xlist);
7261 gtk_box_pack_start(GTK_BOX(hbox), com, FALSE, FALSE, 5);
7262 gtk_combo_box_set_active(GTK_COMBO_BOX(com), 0);
7263 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
7264
7265 tmp = gtk_hseparator_new();
7266 gtk_box_pack_start(GTK_BOX(vbox), tmp, FALSE, FALSE, 5);
7267
7268 /* sensitivity */
7269 sensitize_denton(&tdi, FALSE);
7270 g_signal_connect(G_OBJECT(rb1), "toggled",
7271 G_CALLBACK(tdisagg_switch_method), &tdi);
7272
7273 /* show plot? */
7274 hbox = gtk_hbox_new(FALSE, 5);
7275 tdi.plot_check = tmp = gtk_check_button_new_with_label(_("show plot"));
7276 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tmp), FALSE);
7277 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
7278 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
7279
7280 /* show regression results? (Not for Denton) */
7281 hbox = gtk_hbox_new(FALSE, 5);
7282 tdi.reg_check = tmp =
7283 gtk_check_button_new_with_label(_("show regression results"));
7284 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tmp), FALSE);
7285 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
7286 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
7287
7288 /* buttons */
7289 hbox = gtk_dialog_get_action_area(GTK_DIALOG(dialog));
7290 cancel_delete_button(hbox, dialog);
7291 tmp = ok_button(hbox);
7292 g_signal_connect(G_OBJECT(tmp), "clicked",
7293 G_CALLBACK(do_tdisagg), &tdi);
7294 gtk_widget_grab_default(tmp);
7295 context_help_button(hbox, TDISAGG);
7296
7297 gtk_widget_show_all(dialog);
7298 }
7299
7300 /* apparatus for BDS nonlinearity test from menu */
7301
7302 struct bds_info {
7303 int vnum; /* ID of series to test */
7304 GtkWidget *dlg; /* the dialog widget */
7305 GtkWidget *src; /* source or parent of dialog */
7306 GtkWidget *mspin; /* spin button for order/max dimension */
7307 GtkWidget *sdb; /* radio button for interpretation of eps */
7308 GtkWidget *cspin; /* spin button for eps a la Kanzler */
7309 GtkWidget *sspin; /* spin button for eps = multiple of s.d. */
7310 GtkWidget *boot; /* radio button for bootstrapped P-values */
7311 };
7312
record_bdstest(int m,int v,gretlopt opt,double dval,int boot,GtkWidget * modelwin)7313 static void record_bdstest (int m, int v, gretlopt opt, double dval,
7314 int boot, GtkWidget *modelwin)
7315 {
7316 const char *dstr[2] = {"corr1", "sdcrit"};
7317 GString *gs = g_string_new("bds ");
7318 int i = (opt == OPT_C)? 0 : 1;
7319
7320 if (modelwin != NULL) {
7321 lib_command_strcpy("# series residual = $uhat");
7322 record_command_verbatim();
7323 }
7324
7325 g_string_append_printf(gs, "%d %s ", m, dataset->varname[v]);
7326 gretl_push_c_numeric_locale();
7327 g_string_append_printf(gs, "--%s=%g ", dstr[i], dval);
7328 gretl_pop_c_numeric_locale();
7329 g_string_append_printf(gs, "--boot=%d", boot);
7330
7331 lib_command_strcpy(gs->str);
7332 record_command_verbatim();
7333 g_string_free(gs, TRUE);
7334 }
7335
do_bdstest(GtkWidget * w,struct bds_info * bi)7336 static void do_bdstest (GtkWidget *w, struct bds_info *bi)
7337 {
7338 gretlopt dopt, opt = OPT_B;
7339 int m = spinner_get_int(bi->mspin);
7340 int sdcrit = button_is_active(bi->sdb);
7341 int boot = button_is_active(bi->boot);
7342 double dval;
7343 PRN *prn = NULL;
7344
7345 if (sdcrit) {
7346 dval = gtk_spin_button_get_value(GTK_SPIN_BUTTON(bi->sspin));
7347 dopt = OPT_S;
7348 } else {
7349 dval = gtk_spin_button_get_value(GTK_SPIN_BUTTON(bi->cspin));
7350 dopt = OPT_C;
7351 }
7352
7353 opt |= dopt;
7354 set_optval_double(BDS, dopt, dval);
7355 set_optval_int(BDS, OPT_B, boot);
7356
7357 bufopen(&prn);
7358
7359 if (prn != NULL) {
7360 int list[2] = {1, bi->vnum};
7361 int err = 0;
7362
7363 err = bds_test_driver(m, list, dataset, opt, prn);
7364 if (err) {
7365 gui_errmsg(err);
7366 gretl_print_destroy(prn);
7367 } else {
7368 view_buffer(prn, 78, 400, "bds", PRINT, NULL);
7369 record_bdstest(m, bi->vnum, dopt, dval, boot, bi->src);
7370 }
7371 }
7372
7373 gtk_widget_destroy(bi->dlg);
7374 }
7375
switch_bds_mode(GtkToggleButton * b,struct bds_info * bi)7376 static void switch_bds_mode (GtkToggleButton *b, struct bds_info *bi)
7377 {
7378 int sdcrit = gtk_toggle_button_get_active(b);
7379
7380 gtk_widget_set_sensitive(bi->sspin, sdcrit);
7381 gtk_widget_set_sensitive(bi->cspin, !sdcrit);
7382 }
7383
bdstest_dialog(int v,GtkWidget * parent)7384 void bdstest_dialog (int v, GtkWidget *parent)
7385 {
7386 struct bds_info bi = {0};
7387 GtkWidget *dialog, *hbox;
7388 GtkWidget *vbox, *label;
7389 GtkWidget *rb1, *tmp;
7390 GtkWidget *tbl;
7391 GSList *group = NULL;
7392
7393 if (maybe_raise_dialog()) {
7394 return;
7395 }
7396
7397 dialog = gretl_dialog_new("gretl: BDS test", parent, GRETL_DLG_BLOCK);
7398 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
7399
7400 bi.vnum = v;
7401 bi.dlg = dialog;
7402 bi.src = parent;
7403
7404 /* maximum dimension control */
7405 hbox = gtk_hbox_new(FALSE, 5);
7406 label = gtk_label_new(_("Maximum dimension:"));
7407 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
7408 bi.mspin = gtk_spin_button_new_with_range(2, 10, 1);
7409 gtk_box_pack_start(GTK_BOX(hbox), bi.mspin, FALSE, FALSE, 5);
7410 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
7411
7412 vbox_add_hsep(vbox);
7413
7414 /* distance controls */
7415 hbox = gtk_hbox_new(FALSE, 5);
7416 label = gtk_label_new(_("Criterion for closeness:"));
7417 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
7418 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
7419 tbl = gtk_table_new(2, 2, FALSE);
7420 /* via correlation */
7421 rb1 = gtk_radio_button_new_with_label(NULL, _("First-order correlation"));
7422 gtk_table_attach_defaults(GTK_TABLE(tbl), rb1, 0, 1, 0, 1);
7423 bi.cspin = tmp = gtk_spin_button_new_with_range(0.1, 0.9, .01);
7424 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tmp), 0.7);
7425 gtk_table_attach_defaults(GTK_TABLE(tbl), tmp, 1, 2, 0, 1);
7426 /* via s.d. */
7427 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(rb1));
7428 bi.sdb = gtk_radio_button_new_with_label(group, _("Multiple of std. dev."));
7429 gtk_table_attach_defaults(GTK_TABLE(tbl), bi.sdb, 0, 1, 1, 2);
7430 bi.sspin = tmp = gtk_spin_button_new_with_range(0.1, 4.0, .01);
7431 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tmp), 1.5);
7432 gtk_table_attach_defaults(GTK_TABLE(tbl), tmp, 1, 2, 1, 2);
7433 gtk_box_pack_start(GTK_BOX(vbox), tbl, FALSE, FALSE, 0);
7434 gtk_widget_set_sensitive(bi.sspin, FALSE);
7435 g_signal_connect(G_OBJECT(bi.sdb), "toggled",
7436 G_CALLBACK(switch_bds_mode), &bi);
7437
7438 vbox_add_hsep(vbox);
7439
7440 /* p-value type control */
7441 hbox = gtk_hbox_new(FALSE, 5);
7442 rb1 = gtk_radio_button_new_with_label(NULL, _("Asymptotic p-values"));
7443 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(rb1));
7444 gtk_box_pack_start(GTK_BOX(hbox), rb1, FALSE, FALSE, 5);
7445 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
7446 hbox = gtk_hbox_new(FALSE, 5);
7447 bi.boot = tmp = gtk_radio_button_new_with_label(group, _("Bootstrap p-values"));
7448 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
7449 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
7450 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tmp), dataset->n < 600);
7451
7452 /* buttons */
7453 hbox = gtk_dialog_get_action_area(GTK_DIALOG(dialog));
7454 cancel_delete_button(hbox, dialog);
7455 tmp = ok_button(hbox);
7456 g_signal_connect(G_OBJECT(tmp), "clicked",
7457 G_CALLBACK(do_bdstest), &bi);
7458 gtk_widget_grab_default(tmp);
7459 context_help_button(hbox, BDS);
7460
7461 gtk_widget_show_all(dialog);
7462 }
7463
7464 struct regls_options {
7465 gretl_bundle *parms;
7466 GtkWidget *dlg;
7467 GtkWidget *c[3];
7468 GtkWidget *b[4];
7469 };
7470
set_regls_options(GtkWidget * w,struct regls_options * ro)7471 static void set_regls_options (GtkWidget *w, struct regls_options *ro)
7472 {
7473 int use_1se, set_seed;
7474 int lccd, rccd, timer;
7475 double seed;
7476
7477 lccd = gtk_combo_box_get_active(GTK_COMBO_BOX(ro->c[0]));
7478 rccd = gtk_combo_box_get_active(GTK_COMBO_BOX(ro->c[1]));
7479 use_1se = gtk_combo_box_get_active(GTK_COMBO_BOX(ro->c[2]));
7480 set_seed = button_is_active(ro->b[0]);
7481 timer = button_is_active(ro->b[3]);
7482
7483 gretl_bundle_set_int(ro->parms, "lccd", lccd);
7484 gretl_bundle_set_int(ro->parms, "rccd", rccd);
7485 gretl_bundle_set_int(ro->parms, "use_1se", use_1se);
7486 gretl_bundle_set_int(ro->parms, "set_seed", set_seed);
7487 gretl_bundle_set_int(ro->parms, "timer", timer);
7488
7489 #ifdef HAVE_MPI
7490 int no_mpi = !button_is_active(ro->b[2]);
7491 gretl_bundle_set_int(ro->parms, "no_mpi", no_mpi);
7492 #endif
7493
7494 if (set_seed) {
7495 seed = gtk_spin_button_get_value(GTK_SPIN_BUTTON(ro->b[1]));
7496 gretl_bundle_set_scalar(ro->parms, "seed", seed);
7497 }
7498
7499 gtk_widget_destroy(ro->dlg);
7500 }
7501
regls_advanced_dialog(gretl_bundle * b,GtkWidget * parent)7502 void regls_advanced_dialog (gretl_bundle *b, GtkWidget *parent)
7503 {
7504 struct regls_options ro = {0};
7505 const char *anames[] = {
7506 N_("LASSO algorithm:"),
7507 N_("RIDGE algorithm:")
7508 };
7509 const char *lopts[] = {"ADMM", "CCD"};
7510 const char *ropts[] = {"SVD", "CCD"};
7511 const char **opts;
7512 GtkWidget *dialog, *vbox, *hbox, *w;
7513 double seed;
7514 int use_1se, set_seed;
7515 int lccd, rccd, timer;
7516 #ifdef HAVE_MPI
7517 int no_mpi = 0;
7518 #endif
7519 int i;
7520
7521 dialog = gretl_dialog_new("gretl: regls options", parent, GRETL_DLG_BLOCK);
7522 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
7523
7524 ro.dlg = dialog;
7525 ro.parms = b;
7526
7527 lccd = gretl_bundle_get_int(b, "lccd", NULL);
7528 rccd = gretl_bundle_get_int(b, "rccd", NULL);
7529 use_1se = gretl_bundle_get_int(b, "use_1se", NULL);
7530 timer = gretl_bundle_get_int(b, "timer", NULL);
7531 set_seed = gretl_bundle_get_int(b, "set_seed", NULL);
7532 seed = gretl_bundle_get_scalar(b, "seed", NULL);
7533 #ifdef HAVE_MPI
7534 no_mpi = gretl_bundle_get_int(b, "no_mpi", NULL);
7535 #endif
7536
7537 /* algorithms for LASSO, Ridge */
7538 for (i=0; i<2; i++) {
7539 hbox = gtk_hbox_new(FALSE, 5);
7540 w = gtk_label_new(_(anames[i]));
7541 gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 5);
7542 ro.c[i] = gtk_combo_box_text_new();
7543 opts = (i == 1)? ropts : lopts;
7544 combo_box_append_text(ro.c[i], opts[0]);
7545 combo_box_append_text(ro.c[i], opts[1]);
7546 gtk_combo_box_set_active(GTK_COMBO_BOX(ro.c[i]), (i == 1)? rccd : lccd);
7547 gtk_box_pack_start(GTK_BOX(hbox), ro.c[i], FALSE, FALSE, 5);
7548 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
7549 }
7550
7551 /* optimization criterion */
7552 hbox = gtk_hbox_new(FALSE, 5);
7553 w = gtk_label_new(_("cross validation criterion"));
7554 gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 5);
7555 ro.c[i] = gtk_combo_box_text_new();
7556 combo_box_append_text(ro.c[i], _("minimized MSE"));
7557 combo_box_append_text(ro.c[i], _("one-standard-error rule"));
7558 gtk_combo_box_set_active(GTK_COMBO_BOX(ro.c[i]), use_1se);
7559 gtk_box_pack_start(GTK_BOX(hbox), ro.c[i], FALSE, FALSE, 5);
7560 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
7561
7562 /* seed */
7563 hbox = gtk_hbox_new(FALSE, 5);
7564 ro.b[0] = gtk_check_button_new_with_label(_("set seed for random folds"));
7565 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ro.b[0]), set_seed);
7566 gtk_box_pack_start(GTK_BOX(hbox), ro.b[0], FALSE, FALSE, 5);
7567 ro.b[1] = gtk_spin_button_new_with_range(1, (gdouble) UINT_MAX, 1);
7568 gtk_entry_set_width_chars(GTK_ENTRY(ro.b[1]), 10);
7569 gtk_spin_button_set_value(GTK_SPIN_BUTTON(ro.b[1]), seed);
7570 gtk_spin_button_set_increments(GTK_SPIN_BUTTON(ro.b[1]), 1, 100000);
7571 gtk_widget_set_sensitive(ro.b[1], set_seed);
7572 sensitize_conditional_on(ro.b[1], ro.b[0]);
7573 gtk_box_pack_start(GTK_BOX(hbox), ro.b[1], FALSE, FALSE, 5);
7574 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
7575
7576 #ifdef HAVE_MPI
7577 /* MPI switch */
7578 hbox = gtk_hbox_new(FALSE, 5);
7579 ro.b[2] = gtk_check_button_new_with_label(_("use MPI if available"));
7580 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ro.b[2]), !no_mpi);
7581 gtk_box_pack_start(GTK_BOX(hbox), ro.b[2], FALSE, FALSE, 5);
7582 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
7583 #endif
7584
7585 /* timer */
7586 hbox = gtk_hbox_new(FALSE, 5);
7587 ro.b[3] = gtk_check_button_new_with_label(_("show execution time"));
7588 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ro.b[3]), timer);
7589 gtk_box_pack_start(GTK_BOX(hbox), ro.b[3], FALSE, FALSE, 5);
7590 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
7591
7592 /* buttons */
7593 hbox = gtk_dialog_get_action_area(GTK_DIALOG(dialog));
7594 cancel_delete_button(hbox, dialog);
7595 w = ok_button(hbox);
7596 g_signal_connect(G_OBJECT(w), "clicked",
7597 G_CALLBACK(set_regls_options), &ro);
7598 gtk_widget_grab_default(w);
7599 context_help_button(hbox, REGLS_ADV);
7600
7601 gtk_widget_show_all(dialog);
7602 }
7603