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 /* selector.c for gretl */
21
22 #include "gretl.h"
23 #include "selector.h"
24 #include "dlgutils.h"
25 #include "menustate.h"
26 #include "fileselect.h"
27 #include "fnsave.h"
28 #include "treeutils.h"
29 #include "toolbar.h"
30 #include "winstack.h"
31 #include "tabwin.h"
32 #include "lagpref.h"
33 #include "fncall.h"
34 #include "textbuf.h"
35
36 #include "var.h"
37 #include "gretl_func.h"
38 #include "libset.h"
39 #include "uservar.h"
40 #include "johansen.h"
41 #include "gretl_bfgs.h"
42 #include "gretl_midas.h"
43
44 /* for graphical selector buttons */
45 #include "arrows.h"
46
47 #if 0
48 # include "bootstrap.h"
49 #endif
50
51 #define LDEBUG 0
52 #define VLDEBUG 0
53
54 enum {
55 SR_LVARS = 1,
56 SR_RVARS1,
57 SR_RVARS2,
58 SR_LVARS2
59 };
60
61 #define N_EXTRA 8
62
63 struct _selector {
64 GtkWidget *parent;
65 GtkWidget *dlg;
66 GtkWidget *vbox;
67 GtkWidget *action_area;
68 GtkWidget *lvars;
69 GtkWidget *lvars2;
70 GtkWidget *table;
71 GtkWidget *depvar;
72 GtkWidget *rvars1;
73 GtkWidget *rvars2;
74 GtkWidget *default_check;
75 GtkWidget *add_button;
76 GtkWidget *remove_button;
77 GtkWidget *lags_button;
78 GtkWidget *hess_button;
79 GtkWidget *x12a_button;
80 GtkWidget *xdiff_button;
81 GtkWidget *hccme_button;
82 GtkWidget *extra[N_EXTRA];
83 int ci;
84 int blocking;
85 int active_var;
86 int error;
87 int n_left;
88 int state_pushed;
89 int row;
90 int n_rows;
91 gretlopt opts;
92 char *cmdlist;
93 size_t cmdsize;
94 size_t cmdlen;
95 gpointer data;
96 gpointer extra_data;
97 int (*callback)();
98 };
99
100 enum {
101 COL_ID = 0,
102 COL_LAG,
103 COL_NAME,
104 COL_FLAG
105 };
106
107 enum {
108 MCOL_M = 1,
109 MCOL_NAME,
110 MCOL_MINLAG,
111 MCOL_MAXLAG,
112 MCOL_TYPE,
113 MCOL_K
114 };
115
116 enum {
117 ARMA_p,
118 ARIMA_d,
119 ARMA_q,
120 ARMA_plist,
121 ARMA_qlist,
122 ARMA_P,
123 ARIMA_D,
124 ARMA_Q
125 };
126
127 enum {
128 REGLS_EST,
129 REGLS_ALPHA,
130 REGLS_LAMVAL,
131 REGLS_NLAM,
132 REGLS_NFOLDS,
133 REGLS_FTYPE,
134 REGLS_PLOT
135 };
136
137 #define EXTRA_LAGS (N_EXTRA - 1)
138
139 #define VNAME_WIDTH 18
140 #define BUTTON_WIDTH 64
141
142 /* single-equation estimation commands plus some GUI extensions */
143 #define MODEL_CODE(c) (MODEL_COMMAND(c) || c == PANEL_WLS || c == PANEL_B || \
144 c == OLOGIT || c == OPROBIT || c == REPROBIT || \
145 c == MLOGIT || c == IV_LIML || c == IV_GMM || \
146 c == COUNTMOD || c == REGLS || c == FE_LOGISTIC)
147
148 #define MODEL_NEEDS_X(c) (MODEL_CODE(c) && !(c == ARMA || c == GARCH))
149
150 #define IV_MODEL(c) (c == IVREG || c == IV_LIML || c == IV_GMM)
151
152 #define NONPARAM_CODE(c) (c == LOESS || c == NADARWAT)
153
154 #define COINT_CODE(c) (c == COINT || c == COINT2)
155
156 #define VEC_CODE(c) (c == COINT || c == COINT2 || c == VAR || \
157 c == VECM || c == VLAGSEL)
158
159 #define VEC_MODEL_CODE(c) (c == VAR || c == VECM || c == VLAGSEL)
160
161 #define VECLAGS_CODE(c) (c == VAR || c == VECM)
162
163 #define ADDVAR_CODE(c) (c == LOGS || c == LAGS || c == SQUARE || \
164 c == DIFF || c == LDIFF)
165
166 #define TWO_VARS_CODE(c) (c == ELLIPSE || c == XCORRGM || c == QQPLOT)
167
168 #define THREE_VARS_CODE(c) (c == GR_DUMMY || c == GR_XYZ || \
169 c == GR_3D || c == ANOVA)
170
171 #define FNPKG_CODE(c) (c == SAVE_FUNCTIONS || c == EDIT_FUNCTIONS)
172
173 #define SHOW_LISTS_CODE(c) (c == SUMMARY || c == CORR || c == MAHAL || c == PCA)
174
175 #define LIST_USE_INTS(c) (c == ELLIPSE || c == SAVE_FUNCTIONS)
176
177 #define WANT_TOGGLES(c) (c == DPANEL || \
178 c == ARMA || \
179 c == COINT || \
180 c == COINT2 || \
181 c == CORR || \
182 c == GARCH || \
183 c == HECKIT || \
184 c == HSK || \
185 c == BIPROBIT || \
186 c == INTREG || \
187 c == IVREG || \
188 c == LOGIT || \
189 c == OLOGIT || \
190 c == MLOGIT || \
191 c == LOGISTIC || \
192 c == MPOLS || \
193 c == OLS || \
194 c == PANEL || \
195 c == PANEL_WLS || \
196 c == PANEL_B || \
197 c == FE_LOGISTIC || \
198 c == COUNTMOD || \
199 c == DURATION || \
200 c == PROBIT || \
201 c == OPROBIT || \
202 c == REPROBIT || \
203 c == QUANTREG || \
204 c == MIDASREG || \
205 c == TOBIT || \
206 c == VAR || \
207 c == VECM || \
208 c == VLAGSEL || \
209 c == WLS || \
210 c == GR_BOX || \
211 c == XTAB)
212
213 #define USE_VECXLIST(c) (c == VAR || c == VLAGSEL || c == VECM || \
214 c == COINT2)
215
216 #define USE_RXLIST(c) (c == VECM || c == COINT2)
217
218 #define AUX_LAST(c) (c == IVREG || \
219 c == IV_LIML || \
220 c == IV_GMM || \
221 c == HECKIT || \
222 c == BIPROBIT || \
223 c == VAR || \
224 c == VLAGSEL || \
225 c == VECM || \
226 c == COINT2 || \
227 c == MIDASREG || \
228 c == SAVE_FUNCTIONS || \
229 c == EDIT_FUNCTIONS)
230
231 #define USE_ZLIST(c) (c == IVREG || c == IV_LIML || c == IV_GMM || \
232 c == HECKIT || c == BIPROBIT)
233
234 #define RHS_PREFILL(c) (c == CORR || \
235 c == MAHAL || \
236 c == PCA || \
237 c == SUMMARY || \
238 c == XTAB)
239
240 #define dataset_lags_ok(d) ((d)->structure == TIME_SERIES || \
241 (d)->structure == SPECIAL_TIME_SERIES || \
242 (d)->structure == STACKED_TIME_SERIES)
243
244 #define select_lags_primary(c) (MODEL_CODE(c))
245
246 #define select_lags_depvar(c) (MODEL_CODE(c) && c != ARMA && \
247 c != DPANEL && c != MIDASREG)
248
249 /* Should we have a lags button associated with auxiliary
250 variable selector? */
251
252 #define select_lags_aux(c) (c == VAR || c == VLAGSEL || c == VECM || \
253 c == IVREG || c == IV_LIML || c == IV_GMM || \
254 c == HECKIT || c == BIPROBIT)
255
256 #define list_lag_special(i) (i < -1)
257
258 /* static state variables */
259
260 static int default_y = -1;
261 static int want_seasonals = 0;
262 static int default_order;
263 static int vartrend = 0;
264 static int varconst = 1;
265 static int lags_hidden;
266 static int arma_p = 1;
267 static int arma_P = 0;
268 static int arima_d = 0;
269 static int arima_D = 0;
270 static int arma_q = 1;
271 static int arma_Q = 0;
272 static int garch_p = 1;
273 static int garch_q = 1;
274 static int arma_const = 1;
275 static int garch_const = 1;
276 static int arma_x12 = 0;
277 static int arma_hessian = 1;
278 static int arima_xdiff = 1;
279 static int selvar;
280 static int y2var;
281 static int offvar;
282 static int censvar;
283 static int jrank = 1;
284 static int jcase = J_UNREST_CONST;
285 static int verbose;
286 static int lovar;
287 static int hivar;
288 static int wtvar;
289 static int np_xvar;
290 static char lp_pvals;
291
292 static char dpd_2step;
293 static char dpd_asy;
294 static char dpd_dpd;
295 static char dpd_p;
296
297 static int y_x_lags_enabled;
298 static int y_w_lags_enabled;
299
300 static int *xlist;
301 static int *instlist;
302 static int *veclist;
303 static int *vecxlist;
304
305 static char *arlags;
306 static char *malags;
307 static char cluster_var[VNAMELEN];
308
309 static double tobit_lo = 0;
310 static double tobit_hi = NADBL;
311
312 static char mds_listname[VNAMELEN];
313 static int mds_quad[4] = {0, 0, 1, 2};
314 static int mds_order = 1;
315
316 static gretlopt model_opt;
317
318 static GtkWidget *multiplot_label;
319 static GtkWidget *multiplot_menu;
320
321 static gretl_bundle *regls_adv;
322
323 static selector *open_selector;
324
325 static gint listvar_reorder_click (GtkWidget *widget, GdkEventButton *event,
326 gpointer data);
327 static gint lvars_right_click (GtkWidget *widget, GdkEventButton *event,
328 selector *sr);
329 static gint listvar_flagcol_click (GtkWidget *widget, GdkEventButton *event,
330 gpointer data);
331 static gint listvar_midas_click (GtkWidget *widget, GdkEventButton *event,
332 selector *sr);
333 static int list_show_var (int v, int ci, int show_lags);
334 static void available_functions_list (selector *sr);
335 static void primary_rhs_varlist (selector *sr);
336 static gboolean lags_dialog_driver (GtkWidget *w, selector *sr);
337 static void call_iters_dialog (GtkWidget *w, GtkWidget *combo);
338 static void reset_arma_spinners (selector *sr);
339 static void clear_midas_spec (void);
340 static int check_midas_rvars2 (GtkTreeModel *model, gboolean *have_beta1);
341
set_or_get_n_rvars1(selector * sr,int n)342 static int set_or_get_n_rvars1 (selector *sr, int n)
343 {
344 static int nv;
345
346 if (n >= 0) {
347 nv = n;
348 if (sr != NULL && sr->ci == CORR && sr->extra[0] != NULL) {
349 gtk_widget_set_sensitive(sr->extra[0], n > 2);
350 }
351 }
352
353 return nv;
354 }
355
set_n_rvars1(selector * sr,int n)356 static void set_n_rvars1 (selector *sr, int n)
357 {
358 set_or_get_n_rvars1(sr, n);
359 }
360
get_n_rvars1(void)361 static int get_n_rvars1 (void)
362 {
363 return set_or_get_n_rvars1(NULL, -1);
364 }
365
want_combo(selector * sr)366 static int want_combo (selector *sr)
367 {
368 return (sr->ci == ARMA ||
369 sr->ci == VECM ||
370 sr->ci == COINT ||
371 sr->ci == COINT2 ||
372 sr->ci == COUNTMOD ||
373 sr->ci == DURATION ||
374 sr->ci == IV_GMM ||
375 sr->ci == EXPORT);
376 }
377
want_radios(selector * sr)378 static int want_radios (selector *sr)
379 {
380 int c = sr->ci;
381 int ret = 0;
382
383 if (c == PANEL || c == SCATTERS || c == AR1 ||
384 c == LOGIT || c == PROBIT || c == HECKIT ||
385 c == XTAB || c == PCA ||
386 c == QUANTREG || c == DPANEL ||
387 c == LOGISTIC || c == FE_LOGISTIC ||
388 c == VAROMIT || c == REGLS) {
389 ret = 1;
390 } else if (c == ADD || c == OMIT) {
391 windata_t *vwin = (windata_t *) sr->data;
392 MODEL *pmod = (MODEL *) vwin->data;
393
394 if (c == OMIT && pmod->ci == HECKIT) {
395 /* omit: Wald test only */
396 sr->opts |= OPT_W;
397 } else if (c == ADD && pmod->ci != OLS) {
398 /* add: LM option is OLS-only */
399 ret = 0;
400 } else {
401 ret = 1;
402 }
403 }
404
405 return ret;
406 }
407
selector_set_blocking(selector * sr,int modal)408 static void selector_set_blocking (selector *sr, int modal)
409 {
410 if (modal) {
411 gretl_set_window_modal(sr->dlg);
412 }
413 sr->blocking = 1;
414 gtk_main();
415 }
416
selection_at_max(selector * sr,int nsel)417 static int selection_at_max (selector *sr, int nsel)
418 {
419 return (TWO_VARS_CODE(sr->ci) && nsel == 2);
420 }
421
sr_get_lag_context(selector * sr,int locus)422 static int sr_get_lag_context (selector *sr, int locus)
423 {
424 int c = 0;
425
426 if (sr == NULL || !dataset_lags_ok(dataset)) {
427 return 0;
428 }
429
430 if (locus == SR_RVARS1 && select_lags_primary(sr->ci)) {
431 c = LAG_X;
432 } else if (locus == SR_RVARS2 && select_lags_aux(sr->ci)) {
433 c = (USE_ZLIST(sr->ci))? LAG_W : LAG_X;
434 }
435
436 return c;
437 }
438
lag_context_from_widget(GtkWidget * w)439 static int lag_context_from_widget (GtkWidget *w)
440 {
441 gint locus = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w), "locus"));
442 selector *sr = g_object_get_data(G_OBJECT(w), "sr");
443 int context = 0;
444
445 if (sr != NULL && locus) {
446 context = sr_get_lag_context(sr, locus);
447 }
448
449 return context;
450 }
451
452 /* note: @nx is exclusive of const and (lags of) dependent variable */
453
lags_button_relevant(selector * sr,int locus)454 static int lags_button_relevant (selector *sr, int locus)
455 {
456 if (sr->lags_button != NULL) {
457 if (locus == SR_RVARS1 && select_lags_primary(sr->ci)) {
458 return 1;
459 } else if (locus == SR_RVARS2 && select_lags_aux(sr->ci)) {
460 return 1;
461 }
462 }
463
464 return 0;
465 }
466
enable_lags_for_context(int context,gboolean s)467 void enable_lags_for_context (int context, gboolean s)
468 {
469 if (context == LAG_Y_X) {
470 y_x_lags_enabled = s;
471 } else if (context == LAG_Y_W) {
472 y_w_lags_enabled = s;
473 }
474 }
475
lags_enabled_for_context(int context)476 gboolean lags_enabled_for_context (int context)
477 {
478 if (context == LAG_Y_X) {
479 return y_x_lags_enabled;
480 } else if (context == LAG_Y_W) {
481 return y_w_lags_enabled;
482 } else {
483 return TRUE;
484 }
485 }
486
clear_selector(void)487 void clear_selector (void)
488 {
489 default_y = -1;
490 default_order = 0;
491 selvar = 0;
492 y2var = 0;
493 offvar = 0;
494 censvar = 0;
495 wtvar = 0;
496 np_xvar = 0;
497 vartrend = 0;
498 varconst = 1;
499 lovar = hivar = 0;
500
501 dpd_asy = dpd_2step = 0;
502 dpd_dpd = 0;
503 dpd_p = 1;
504
505 arma_p = 1;
506 arima_d = 0;
507 arma_q = 1;
508 arma_P = 0;
509 arima_D = 0;
510 arma_Q = 0;
511 arma_const = 1;
512 arma_hessian = 1;
513
514 garch_p = 1;
515 garch_q = 1;
516 garch_const = 1;
517
518 jrank = 1;
519 jcase = J_UNREST_CONST;
520
521 free(xlist);
522 xlist = NULL;
523 free(instlist);
524 instlist = NULL;
525
526 free(veclist);
527 veclist = NULL;
528 free(vecxlist);
529 vecxlist = NULL;
530
531 free(arlags);
532 arlags = NULL;
533 free(malags);
534 malags = NULL;
535
536 *cluster_var = '\0';
537
538 tobit_lo = 0;
539 tobit_hi = NADBL;
540
541 lp_pvals = 0;
542
543 clear_midas_spec();
544 destroy_lag_preferences();
545 call_iters_dialog(NULL, NULL);
546
547 if (open_selector != NULL) {
548 selector *sr = open_selector;
549
550 if (sr->ci == ARMA) {
551 reset_arma_spinners(sr);
552 }
553 }
554 }
555
selector_get_window(const selector * sr)556 GtkWidget *selector_get_window (const selector *sr)
557 {
558 return (sr != NULL)? sr->dlg : NULL;
559 }
560
561 static int presel;
562
selector_set_varnum(int v)563 void selector_set_varnum (int v)
564 {
565 presel = v;
566 }
567
modelspec_dialog(int ci)568 void modelspec_dialog (int ci)
569 {
570 selection_dialog(ci, _("gretl: specify model"), NULL, do_model);
571 }
572
varnum_from_keystring(MODEL * pmod,const char * key)573 static int varnum_from_keystring (MODEL *pmod, const char *key)
574 {
575 char *s = (char *) gretl_model_get_data(pmod, key);
576 int v = 0;
577
578 if (s != NULL && *s != '\0') {
579 v = series_index(dataset, s);
580 if (v == dataset->v) {
581 v = 0;
582 }
583 }
584
585 return v;
586 }
587
lag_list_from_mask(char * mask,int k)588 static int *lag_list_from_mask (char *mask, int k)
589 {
590 int *list;
591 int i, j;
592
593 list = gretl_list_new(k);
594
595 if (list != NULL) {
596 j = 1;
597 for (i=0; mask[i]; i++) {
598 if (mask[i] == '1') {
599 list[j++] = i + 1;
600 } else {
601 list[0] -= 1;
602 }
603 }
604 }
605
606 return list;
607 }
608
retrieve_arma_info(MODEL * pmod)609 static void retrieve_arma_info (MODEL *pmod)
610 {
611 int acode = gretl_model_get_int(pmod, "arma_flags");
612 int *laglist;
613 char *mask;
614
615 if (!(acode & ARMA_EXACT)) {
616 model_opt |= OPT_C;
617 }
618
619 if (acode & ARMA_X12A) {
620 arma_x12 = 1;
621 }
622
623 if (pmod->opt & OPT_G) {
624 /* use OPG for covariance matrix */
625 arma_hessian = 0;
626 }
627
628 if (pmod->opt & OPT_Y) {
629 /* don't difference ARIMAX regressors */
630 arima_xdiff = 0;
631 }
632
633 if (pmod->opt & OPT_L) {
634 model_opt |= OPT_L;
635 }
636
637 arma_p = arma_model_nonseasonal_AR_order(pmod);
638 arma_q = arma_model_nonseasonal_MA_order(pmod);
639 arima_d = gretl_model_get_int(pmod, "arima_d");
640 arma_P = gretl_model_get_int(pmod, "arma_P");
641 arma_Q = gretl_model_get_int(pmod, "arma_Q");
642 arima_D = gretl_model_get_int(pmod, "arima_D");
643 arma_const = pmod->ifc;
644
645 free(arlags);
646 arlags = NULL;
647
648 if (arma_p > 0) {
649 mask = (char *) gretl_model_get_data(pmod, "pmask");
650 if (mask != NULL) {
651 laglist = lag_list_from_mask(mask, arma_p);
652 if (laglist != NULL) {
653 arlags = gretl_list_to_numeric_string(laglist);
654 free(laglist);
655 }
656 }
657 }
658
659 free(malags);
660 malags = NULL;
661
662 if (arma_q > 0) {
663 mask = (char *) gretl_model_get_data(pmod, "qmask");
664 if (mask != NULL) {
665 laglist = lag_list_from_mask(mask, arma_q);
666 if (laglist != NULL) {
667 free(malags);
668 malags = gretl_list_to_numeric_string(laglist);
669 free(laglist);
670 }
671 }
672 }
673 }
674
retrieve_AR_lags_info(MODEL * pmod)675 static void retrieve_AR_lags_info (MODEL *pmod)
676 {
677 free(arlags);
678 arlags = NULL;
679
680 if (pmod->arinfo != NULL && pmod->arinfo->arlist != NULL) {
681 arlags = gretl_list_to_numeric_string(pmod->arinfo->arlist);
682 }
683 }
684
retrieve_heckit_info(MODEL * pmod,int * gotinst)685 static void retrieve_heckit_info (MODEL *pmod, int *gotinst)
686 {
687 int *zlist = gretl_model_get_secondary_list(pmod);
688
689 if (zlist != NULL) {
690 selvar = zlist[1];
691 free(instlist);
692 instlist = gretl_list_copy_from_pos(zlist, 2);
693 if (instlist != NULL) {
694 *gotinst = 1;
695 }
696 free(zlist);
697 }
698
699 if (pmod->opt & OPT_T) {
700 /* two-step estimation */
701 model_opt |= OPT_T;
702 }
703 }
704
retrieve_biprobit_info(MODEL * pmod,int * gotinst)705 static void retrieve_biprobit_info (MODEL *pmod, int *gotinst)
706 {
707 /* the biprobit list takes the form:
708 y1 y2 x1 ; x2
709 */
710 if (pmod->list != NULL && pmod->list[0] > 2) {
711 y2var = pmod->list[2];
712 }
713 free(instlist);
714 instlist = gretl_model_get_secondary_list(pmod);
715 *gotinst = instlist != NULL;
716 }
717
retrieve_tobit_info(MODEL * pmod)718 static void retrieve_tobit_info (MODEL *pmod)
719 {
720 double x0 = gretl_model_get_double(pmod, "llimit");
721 double x1 = gretl_model_get_double(pmod, "rlimit");
722
723 if (na(x0) && na(x1)) {
724 /* the standard set-up */
725 tobit_lo = 0;
726 tobit_hi = NADBL;
727 } else {
728 /* user-specified limits */
729 tobit_lo = x0;
730 tobit_hi = x1;
731 }
732 }
733
retrieve_midas_info(MODEL * pmod)734 static void retrieve_midas_info (MODEL *pmod)
735 {
736 gretl_bundle *b = NULL;
737 gretl_array *A;
738 int err = 0;
739
740 if (pmod->opt & OPT_L) {
741 model_opt |= OPT_L;
742 }
743
744 A = gretl_model_get_data(pmod, "midas_info");
745
746 if (A != NULL) {
747 b = gretl_array_get_bundle(A, 0);
748 }
749
750 if (b != NULL) {
751 strcpy(mds_listname, gretl_bundle_get_string(b, "lname", &err));
752 mds_quad[0] = gretl_bundle_get_int(b, "minlag", &err);
753 mds_quad[1] = gretl_bundle_get_int(b, "maxlag", &err);
754 mds_quad[2] = gretl_bundle_get_int(b, "type", &err);
755 mds_quad[3] = gretl_bundle_get_int(b, "nparm", &err);
756 }
757 }
758
759 /* support for the "Modify model..." Edit menu item */
760
selector_from_model(windata_t * vwin)761 void selector_from_model (windata_t *vwin)
762 {
763 void *ptr = vwin->data;
764 int ci = vwin->role;
765
766 model_opt = OPT_NONE;
767
768 if (ci == VIEW_MODEL) {
769 /* single-equation model (mostly) */
770 MODEL *pmod = (MODEL *) ptr;
771 int sel_ci = pmod->ci;
772 int cv, dv = -1, gotinst = 0;
773
774 if (pmod->ci == NLS || pmod->ci == MLE || pmod->ci == GMM) {
775 revise_nl_model(pmod, vwin_toplevel(vwin));
776 return;
777 }
778
779 if (pmod->ci == INTREG) {
780 lovar = varnum_from_keystring(pmod, "lovar");
781 hivar = varnum_from_keystring(pmod, "hivar");
782 } else {
783 dv = gretl_model_get_depvar(pmod);
784 if (dv >= 0 && dv < dataset->v) {
785 default_y = dv;
786 }
787 }
788
789 free(xlist);
790 xlist = gretl_model_get_x_list(pmod);
791
792 if (pmod->ci == WLS) {
793 wtvar = pmod->nwt;
794 } else if (pmod->ci == ARMA) {
795 retrieve_arma_info(pmod);
796 } else if (pmod->ci == GARCH) {
797 garch_p = pmod->list[1];
798 garch_q = pmod->list[2];
799 garch_const = pmod->ifc;
800 if (pmod->opt & OPT_F) {
801 model_opt |= OPT_F;
802 }
803 } else if (pmod->ci == HECKIT) {
804 retrieve_heckit_info(pmod, &gotinst);
805 } else if (COUNT_MODEL(pmod->ci)) {
806 if (pmod->ci == NEGBIN) {
807 if (pmod->opt & OPT_M) {
808 model_opt |= OPT_M;
809 } else {
810 model_opt |= OPT_N;
811 }
812 }
813 sel_ci = COUNTMOD;
814 offvar = gretl_model_get_int(pmod, "offset_var");
815 } else if (pmod->ci == DURATION) {
816 if (pmod->opt & OPT_E) {
817 model_opt |= OPT_E;
818 } else if (pmod->opt & OPT_L) {
819 model_opt |= OPT_L;
820 } else if (pmod->opt & OPT_Z) {
821 model_opt |= OPT_Z;
822 }
823 censvar = gretl_model_get_int(pmod, "cens_var");
824 } else if (pmod->ci == IVREG) {
825 free(instlist);
826 instlist = gretl_model_get_secondary_list(pmod);
827 if (instlist != NULL) {
828 gotinst = 1;
829 }
830 if (pmod->opt & OPT_L) {
831 sel_ci = IV_LIML;
832 } else if (pmod->opt & OPT_G) {
833 sel_ci = IV_GMM;
834 }
835 } else if (pmod->ci == ARCH) {
836 default_order = gretl_model_get_int(pmod, "arch_order");
837 } else if (pmod->ci == AR) {
838 retrieve_AR_lags_info(pmod);
839 } else if (pmod->ci == AR1) {
840 if (pmod->opt & OPT_P) {
841 model_opt |= OPT_P;
842 } else if (pmod->opt & OPT_H) {
843 model_opt |= OPT_H;
844 }
845 } else if (pmod->ci == PANEL) {
846 if (pmod->opt & OPT_F) {
847 model_opt |= OPT_F;
848 } else if (pmod->opt & OPT_U) {
849 model_opt |= OPT_U;
850 } else if (pmod->opt & OPT_H) {
851 sel_ci = PANEL_WLS;
852 } else if (pmod->opt & OPT_B) {
853 sel_ci = PANEL_B;
854 }
855 if (pmod->opt & OPT_D) {
856 model_opt |= OPT_D;
857 }
858 } else if (pmod->ci == DPANEL) {
859 if (pmod->opt & OPT_A) {
860 model_opt |= OPT_A;
861 }
862 if (pmod->opt & OPT_D) {
863 model_opt |= OPT_D;
864 }
865 if (pmod->opt & OPT_T) {
866 model_opt |= OPT_T;
867 }
868 if (pmod->opt & OPT_L) {
869 model_opt |= OPT_L;
870 }
871 if (pmod->opt & OPT_X) {
872 model_opt |= OPT_X;
873 }
874 } else if (pmod->ci == LAD) {
875 if (gretl_model_get_int(pmod, "rq")) {
876 sel_ci = QUANTREG;
877 }
878 /* FIXME replicate rq_tauvec? */
879 } else if (pmod->ci == LOGIT) {
880 if (gretl_model_get_int(pmod, "ordered")) {
881 sel_ci = OLOGIT;
882 } else if (gretl_model_get_int(pmod, "multinom")) {
883 sel_ci = MLOGIT;
884 }
885 } else if (pmod->ci == PROBIT) {
886 if (gretl_model_get_int(pmod, "ordered")) {
887 sel_ci = OPROBIT;
888 } else if (pmod->opt & OPT_E) {
889 sel_ci = REPROBIT;
890 }
891 } else if (pmod->ci == TOBIT) {
892 retrieve_tobit_info(pmod);
893 } else if (pmod->ci == BIPROBIT) {
894 retrieve_biprobit_info(pmod, &gotinst);
895 } else if (pmod->ci == MIDASREG) {
896 retrieve_midas_info(pmod);
897 } else if (pmod->ci == LOGISTIC) {
898 if (pmod->opt & OPT_F) {
899 sel_ci = FE_LOGISTIC;
900 }
901 }
902 if (pmod->opt & OPT_R) {
903 model_opt |= OPT_R;
904 }
905
906 *cluster_var = '\0';
907 cv = gretl_model_get_cluster_var(pmod);
908 if (cv > 0 && cv < dataset->v) {
909 model_opt |= OPT_C;
910 strcpy(cluster_var, dataset->varname[cv]);
911 }
912
913 y_x_lags_enabled = y_w_lags_enabled = 0;
914
915 if ((dataset_is_time_series(dataset) ||
916 dataset_is_panel(dataset)) &&
917 (xlist != NULL || gotinst)) {
918 set_lag_prefs_from_model(dv, xlist, instlist);
919 }
920
921 modelspec_dialog(sel_ci);
922 } else if (ci == VAR || ci == VECM) {
923 GRETL_VAR *var = (GRETL_VAR *) ptr;
924
925 varconst = (var->detflags & DET_CONST);
926 vartrend = (var->detflags & DET_TREND);
927 want_seasonals = (var->detflags & DET_SEAS);
928
929 if (var->robust) {
930 model_opt |= OPT_R;
931 }
932
933 free(veclist);
934 veclist = gretl_list_copy(var->ylist);
935
936 free(vecxlist);
937 vecxlist = NULL;
938
939 if (var->rlist != NULL) {
940 vecxlist = gretl_lists_join_with_separator(var->xlist,
941 var->rlist);
942 } else if (var->xlist != NULL) {
943 vecxlist = gretl_list_copy(var->xlist);
944 }
945
946 set_lag_prefs_from_VAR(var->lags, vecxlist);
947 default_order = var->order;
948
949 if (ci == VECM) {
950 jrank = gretl_VECM_rank(var);
951 jcase = jcode(var);
952 default_order += 1;
953 }
954
955 selection_dialog(ci, (ci == VAR)? _("gretl: VAR") : _("gretl: VECM"),
956 NULL, do_vector_model);
957 } else if (ci == SYSTEM) {
958 revise_system_model(ptr, vwin_toplevel(vwin));
959 }
960
961 model_opt = OPT_NONE;
962 }
963
964 #define UNRESTRICTED N_("U")
965 #define RESTRICTED N_("R")
966
967 static char varflag[8];
968
set_varflag(const char * s)969 static void set_varflag (const char *s)
970 {
971 *varflag = '\0';
972 strncat(varflag, s, 7);
973 }
974
selector_get_depvar_number(const selector * sr)975 int selector_get_depvar_number (const selector *sr)
976 {
977 int ynum = -1;
978
979 if (sr == NULL) {
980 sr = open_selector;
981 }
982
983 if (sr != NULL && sr->depvar != NULL) {
984 const char *s = gtk_entry_get_text(GTK_ENTRY(sr->depvar));
985
986 if (s != NULL && *s != '\0') {
987 ynum = series_index(dataset, s);
988 if (ynum == dataset->v) {
989 ynum = -1;
990 }
991 }
992 }
993
994 return ynum;
995 }
996
depvar_selected(const selector * sr)997 static int depvar_selected (const selector *sr)
998 {
999 return selector_get_depvar_number(sr) > 0;
1000 }
1001
1002 static gint dblclick_lvars_row (GtkWidget *w, GdkEventButton *event,
1003 selector *sr);
1004
1005 /* when adding a lag to the exogenous vars box for a VECM,
1006 see if we can find a previously added lag (or non-lag) of
1007 this variable, and if so use that to set the Restricted/
1008 Unrestricted flag on the newly added lag
1009 */
1010
set_varflag_from_parent(int v,int lag,GtkTreeModel * mod,GtkTreeIter * iter)1011 static void set_varflag_from_parent (int v, int lag, GtkTreeModel *mod,
1012 GtkTreeIter *iter)
1013 {
1014 GtkTreeIter piter;
1015 gchar *flag;
1016 gint pv, plag;
1017 int done = 0;
1018
1019 if (gtk_tree_model_get_iter_first(mod, &piter)) {
1020 while (1) {
1021 gtk_tree_model_get(mod, &piter, COL_ID, &pv, COL_LAG, &plag, -1);
1022 if (pv == v && plag != lag) {
1023 gtk_tree_model_get(mod, &piter, COL_FLAG, &flag, -1);
1024 gtk_list_store_set(GTK_LIST_STORE(mod), iter, COL_FLAG, flag, -1);
1025 done = 1;
1026 g_free(flag);
1027 break;
1028
1029 }
1030 if (!gtk_tree_model_iter_next(mod, &piter)) {
1031 break;
1032 }
1033 }
1034 }
1035
1036 if (!done) {
1037 gtk_list_store_set(GTK_LIST_STORE(mod), iter, COL_FLAG, varflag, -1);
1038 }
1039 }
1040
1041 static void
real_varlist_set_var(int v,int lag,GtkTreeModel * mod,GtkTreeIter * iter)1042 real_varlist_set_var (int v, int lag, GtkTreeModel *mod, GtkTreeIter *iter)
1043 {
1044 int ncols = gtk_tree_model_get_n_columns(mod);
1045 GtkListStore *store = GTK_LIST_STORE(mod);
1046
1047 if (lag == 0) {
1048 gtk_list_store_set(store, iter, COL_ID, v, COL_LAG, 0,
1049 COL_NAME, dataset->varname[v],
1050 -1);
1051 } else {
1052 char vstr[VNAMELEN + 8];
1053
1054 sprintf(vstr, "%s(-%d)", dataset->varname[v], lag);
1055 gtk_list_store_set(store, iter, COL_ID, v, COL_LAG, lag,
1056 COL_NAME, vstr, -1);
1057 }
1058
1059 if (ncols == 4) {
1060 if (lag == 0) {
1061 gtk_list_store_set(store, iter, COL_FLAG, varflag, -1);
1062 } else {
1063 set_varflag_from_parent(v, lag, mod, iter);
1064 }
1065 }
1066 }
1067
1068 static int
varlist_remove_var_full(int v,GtkTreeModel * mod,GtkTreeIter * iter)1069 varlist_remove_var_full (int v, GtkTreeModel *mod, GtkTreeIter *iter)
1070 {
1071 GtkTreeIter *last = iter;
1072 int row = -1, ok = 1;
1073 int tv, i = 0;
1074
1075 #if VLDEBUG
1076 fprintf(stderr, "\nvarlist_remove_var_full: looking for var %d (%s)\n", v,
1077 dataset->varname[v]);
1078 #endif
1079
1080 if (gtk_tree_model_get_iter_first(mod, iter)) {
1081 last = iter;
1082 while (1) {
1083 gtk_tree_model_get(mod, iter, COL_ID, &tv, -1);
1084 #if VLDEBUG
1085 fprintf(stderr, "row %d: checking against %d\n", i, tv);
1086 #endif
1087 if (tv == v) {
1088 ok = gtk_list_store_remove(GTK_LIST_STORE(mod), iter);
1089 #if VLDEBUG
1090 fprintf(stderr, "removed at row %d, now ok = %d\n", i, ok);
1091 #endif
1092 if (row < 0) {
1093 row = i;
1094 }
1095 if (ok) {
1096 continue;
1097 } else {
1098 break;
1099 }
1100 }
1101 if (!gtk_tree_model_iter_next(mod, iter)) {
1102 /* iter is now invalid */
1103 iter = last;
1104 break;
1105 }
1106 last = iter;
1107 i++;
1108 }
1109 } else {
1110 iter = last;
1111 }
1112
1113 return row;
1114 }
1115
1116 static void
varlist_insert_var_full(int v,GtkTreeModel * mod,GtkTreeIter * iter,selector * sr,int locus)1117 varlist_insert_var_full (int v, GtkTreeModel *mod, GtkTreeIter *iter,
1118 selector *sr, int locus)
1119 {
1120 int lcontext = 0;
1121
1122 #if VLDEBUG
1123 fprintf(stderr, "varlist_insert_var_full: starting var %d\n", v);
1124 #endif
1125
1126 if (v > 0 && dataset_lags_ok(dataset)) {
1127 lcontext = sr_get_lag_context(sr, locus);
1128 }
1129
1130 if (lcontext) {
1131 int *laglist = get_lag_pref_as_list(v, lcontext);
1132
1133 if (laglist != NULL) {
1134 int i, row, append = 0;
1135
1136 row = varlist_remove_var_full(v, mod, iter);
1137 if (row < 0) {
1138 append = 1;
1139 }
1140
1141 #if VLDEBUG
1142 fprintf(stderr, "got laglist, done prior removal, row=%d, append=%d\n",
1143 row, append);
1144 #endif
1145 for (i=1; i<=laglist[0]; i++) {
1146 if (append) {
1147 gtk_list_store_append(GTK_LIST_STORE(mod), iter);
1148 } else {
1149 gtk_list_store_insert(GTK_LIST_STORE(mod), iter, row++);
1150 }
1151 #if VLDEBUG
1152 fprintf(stderr, "adding var %d, lag %d\n", v, laglist[i]);
1153 #endif
1154 real_varlist_set_var(v, laglist[i], mod, iter);
1155 }
1156 free(laglist);
1157 } else {
1158 lcontext = 0;
1159 }
1160 }
1161
1162 if (lcontext == 0) {
1163 gtk_list_store_append(GTK_LIST_STORE(mod), iter);
1164 real_varlist_set_var(v, 0, mod, iter);
1165 }
1166 }
1167
set_active_var(GtkWidget * widget,GdkEventButton * event,selector * sr)1168 static gboolean set_active_var (GtkWidget *widget, GdkEventButton *event,
1169 selector *sr)
1170 {
1171 GtkTreeView *view = GTK_TREE_VIEW(widget);
1172 GtkTreeModel *model = gtk_tree_view_get_model(view);
1173 GtkTreePath *path;
1174
1175 if (gtk_tree_view_get_path_at_pos(view, event->x, event->y, &path,
1176 NULL, NULL, NULL)) {
1177 GtkTreeIter iter;
1178 gint varnum, row;
1179
1180 gtk_tree_model_get_iter(model, &iter, path);
1181 gtk_tree_model_get(model, &iter, COL_ID, &varnum, -1);
1182 if (sr != NULL) {
1183 sr->active_var = varnum;
1184 }
1185 row = tree_path_get_row_number(path);
1186 gtk_tree_path_free(path);
1187 /* note: the following is used in listbox_drag() */
1188 g_object_set_data(G_OBJECT(widget), "active_row",
1189 GINT_TO_POINTER(row));
1190 }
1191
1192 return FALSE;
1193 }
1194
list_append_var_simple(GtkListStore * store,GtkTreeIter * iterp,int v)1195 static void list_append_var_simple (GtkListStore *store,
1196 GtkTreeIter *iterp,
1197 int v)
1198 {
1199 const char *vname = dataset->varname[v];
1200
1201 gtk_list_store_append(store, iterp);
1202 gtk_list_store_set(store, iterp,
1203 COL_ID, v,
1204 COL_LAG, 0,
1205 COL_NAME, vname,
1206 -1);
1207 }
1208
list_append_var(GtkTreeModel * mod,GtkTreeIter * iter,int v,selector * sr,int locus)1209 static void list_append_var (GtkTreeModel *mod,
1210 GtkTreeIter *iter,
1211 int v, selector *sr,
1212 int locus)
1213 {
1214 int i, lcontext = 0;
1215
1216 if (v > 0 && dataset_lags_ok(dataset)) {
1217 lcontext = sr_get_lag_context(sr, locus);
1218 }
1219
1220 if (lcontext) {
1221 int *laglist = get_lag_pref_as_list(v, lcontext);
1222
1223 if (laglist != NULL) {
1224 for (i=1; i<=laglist[0]; i++) {
1225 gtk_list_store_append(GTK_LIST_STORE(mod), iter);
1226 real_varlist_set_var(v, laglist[i], mod, iter);
1227 }
1228 free(laglist);
1229 } else {
1230 lcontext = 0;
1231 }
1232 }
1233
1234 if (lcontext == 0) {
1235 gtk_list_store_append(GTK_LIST_STORE(mod), iter);
1236 real_varlist_set_var(v, 0, mod, iter);
1237 }
1238 }
1239
list_append_midas_var(GtkListStore * store,GtkTreeIter * iterp,int v,int m)1240 static void list_append_midas_var (GtkListStore *store,
1241 GtkTreeIter *iterp,
1242 int v, int m)
1243 {
1244 char mname[VNAMELEN];
1245 const char *vname;
1246 int ID = v;
1247
1248 vname = get_listname_by_consecutive_content(m, v);
1249
1250 if (vname != NULL) {
1251 /* got a pre-existing MIDAS list */
1252 strcpy(mname, vname);
1253 ID = -1;
1254 } else {
1255 /* got the "anchor" of a potential list */
1256 char *p;
1257
1258 vname = dataset->varname[v];
1259 strcpy(mname, vname);
1260 p = strrchr(mname, '_');
1261 if (p != NULL) {
1262 *p = '\0';
1263 }
1264 }
1265
1266 gtk_list_store_append(store, iterp);
1267 gtk_list_store_set(store, iterp,
1268 COL_ID, ID, MCOL_M, m,
1269 MCOL_NAME, mname, -1);
1270
1271 if (!strcmp(mname, mds_listname)) {
1272 /* FIXME */
1273 fprintf(stderr, "Should add %s on right?\n", mname);
1274 }
1275 }
1276
render_varname(GtkTreeViewColumn * column,GtkCellRenderer * renderer,GtkTreeModel * model,GtkTreeIter * iter,gpointer p)1277 static void render_varname (GtkTreeViewColumn *column,
1278 GtkCellRenderer *renderer,
1279 GtkTreeModel *model,
1280 GtkTreeIter *iter,
1281 gpointer p)
1282 {
1283 gint id;
1284
1285 gtk_tree_model_get(model, iter, COL_ID, &id, -1);
1286 if (id < 0) {
1287 g_object_set(renderer, "weight", PANGO_WEIGHT_BOLD, NULL);
1288 } else {
1289 g_object_set(renderer, "weight", PANGO_WEIGHT_NORMAL, NULL);
1290 }
1291 }
1292
1293 /* build a new liststore and associated tree view, and pack into the
1294 given @hbox */
1295
var_list_box_new(GtkBox * hbox,selector * sr,int locus)1296 static GtkWidget *var_list_box_new (GtkBox *hbox, selector *sr, int locus)
1297 {
1298 GtkListStore *store;
1299 GtkWidget *view, *scroller;
1300 GtkCellRenderer *renderer;
1301 GtkTreeViewColumn *column;
1302 GtkTreeSelection *select;
1303 gboolean flagcol = FALSE;
1304 gboolean midascol = FALSE;
1305 int cw, width = 160;
1306 int height = -1;
1307
1308 cw = get_char_width(sr->dlg);
1309 if (cw > 0) {
1310 width = 18 * cw;
1311 }
1312
1313 if (USE_RXLIST(sr->ci) && locus == SR_RVARS2) {
1314 /* VECM special, with restricted/unrestricted flag column */
1315 store = gtk_list_store_new(4, G_TYPE_INT, G_TYPE_INT,
1316 G_TYPE_STRING, G_TYPE_STRING);
1317 flagcol = TRUE;
1318 } else if (sr->ci == MIDASREG && locus == SR_RVARS2) {
1319 /* MIDAS special with parameterization info */
1320 store = gtk_list_store_new(7, G_TYPE_INT, G_TYPE_INT,
1321 G_TYPE_STRING, G_TYPE_INT,
1322 G_TYPE_INT, G_TYPE_INT,
1323 G_TYPE_INT);
1324 midascol = TRUE;
1325 } else {
1326 /* ID number, lag or frequency ratio, varname */
1327 store = gtk_list_store_new(3, G_TYPE_INT, G_TYPE_INT, G_TYPE_STRING);
1328 }
1329
1330 view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
1331 g_object_unref(G_OBJECT(store));
1332
1333 g_object_set_data(G_OBJECT(view), "sr", sr);
1334 g_object_set_data(G_OBJECT(view), "locus", GINT_TO_POINTER(locus));
1335
1336 renderer = gtk_cell_renderer_text_new();
1337 g_object_set(renderer, "ypad", 0, NULL);
1338 column = gtk_tree_view_column_new_with_attributes(NULL,
1339 renderer,
1340 "text",
1341 COL_NAME,
1342 NULL);
1343 gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
1344
1345 if (locus == SR_RVARS2 && sr->ci == MIDASREG) {
1346 gretl_tooltips_add(view, _("Select and right-click to edit specification"));
1347 }
1348
1349 if (flagcol) {
1350 column = gtk_tree_view_column_new_with_attributes(NULL,
1351 renderer,
1352 "text",
1353 COL_FLAG,
1354 NULL);
1355 gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
1356 } else {
1357 gtk_tree_view_column_set_cell_data_func(column, renderer,
1358 render_varname,
1359 NULL, NULL);
1360 }
1361
1362 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), FALSE);
1363 gtk_tree_view_set_reorderable(GTK_TREE_VIEW(view), FALSE);
1364
1365 select = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
1366
1367 if (locus == SR_LVARS2 || (locus == SR_RVARS2 && sr->ci == MIDASREG)) {
1368 gtk_tree_selection_set_mode(select, GTK_SELECTION_SINGLE);
1369 } else {
1370 gtk_tree_selection_set_mode(select, GTK_SELECTION_MULTIPLE);
1371 g_signal_connect(G_OBJECT(view), "motion-notify-event",
1372 G_CALLBACK(listbox_drag), NULL);
1373 }
1374
1375 /* enable interactive search on name */
1376 gtk_tree_view_set_search_column(GTK_TREE_VIEW(view), COL_NAME);
1377 gtk_tree_view_set_enable_search(GTK_TREE_VIEW(view), TRUE);
1378
1379 if (locus == SR_LVARS) {
1380 /* left-hand box with the selectable vars */
1381 g_signal_connect(G_OBJECT(view), "button-press-event",
1382 G_CALLBACK(lvars_right_click),
1383 sr);
1384 g_signal_connect(G_OBJECT(view), "button-press-event",
1385 G_CALLBACK(set_active_var),
1386 sr);
1387 g_signal_connect(G_OBJECT(view), "button-press-event",
1388 G_CALLBACK(dblclick_lvars_row),
1389 sr);
1390 } else if (locus == SR_RVARS1 || locus == SR_RVARS2) {
1391 /* lists of selected items */
1392 g_signal_connect(G_OBJECT(view), "button-press-event",
1393 G_CALLBACK(set_active_var),
1394 NULL);
1395 if (flagcol) {
1396 g_signal_connect(G_OBJECT(view), "button-press-event",
1397 G_CALLBACK(listvar_flagcol_click),
1398 view);
1399 } else if (midascol) {
1400 g_signal_connect(G_OBJECT(view), "button-press-event",
1401 G_CALLBACK(listvar_midas_click),
1402 sr);
1403 } else {
1404 g_signal_connect(G_OBJECT(view), "button-press-event",
1405 G_CALLBACK(listvar_reorder_click),
1406 view);
1407 }
1408 } else if (locus == SR_LVARS2) {
1409 g_signal_connect(G_OBJECT(view), "button-press-event",
1410 G_CALLBACK(lvars_right_click),
1411 sr);
1412 }
1413
1414 scroller = gtk_scrolled_window_new(NULL, NULL);
1415 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroller),
1416 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1417 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scroller),
1418 GTK_SHADOW_IN);
1419 gtk_container_add(GTK_CONTAINER(scroller), view);
1420
1421 gtk_box_pack_start(hbox, scroller, TRUE, TRUE, 0);
1422
1423 width *= gui_scale;
1424 gtk_widget_set_size_request(view, width, height);
1425 gtk_widget_show(view);
1426
1427 #if GTK_MAJOR_VERSION >= 3
1428 gtk_scrolled_window_set_min_content_width(GTK_SCROLLED_WINDOW(scroller),
1429 width);
1430 #endif
1431
1432 gtk_widget_show(scroller);
1433
1434 return view;
1435 }
1436
binary_var_check(int v,const char * vname)1437 static int binary_var_check (int v, const char *vname)
1438 {
1439 if (!gretl_isdummy(dataset->t1, dataset->t2, dataset->Z[v])) {
1440 errbox_printf(_("The variable '%s' is not a 0/1 variable."), vname);
1441 return 1;
1442 }
1443
1444 return 0;
1445 }
1446
1447 /* add to "extra" var slot the current selection from sr->lvars */
1448
real_set_extra_var(GtkTreeModel * model,GtkTreePath * path,GtkTreeIter * iter,selector * sr)1449 static void real_set_extra_var (GtkTreeModel *model, GtkTreePath *path,
1450 GtkTreeIter *iter, selector *sr)
1451 {
1452 gchar *vname;
1453 gint v;
1454
1455 gtk_tree_model_get(model, iter, COL_ID, &v, COL_NAME, &vname, -1);
1456
1457 if (v < 0) {
1458 return;
1459 }
1460
1461 if (sr->ci == HECKIT || sr->ci == BIPROBIT) {
1462 if (binary_var_check(v, vname)) {
1463 return;
1464 }
1465 } else if (NONPARAM_CODE(sr->ci)) {
1466 const gchar *test = gtk_entry_get_text(GTK_ENTRY(sr->depvar));
1467
1468 if (!strcmp(vname, test)) {
1469 /* can't have the same var in both places */
1470 gtk_entry_set_text(GTK_ENTRY(sr->depvar), "");
1471 }
1472 }
1473
1474 gtk_entry_set_text(GTK_ENTRY(sr->extra[0]), vname);
1475 g_free(vname);
1476 g_object_set_data(G_OBJECT(sr->extra[0]), "data",
1477 GINT_TO_POINTER(v));
1478 }
1479
set_extra_var_callback(GtkWidget * w,selector * sr)1480 static void set_extra_var_callback (GtkWidget *w, selector *sr)
1481 {
1482 GtkTreeSelection *selection;
1483
1484 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(sr->lvars));
1485 gtk_tree_selection_selected_foreach(selection,
1486 (GtkTreeSelectionForeachFunc)
1487 real_set_extra_var,
1488 sr);
1489 }
1490
real_set_third_var(GtkTreeModel * model,GtkTreePath * path,GtkTreeIter * iter,selector * sr)1491 static void real_set_third_var (GtkTreeModel *model, GtkTreePath *path,
1492 GtkTreeIter *iter, selector *sr)
1493 {
1494 gchar *vname = NULL;
1495 gint v;
1496
1497 gtk_tree_model_get(model, iter, COL_ID, &v, COL_NAME, &vname, -1);
1498
1499 if (v < 0) {
1500 g_free(vname);
1501 return;
1502 }
1503
1504 gtk_entry_set_text(GTK_ENTRY(sr->rvars1), vname);
1505 g_free(vname);
1506 g_object_set_data(G_OBJECT(sr->rvars1), "data",
1507 GINT_TO_POINTER(v));
1508 }
1509
set_third_var_callback(GtkWidget * w,selector * sr)1510 static void set_third_var_callback (GtkWidget *w, selector *sr)
1511 {
1512 GtkTreeSelection *selection;
1513
1514 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(sr->lvars));
1515 gtk_tree_selection_selected_foreach(selection,
1516 (GtkTreeSelectionForeachFunc)
1517 real_set_third_var,
1518 sr);
1519 }
1520
1521 /* When adding a variable to the Endogenous or Exogenous listing
1522 for VAR, VECM, etc., check that the variable in question is not
1523 present in the other listing: if it is, then remove it.
1524
1525 And similarly, when constructing a list of function interfaces
1526 for a package, don't allow selection of a given function as
1527 both a public interface and a private ("Helper") function.
1528 */
1529
dual_selection_fix_conflicts(selector * sr,int new_locus)1530 static void dual_selection_fix_conflicts (selector *sr, int new_locus)
1531 {
1532 GtkTreeModel *targ, *src;
1533 GtkTreeIter iter;
1534 gboolean ok;
1535 int *srclist = NULL;
1536 gint v;
1537
1538 if (new_locus == SR_RVARS1) {
1539 src = gtk_tree_view_get_model(GTK_TREE_VIEW(sr->rvars1));
1540 targ = gtk_tree_view_get_model(GTK_TREE_VIEW(sr->rvars2));
1541 } else {
1542 src = gtk_tree_view_get_model(GTK_TREE_VIEW(sr->rvars2));
1543 targ = gtk_tree_view_get_model(GTK_TREE_VIEW(sr->rvars1));
1544 }
1545
1546 /* construct list of vars in @src */
1547
1548 if (gtk_tree_model_get_iter_first(src, &iter)) {
1549 do {
1550 gtk_tree_model_get(src, &iter, COL_ID, &v, -1);
1551 gretl_list_append_term(&srclist, v);
1552 } while (gtk_tree_model_iter_next(src, &iter));
1553 }
1554
1555 /* check @srclist against @targ */
1556
1557 if (srclist != NULL && gtk_tree_model_get_iter_first(targ, &iter)) {
1558 do {
1559 ok = TRUE;
1560 gtk_tree_model_get(targ, &iter, COL_ID, &v, -1);
1561 if (in_gretl_list(srclist, v)) {
1562 ok = gtk_list_store_remove(GTK_LIST_STORE(targ), &iter);
1563 }
1564 } while (ok && gtk_tree_model_iter_next(targ, &iter));
1565 }
1566
1567 free(srclist);
1568 }
1569
1570 static void
maybe_insert_or_revise_depvar_lags(selector * sr,int v,int lcontext,int revise)1571 maybe_insert_or_revise_depvar_lags (selector *sr, int v, int lcontext,
1572 int revise)
1573 {
1574 int *laglist = NULL;
1575 GtkWidget *w;
1576 GtkTreeModel *mod;
1577 GtkTreeIter iter;
1578 int append = 1;
1579 int modv, row = 0;
1580 int jmin = 0, jmax = 1;
1581 int i, j;
1582
1583 if (lcontext == LAG_Y_X) {
1584 jmin = 0;
1585 jmax = 1;
1586 } else if (lcontext == LAG_Y_W) {
1587 /* instrument, not indep var */
1588 jmin = 1;
1589 jmax = 2;
1590 }
1591
1592 for (j=jmin; j<jmax; j++) {
1593
1594 w = (j > 0)? sr->rvars2: sr->rvars1;
1595 if (w == NULL) {
1596 return;
1597 }
1598
1599 mod = gtk_tree_view_get_model(GTK_TREE_VIEW(w));
1600
1601 if (lcontext == 0) {
1602 lcontext = (j > 0)? LAG_Y_W : LAG_Y_X;
1603 }
1604
1605 laglist = get_lag_pref_as_list(v, lcontext);
1606 if (laglist == NULL) {
1607 if (revise) {
1608 varlist_remove_var_full(v, mod, &iter);
1609 }
1610 return;
1611 }
1612
1613 varlist_remove_var_full(v, mod, &iter);
1614
1615 if (gtk_tree_model_get_iter_first(mod, &iter)) {
1616 do {
1617 gtk_tree_model_get(mod, &iter, COL_ID, &modv, -1);
1618 if (modv > 0) {
1619 append = 0;
1620 break;
1621 }
1622 row++;
1623 } while (gtk_tree_model_iter_next(mod, &iter));
1624 }
1625
1626 for (i=1; i<=laglist[0]; i++) {
1627 if (append) {
1628 gtk_list_store_append(GTK_LIST_STORE(mod), &iter);
1629 } else {
1630 gtk_list_store_insert(GTK_LIST_STORE(mod), &iter, row++);
1631 }
1632 #if VLDEBUG
1633 fprintf(stderr, "depvar_lags: adding var %d, lag %d\n", v, laglist[i]);
1634 #endif
1635 real_varlist_set_var(v, laglist[i], mod, &iter);
1636 }
1637
1638 free(laglist);
1639 }
1640 }
1641
maybe_insert_depvar_lags(selector * sr,int v,int lcontext)1642 static void maybe_insert_depvar_lags (selector *sr, int v, int lcontext)
1643 {
1644 maybe_insert_or_revise_depvar_lags(sr, v, lcontext, 0);
1645 }
1646
maybe_revise_depvar_lags(selector * sr,int v,int lcontext)1647 static void maybe_revise_depvar_lags (selector *sr, int v, int lcontext)
1648 {
1649 maybe_insert_or_revise_depvar_lags(sr, v, lcontext, 1);
1650 }
1651
remove_as_indep_var(selector * sr,gint v)1652 static void remove_as_indep_var (selector *sr, gint v)
1653 {
1654 GtkTreeView *view = GTK_TREE_VIEW(sr->rvars1);
1655 GtkTreeModel *model = gtk_tree_view_get_model(view);
1656 GtkTreeIter iter;
1657 gboolean ok;
1658 gint xnum;
1659
1660 if (gtk_tree_model_get_iter_first(model, &iter)) {
1661 do {
1662 ok = TRUE;
1663 gtk_tree_model_get(model, &iter, COL_ID, &xnum, -1);
1664 if (xnum == v) {
1665 ok = gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
1666 }
1667 } while (ok && gtk_tree_model_iter_next(model, &iter));
1668 }
1669 }
1670
dependent_var_cleanup(selector * sr,int newy)1671 static void dependent_var_cleanup (selector *sr, int newy)
1672 {
1673 int oldy = selector_get_depvar_number(sr);
1674
1675 if (GTK_IS_TREE_VIEW(sr->rvars1) && oldy != newy) {
1676 if (oldy > 0) {
1677 remove_as_indep_var(sr, oldy); /* lags business */
1678 }
1679 y_x_lags_enabled = 0;
1680 y_w_lags_enabled = 0;
1681 remove_as_indep_var(sr, newy);
1682 }
1683 }
1684
np_xvar_cleanup(selector * sr,int newy)1685 static void np_xvar_cleanup (selector *sr, int newy)
1686 {
1687 const gchar *test = gtk_entry_get_text(GTK_ENTRY(sr->extra[0]));
1688
1689 if (test != NULL && *test != '\0') {
1690 int xv = current_series_index(dataset, test);
1691
1692 if (xv == newy) {
1693 gtk_entry_set_text(GTK_ENTRY(sr->extra[0]), "");
1694 }
1695 }
1696 }
1697
set_dependent_var_from_active(selector * sr)1698 static int set_dependent_var_from_active (selector *sr)
1699 {
1700 gint v = sr->active_var;
1701 const char *vname;
1702
1703 if (v < 0 || v >= dataset->v || sr->depvar == NULL) {
1704 return 1;
1705 }
1706
1707 vname = dataset->varname[v];
1708
1709 if (sr->ci == PROBIT || sr->ci == BIPROBIT) {
1710 if (binary_var_check(v, vname)) {
1711 return 1;
1712 }
1713 }
1714
1715 /* models: if we select foo as regressand, remove it from the list
1716 of regressors if need be; also remove lags associated with the
1717 previous dependent var, if any.
1718 */
1719 if (MODEL_CODE(sr->ci)) {
1720 dependent_var_cleanup(sr, v);
1721 } else if (NONPARAM_CODE(sr->ci)) {
1722 np_xvar_cleanup(sr, v);
1723 }
1724
1725 gtk_entry_set_text(GTK_ENTRY(sr->depvar), vname);
1726
1727 if (select_lags_depvar(sr->ci)) {
1728 maybe_insert_depvar_lags(sr, v, 0);
1729 }
1730
1731 return 0;
1732 }
1733
real_set_dependent_var(GtkTreeModel * model,GtkTreePath * path,GtkTreeIter * iter,selector * sr)1734 static void real_set_dependent_var (GtkTreeModel *model, GtkTreePath *path,
1735 GtkTreeIter *iter, selector *sr)
1736 {
1737 gchar *vname;
1738 gint v;
1739
1740 gtk_tree_model_get(model, iter, COL_ID, &v, COL_NAME, &vname, -1);
1741
1742 if (v < 0) {
1743 return;
1744 }
1745
1746 if (sr->ci == PROBIT || sr->ci == BIPROBIT) {
1747 if (binary_var_check(v, vname)) {
1748 return;
1749 }
1750 }
1751
1752 if (MODEL_CODE(sr->ci)) {
1753 dependent_var_cleanup(sr, v);
1754 }
1755
1756 gtk_entry_set_text(GTK_ENTRY(sr->depvar), vname);
1757
1758 if (select_lags_depvar(sr->ci)) {
1759 maybe_insert_depvar_lags(sr, v, 0);
1760 }
1761 }
1762
set_dependent_var_callback(GtkWidget * w,selector * sr)1763 static void set_dependent_var_callback (GtkWidget *w, selector *sr)
1764 {
1765 GtkTreeSelection *selection;
1766
1767 if (sr->depvar == NULL) return;
1768
1769 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(sr->lvars));
1770 gtk_tree_selection_selected_foreach(selection,
1771 (GtkTreeSelectionForeachFunc)
1772 real_set_dependent_var,
1773 sr);
1774 }
1775
set_right_var_from_main(GtkTreeModel * model,GtkTreePath * path,GtkTreeIter * iter,selector * sr)1776 static void set_right_var_from_main (GtkTreeModel *model, GtkTreePath *path,
1777 GtkTreeIter *iter, selector *sr)
1778 {
1779 GtkTreeModel *rmod;
1780 GtkTreeIter r_iter;
1781 gchar *idstr = NULL;
1782 int v;
1783
1784 gtk_tree_model_get(model, iter, COL_ID, &idstr, -1);
1785
1786 rmod = gtk_tree_view_get_model(GTK_TREE_VIEW(sr->rvars1));
1787 if (rmod == NULL) {
1788 g_free(idstr);
1789 return;
1790 }
1791
1792 v = atoi(idstr);
1793
1794 if (gtk_tree_model_get_iter_first(rmod, &r_iter)) {
1795 while (gtk_tree_model_iter_next(rmod, &r_iter)) {
1796 ;
1797 }
1798 }
1799
1800 gtk_list_store_append(GTK_LIST_STORE(rmod), &r_iter);
1801 real_varlist_set_var(v, 0, rmod, &r_iter);
1802
1803 g_free(idstr);
1804 }
1805
set_vars_from_main(selector * sr)1806 static void set_vars_from_main (selector *sr)
1807 {
1808 GtkTreeSelection *selection;
1809
1810 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(mdata->listbox));
1811 gtk_tree_selection_selected_foreach(selection,
1812 (GtkTreeSelectionForeachFunc)
1813 set_right_var_from_main,
1814 sr);
1815 }
1816
1817 /* Append a specified variable in the SR_RVARS1 locus: used when
1818 saving data and there's only one variable to save.
1819 */
1820
select_singleton(selector * sr)1821 static void select_singleton (selector *sr)
1822 {
1823 GtkTreeModel *lmod, *rmod;
1824 GtkTreeIter iter;
1825 int v;
1826
1827 lmod = gtk_tree_view_get_model(GTK_TREE_VIEW(sr->lvars));
1828 if (lmod == NULL) {
1829 return;
1830 }
1831
1832 rmod = gtk_tree_view_get_model(GTK_TREE_VIEW(sr->rvars1));
1833 if (rmod == NULL) {
1834 return;
1835 }
1836
1837 gtk_tree_model_get_iter_first(lmod, &iter);
1838 gtk_tree_model_get(lmod, &iter, COL_ID, &v, -1);
1839
1840 gtk_tree_model_get_iter_first(rmod, &iter);
1841 gtk_list_store_append(GTK_LIST_STORE(rmod), &iter);
1842 gtk_list_store_set(GTK_LIST_STORE(rmod), &iter,
1843 COL_ID, v, COL_LAG, 0,
1844 COL_NAME, dataset->varname[v], -1);
1845 }
1846
varflag_dialog(int v,GtkWidget * parent)1847 static int varflag_dialog (int v, GtkWidget *parent)
1848 {
1849 const char *opts[] = {
1850 N_("Unrestricted"),
1851 N_("Restricted")
1852 };
1853 gchar *title, *label;
1854 int ret;
1855
1856 title = g_strdup_printf("gretl: %s", _("add exogenous variable"));
1857 label = g_strdup_printf(_("Status of '%s' in VECM:"), dataset->varname[v]);
1858
1859 ret = radio_dialog(title, label, opts, 2, 0, 0, parent);
1860 if (ret == 0) {
1861 set_varflag(UNRESTRICTED);
1862 } else if (ret == 1) {
1863 set_varflag(RESTRICTED);
1864 }
1865
1866 g_free(title);
1867 g_free(label);
1868
1869 return ret;
1870 }
1871
arima_selected(selector * sr)1872 static int arima_selected (selector *sr)
1873 {
1874 int ret = 0;
1875
1876 if (sr->extra[ARIMA_d] != NULL) {
1877 /* the arima_d spinner */
1878 ret = spinner_get_int(sr->extra[ARIMA_d]);
1879 }
1880
1881 if (!ret && sr->extra[ARIMA_D] != NULL) {
1882 /* the seasonal arima_D spinner */
1883 ret = spinner_get_int(sr->extra[ARIMA_D]);
1884 }
1885
1886 return ret;
1887 }
1888
xdiff_button_set_sensitive(selector * sr,gboolean s)1889 static void xdiff_button_set_sensitive (selector *sr, gboolean s)
1890 {
1891 if (sr->xdiff_button != NULL) {
1892 s = s && arima_selected(sr);
1893 gtk_widget_set_sensitive(sr->xdiff_button, s);
1894 }
1895 }
1896
rvars1_n_vars(selector * sr)1897 static int rvars1_n_vars (selector *sr)
1898 {
1899 GtkTreeModel *model;
1900 GtkTreeIter iter;
1901 int nv = 0;
1902
1903 model = gtk_tree_view_get_model(GTK_TREE_VIEW(sr->rvars1));
1904 if (model == NULL) {
1905 return 0;
1906 }
1907
1908 if (gtk_tree_model_get_iter_first(model, &iter)) {
1909 do {
1910 nv++;
1911 } while (gtk_tree_model_iter_next(model, &iter));
1912 }
1913
1914 return nv;
1915 }
1916
1917 /* add a variable (or possibly a list of variables) to the listbox
1918 at @locus */
1919
real_add_generic(GtkTreeModel * srcmodel,GtkTreeIter * srciter,selector * sr,int locus)1920 static void real_add_generic (GtkTreeModel *srcmodel,
1921 GtkTreeIter *srciter,
1922 selector *sr,
1923 int locus)
1924 {
1925 GtkWidget *w;
1926 GtkTreeModel *model;
1927 GtkTreeIter iter;
1928 gchar *vname = NULL;
1929 const int *vlist = NULL;
1930 gint v, xnum;
1931 gint at_max = 0;
1932 gint keep_names = 0;
1933 int i, addvars = 1;
1934 int nvars = 0;
1935 int err = 0;
1936
1937 w = (locus == SR_RVARS2)? sr->rvars2 : sr->rvars1;
1938
1939 if (!GTK_IS_TREE_VIEW(w)) {
1940 return;
1941 }
1942
1943 model = gtk_tree_view_get_model(GTK_TREE_VIEW(w));
1944 if (model == NULL) {
1945 return;
1946 }
1947
1948 /* get the 'source' info */
1949 gtk_tree_model_get(srcmodel, srciter, COL_ID, &v, COL_NAME, &vname, -1);
1950
1951 if (v < 0) {
1952 /* we should have a gretl list, not a single variable */
1953 vlist = get_list_by_name(vname);
1954 if (vlist == NULL) {
1955 err = E_DATA;
1956 } else {
1957 addvars = vlist[0];
1958 }
1959 } else {
1960 keep_names =
1961 GPOINTER_TO_INT(g_object_get_data(G_OBJECT(sr->lvars),
1962 "keep-names"));
1963 }
1964
1965 if (err) {
1966 gui_errmsg(err);
1967 return;
1968 }
1969
1970 if (!keep_names) {
1971 g_free(vname);
1972 vname = NULL;
1973 }
1974
1975 for (i=0; i<addvars && !at_max; i++) {
1976 int already_there = 0;
1977
1978 if (vlist != NULL) {
1979 v = vlist[i+1];
1980 }
1981
1982 /* first check if we're maxed out, or if the variable to
1983 add is already present */
1984
1985 if (gtk_tree_model_get_iter_first(model, &iter)) {
1986 do {
1987 if (i == 0 && selection_at_max(sr, ++nvars)) {
1988 at_max = 1;
1989 }
1990 if (!at_max && !already_there) {
1991 gtk_tree_model_get(model, &iter, COL_ID, &xnum, -1);
1992 if (xnum == v) {
1993 already_there = 1;
1994 }
1995 }
1996 } while (gtk_tree_model_iter_next(model, &iter));
1997 }
1998
1999 if (!already_there && !at_max) {
2000 /* OK to append */
2001 if (keep_names) {
2002 int ncols = gtk_tree_model_get_n_columns(model);
2003
2004 gtk_list_store_append(GTK_LIST_STORE(model), &iter);
2005 gtk_list_store_set(GTK_LIST_STORE(model), &iter,
2006 COL_ID, v, COL_LAG, 0, COL_NAME, vname, -1);
2007 if (ncols == 4) {
2008 gtk_list_store_set(GTK_LIST_STORE(model), &iter,
2009 COL_FLAG, varflag, -1);
2010 }
2011 g_free(vname);
2012 } else {
2013 if (locus == SR_RVARS2 && USE_RXLIST(sr->ci)) {
2014 if (varflag_dialog(v, sr->dlg) < 0) {
2015 return;
2016 }
2017 }
2018 #if VLDEBUG
2019 fprintf(stderr, "real_add_generic: calling varlist_insert_var_full\n");
2020 #endif
2021 varlist_insert_var_full(v, model, &iter, sr, locus);
2022 }
2023
2024 if (selection_at_max(sr, ++nvars)) {
2025 at_max = 1;
2026 }
2027 }
2028 }
2029
2030 if (sr->add_button != NULL && at_max) {
2031 gtk_widget_set_sensitive(sr->add_button, FALSE);
2032 }
2033
2034 if (locus == SR_RVARS1 && sr->ci == CORR) {
2035 set_n_rvars1(sr, nvars);
2036 }
2037
2038 if (nvars > 0) {
2039 if (lags_button_relevant(sr, locus)) {
2040 gtk_widget_set_sensitive(sr->lags_button, TRUE);
2041 } else if (VECLAGS_CODE(sr->ci) && locus == SR_RVARS1 &&
2042 sr->extra[EXTRA_LAGS] != NULL) {
2043 gtk_widget_set_sensitive(sr->extra[EXTRA_LAGS], TRUE);
2044 }
2045 if (sr->ci == ARMA) {
2046 xdiff_button_set_sensitive(sr, TRUE);
2047 }
2048 if (USE_VECXLIST(sr->ci) || FNPKG_CODE(sr->ci)) {
2049 dual_selection_fix_conflicts(sr, locus);
2050 }
2051 }
2052 }
2053
2054 /* shift a MIDAS term from one location in the selection
2055 dialog to another */
2056
move_midas_term(GtkTreeModel * src,GtkTreeIter * srciter,selector * sr)2057 static void move_midas_term (GtkTreeModel *src,
2058 GtkTreeIter *srciter,
2059 selector *sr)
2060 {
2061 GtkTreeModel *targ;
2062 GtkTreeIter iter;
2063 gchar *vname = NULL;
2064 int v, m, src_cols;
2065
2066 /* get the 'source' info */
2067 gtk_tree_model_get(src, srciter,
2068 COL_ID, &v, MCOL_M, &m,
2069 MCOL_NAME, &vname, -1);
2070
2071 /* append to target */
2072 src_cols = gtk_tree_model_get_n_columns(src);
2073 if (src_cols == 3) {
2074 /* going left to right (selecting): defaults */
2075 gboolean have_beta1 = 0;
2076 gboolean no_beta1 = 0;
2077 int lmin = 1, lmax = 2*m;
2078 int ptype = mds_quad[2];
2079 int k = mds_quad[3];
2080 int nterms;
2081
2082 if (mds_quad[0] < mds_quad[1]) {
2083 lmin = mds_quad[0];
2084 lmax = mds_quad[1];
2085 }
2086
2087 targ = gtk_tree_view_get_model(GTK_TREE_VIEW(sr->rvars2));
2088
2089 /* If we have a beta1 term in place on the right,
2090 don't allow adding anything else. And if there's
2091 anything in place already, don't allow adding a
2092 beta1 term.
2093 */
2094 nterms = check_midas_rvars2(targ, &have_beta1);
2095 if (have_beta1) {
2096 warnbox("A one-parameter beta term cannot be combined with others");
2097 return;
2098 } else if (nterms > 0) {
2099 no_beta1 = 1;
2100 }
2101
2102 if (midas_term_dialog(vname, m, &lmin, &lmax, &ptype,
2103 &k, no_beta1, sr->dlg) < 0) {
2104 return;
2105 }
2106 gtk_list_store_append(GTK_LIST_STORE(targ), &iter);
2107 gtk_list_store_set(GTK_LIST_STORE(targ), &iter,
2108 COL_ID, v, MCOL_M, m, MCOL_NAME, vname,
2109 MCOL_MINLAG, lmin, MCOL_MAXLAG, lmax,
2110 MCOL_TYPE, ptype, MCOL_K, k,
2111 -1);
2112 } else {
2113 /* going right to left (deselecting) */
2114 targ = gtk_tree_view_get_model(GTK_TREE_VIEW(sr->lvars2));
2115 gtk_list_store_append(GTK_LIST_STORE(targ), &iter);
2116 gtk_list_store_set(GTK_LIST_STORE(targ), &iter,
2117 COL_ID, v, MCOL_M, m,
2118 MCOL_NAME, vname, -1);
2119 }
2120
2121 g_free(vname);
2122
2123 /* and remove from source */
2124 gtk_list_store_remove(GTK_LIST_STORE(src), srciter);
2125 }
2126
add_to_rvars1(GtkTreeModel * model,GtkTreePath * path,GtkTreeIter * iter,selector * sr)2127 static void add_to_rvars1 (GtkTreeModel *model, GtkTreePath *path,
2128 GtkTreeIter *iter, selector *sr)
2129 {
2130 if (MODEL_CODE(sr->ci)) {
2131 /* don't add the regressand to the list of regressors */
2132 gint xnum, ynum;
2133
2134 gtk_tree_model_get(model, iter, COL_ID, &xnum, -1);
2135 ynum = selector_get_depvar_number(sr);
2136 if (ynum >= 0 && xnum == ynum) {
2137 return;
2138 }
2139 }
2140
2141 real_add_generic(model, iter, sr, SR_RVARS1);
2142 }
2143
add_to_rvars2(GtkTreeModel * model,GtkTreePath * path,GtkTreeIter * iter,selector * sr)2144 static void add_to_rvars2 (GtkTreeModel *model, GtkTreePath *path,
2145 GtkTreeIter *iter, selector *sr)
2146 {
2147 real_add_generic(model, iter, sr, SR_RVARS2);
2148 }
2149
add_to_rvars2_callback(GtkWidget * w,selector * sr)2150 static void add_to_rvars2_callback (GtkWidget *w, selector *sr)
2151 {
2152 GtkTreeSelection *sel;
2153
2154 if (sr->ci == MIDASREG) {
2155 GtkTreeModel *model = NULL;
2156 GtkTreeIter iter;
2157
2158 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(sr->lvars2));
2159 if (gtk_tree_selection_get_selected(sel, &model, &iter)) {
2160 move_midas_term(model, &iter, sr);
2161 }
2162 } else {
2163 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(sr->lvars));
2164 gtk_tree_selection_selected_foreach(sel,
2165 (GtkTreeSelectionForeachFunc)
2166 add_to_rvars2,
2167 sr);
2168 }
2169 }
2170
add_all_to_rvars1_callback(GtkWidget * w,selector * sr)2171 static void add_all_to_rvars1_callback (GtkWidget *w, selector *sr)
2172 {
2173 GtkTreeSelection *selection;
2174
2175 if (!GTK_IS_TREE_VIEW(sr->lvars)) {
2176 return;
2177 }
2178
2179 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(sr->lvars));
2180 gtk_tree_selection_select_all(selection);
2181 gtk_tree_selection_selected_foreach(selection,
2182 (GtkTreeSelectionForeachFunc)
2183 add_to_rvars1,
2184 sr);
2185 }
2186
add_to_rvars1_callback(GtkWidget * w,selector * sr)2187 static void add_to_rvars1_callback (GtkWidget *w, selector *sr)
2188 {
2189 GtkTreeSelection *selection;
2190
2191 if (!GTK_IS_TREE_VIEW(sr->lvars)) {
2192 return;
2193 }
2194
2195 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(sr->lvars));
2196 gtk_tree_selection_selected_foreach(selection,
2197 (GtkTreeSelectionForeachFunc)
2198 add_to_rvars1,
2199 sr);
2200 }
2201
remove_from_right(GtkWidget * w,selector * sr,GtkWidget * listbox)2202 static void remove_from_right (GtkWidget *w, selector *sr,
2203 GtkWidget *listbox)
2204 {
2205 GtkTreeView *view = GTK_TREE_VIEW(listbox);
2206 GtkTreeModel *model = gtk_tree_view_get_model(view);
2207 GtkTreeSelection *selection = gtk_tree_view_get_selection(view);
2208 GtkTreePath *path;
2209 GtkTreeIter iter, last;
2210 int context = 0;
2211 int v, lag;
2212 int *sellist = NULL;
2213 int ridx, nrows = 0;
2214
2215 if (model == NULL || selection == NULL) {
2216 return;
2217 }
2218
2219 /* determine the number of rows in the list box, create a
2220 list of selected row indices, and navigate to the last row
2221 */
2222 if (gtk_tree_model_get_iter_first(model, &iter)) {
2223 if (gtk_tree_selection_iter_is_selected(selection, &iter)) {
2224 sellist = gretl_list_append_term(&sellist, nrows);
2225 }
2226 last = iter;
2227 nrows++;
2228 while (gtk_tree_model_iter_next(model, &iter)) {
2229 if (gtk_tree_selection_iter_is_selected(selection, &iter)) {
2230 sellist = gretl_list_append_term(&sellist, nrows);
2231 }
2232 last = iter;
2233 nrows++;
2234 }
2235 }
2236
2237 if (nrows == 0 || sellist == NULL) {
2238 /* "can't happen", but... */
2239 return;
2240 }
2241
2242 context = lag_context_from_widget(GTK_WIDGET(view));
2243
2244 /* work back upward, deleting the selected rows */
2245 path = gtk_tree_model_get_path(model, &last);
2246
2247 while (1) {
2248 ridx = gtk_tree_path_get_indices(path)[0];
2249 if (gtk_tree_model_get_iter(model, &last, path) &&
2250 in_gretl_list(sellist, ridx)) {
2251 if (context) {
2252 gtk_tree_model_get(model, &last, COL_ID, &v, COL_LAG, &lag, -1);
2253 remove_specific_lag(v, lag, context);
2254 }
2255 gtk_list_store_remove(GTK_LIST_STORE(model), &last);
2256 nrows--;
2257 }
2258 if (!gtk_tree_path_prev(path)) {
2259 break;
2260 }
2261 }
2262
2263 if (sr->add_button != NULL &&
2264 !gtk_widget_is_sensitive(sr->add_button) &&
2265 !selection_at_max(sr, nrows)) {
2266 gtk_widget_set_sensitive(sr->add_button, TRUE);
2267 }
2268
2269 if (sr->ci == CORR) {
2270 set_n_rvars1(sr, nrows);
2271 }
2272
2273 if (nrows == 0) {
2274 /* the listbox is now empty */
2275 if (context && sr->lags_button != NULL) {
2276 /* can't do independent var lags, but can we still
2277 do dependent var lags?
2278 */
2279 int y_lags_ok = select_lags_depvar(sr->ci) && depvar_selected(sr);
2280
2281 gtk_widget_set_sensitive(sr->lags_button, y_lags_ok);
2282 }
2283 if (GTK_WIDGET(view) == sr->rvars1 && sr->ci == ARMA) {
2284 xdiff_button_set_sensitive(sr, FALSE);
2285 }
2286 } else if (sr->ci == MIDASREG && context && nrows == 1) {
2287 /* If only the constant remains, lag selection
2288 for X-vars should be turned off
2289 */
2290 gtk_tree_model_get_iter_first(model, &iter);
2291 gtk_tree_model_get(model, &iter, COL_ID, &v, -1);
2292 if (v == 0) {
2293 gtk_widget_set_sensitive(sr->lags_button, FALSE);
2294 }
2295 }
2296
2297 free(sellist);
2298 }
2299
remove_from_rvars1_callback(GtkWidget * w,selector * sr)2300 static void remove_from_rvars1_callback (GtkWidget *w, selector *sr)
2301 {
2302 remove_from_right(w, sr, sr->rvars1);
2303 }
2304
remove_from_rvars2_callback(GtkWidget * w,selector * sr)2305 static void remove_from_rvars2_callback (GtkWidget *w, selector *sr)
2306 {
2307 if (sr->ci == MIDASREG) {
2308 GtkTreeSelection *sel;
2309 GtkTreeModel *model = NULL;
2310 GtkTreeIter iter;
2311
2312 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(sr->rvars2));
2313 if (gtk_tree_selection_get_selected(sel, &model, &iter)) {
2314 move_midas_term(model, &iter, sr);
2315 }
2316 } else {
2317 remove_from_right(w, sr, sr->rvars2);
2318 }
2319 }
2320
2321 /* double-clicking sets the dependent variable and marks it as the
2322 default, if applicable */
2323
2324 static gint
dblclick_lvars_row(GtkWidget * w,GdkEventButton * event,selector * sr)2325 dblclick_lvars_row (GtkWidget *w, GdkEventButton *event, selector *sr)
2326 {
2327 if (sr->depvar != NULL && event != NULL &&
2328 event->type == GDK_2BUTTON_PRESS) {
2329 int err = set_dependent_var_from_active(sr);
2330
2331 if (!err && sr->default_check != NULL) {
2332 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sr->default_check),
2333 TRUE);
2334 }
2335 }
2336
2337 return FALSE;
2338 }
2339
2340 /* flip the flag that designates an exogenous veriable in a VECM
2341 as either Unrestricted or Restricted (to the cointegrating
2342 space)
2343 */
2344
maybe_flip_vecm_flag(GtkTreeModel * model,GtkTreePath * path,GtkTreeIter * iter,GtkWidget * w)2345 static void maybe_flip_vecm_flag (GtkTreeModel *model, GtkTreePath *path,
2346 GtkTreeIter *iter, GtkWidget *w)
2347 {
2348 gint i = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w), "opt"));
2349 gchar *orig = NULL, *repl = NULL;
2350
2351 gtk_tree_model_get(model, iter, COL_FLAG, &orig, -1);
2352
2353 if (orig != NULL) {
2354 repl = (i == 0)? "U" : "R";
2355 if (strcmp(orig, repl)) {
2356 gtk_list_store_set(GTK_LIST_STORE(model), iter, COL_FLAG, repl, -1);
2357 }
2358 g_free(orig);
2359 }
2360 }
2361
flag_popup_activated(GtkWidget * w,gpointer data)2362 static void flag_popup_activated (GtkWidget *w, gpointer data)
2363 {
2364 GtkTreeView *view = GTK_TREE_VIEW(data);
2365 GtkTreeSelection *sel;
2366
2367 sel = gtk_tree_view_get_selection(view);
2368 gtk_tree_selection_selected_foreach(sel,
2369 (GtkTreeSelectionForeachFunc)
2370 maybe_flip_vecm_flag,
2371 w);
2372 gtk_widget_destroy(w);
2373 }
2374
create_flag_item(GtkWidget * popup,int i,GtkWidget * view)2375 static void create_flag_item (GtkWidget *popup, int i, GtkWidget *view)
2376 {
2377 static char *flag_strs[] = {
2378 N_("Unrestricted"),
2379 N_("Restricted")
2380 };
2381 GtkWidget *item;
2382
2383 item = gtk_menu_item_new_with_label(_(flag_strs[i]));
2384 g_object_set_data(G_OBJECT(item), "opt", GINT_TO_POINTER(i));
2385 g_signal_connect(G_OBJECT(item), "activate",
2386 G_CALLBACK(flag_popup_activated),
2387 view);
2388 g_signal_connect(G_OBJECT(item), "destroy",
2389 G_CALLBACK(delete_widget),
2390 popup);
2391 gtk_widget_show(item);
2392 gtk_menu_shell_append(GTK_MENU_SHELL(popup), item);
2393 }
2394
listvar_flagcol_click(GtkWidget * widget,GdkEventButton * event,gpointer data)2395 static gint listvar_flagcol_click (GtkWidget *widget,
2396 GdkEventButton *event,
2397 gpointer data)
2398 {
2399 GtkWidget *view = GTK_WIDGET(data);
2400 GtkWidget *flag_popup;
2401 int i;
2402
2403 if (right_click(event)) {
2404 flag_popup = gtk_menu_new();
2405 for (i=0; i<2; i++) {
2406 create_flag_item(flag_popup, i, view);
2407 }
2408 gtk_menu_popup(GTK_MENU(flag_popup), NULL, NULL, NULL, NULL,
2409 event->button, event->time);
2410 return TRUE;
2411 }
2412
2413 return FALSE;
2414 }
2415
2416 /* Below: we're allowing the user to revise the MIDAS
2417 parameterization of a previously selected term
2418 */
2419
listvar_midas_click(GtkWidget * widget,GdkEventButton * event,selector * sr)2420 static gint listvar_midas_click (GtkWidget *widget,
2421 GdkEventButton *event,
2422 selector *sr)
2423 {
2424 if (right_click(event)) {
2425 GtkTreeSelection *sel;
2426 GtkTreeModel *model = NULL;
2427 GtkTreeIter iter;
2428
2429 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
2430 if (gtk_tree_selection_get_selected(sel, &model, &iter)) {
2431 int m, lmin, lmax, ptype, k, resp;
2432 gchar *vname = NULL;
2433 gboolean no_beta1;
2434
2435 no_beta1 = (check_midas_rvars2(model, NULL) > 1);
2436 gtk_tree_model_get(model, &iter, MCOL_M, &m, MCOL_NAME, &vname,
2437 MCOL_MINLAG, &lmin, MCOL_MAXLAG, &lmax,
2438 MCOL_TYPE, &ptype, MCOL_K, &k, -1);
2439 resp = midas_term_dialog(vname, m, &lmin, &lmax, &ptype,
2440 &k, no_beta1, sr->dlg);
2441 if (resp != GRETL_CANCEL) {
2442 gtk_list_store_set(GTK_LIST_STORE(model), &iter,
2443 MCOL_MINLAG, lmin, MCOL_MAXLAG, lmax,
2444 MCOL_TYPE, ptype, MCOL_K, k,
2445 -1);
2446 }
2447 }
2448
2449 return TRUE;
2450 }
2451
2452 return FALSE;
2453 }
2454
selection_get_row_info(GtkTreeModel * model,GtkTreeSelection * sel,int * r0,int * r1,int * rmin)2455 static int selection_get_row_info (GtkTreeModel *model,
2456 GtkTreeSelection *sel,
2457 int *r0, int *r1, int *rmin)
2458 {
2459 GtkTreeIter iter;
2460 int i, rmax = 0;
2461
2462 *r0 = 10000;
2463 *r1 = -1;
2464 *rmin = 0;
2465
2466 if (gtk_tree_model_get_iter_first(model, &iter)) {
2467 gint id;
2468
2469 gtk_tree_model_get(model, &iter, COL_ID, &id, -1);
2470 if (id == 0) {
2471 /* don't shift const from position 0 */
2472 *rmin = 1;
2473 }
2474 for (i=0; ; i++) {
2475 if (gtk_tree_selection_iter_is_selected(sel, &iter)) {
2476 if (i < *r0) {
2477 *r0 = i;
2478 }
2479 if (i > *r1) {
2480 *r1 = i;
2481 }
2482 }
2483 if (!gtk_tree_model_iter_next(model, &iter)) {
2484 break;
2485 }
2486 }
2487 rmax = i;
2488 }
2489
2490 return rmax;
2491 }
2492
set_selection_from_list(GtkTreeView * view,GtkTreeModel * model,GtkTreeSelection * sel,const int * list)2493 static void set_selection_from_list (GtkTreeView *view,
2494 GtkTreeModel *model,
2495 GtkTreeSelection *sel,
2496 const int *list)
2497 {
2498 GtkTreeIter iter;
2499 int id, nsel = 0;
2500
2501 gtk_tree_selection_unselect_all(sel);
2502 gtk_tree_model_get_iter_first(model, &iter);
2503
2504 while (gtk_tree_model_iter_next(model, &iter) && nsel < list[0]) {
2505 gtk_tree_model_get(model, &iter, COL_ID, &id, -1);
2506 if (in_gretl_list(list, id)) {
2507 gtk_tree_selection_select_iter(sel, &iter);
2508 nsel++;
2509 }
2510 }
2511 }
2512
swap_row_content(GtkTreeModel * model,GtkTreeIter * iter0,GtkTreeIter * iter1,int flags)2513 static int swap_row_content (GtkTreeModel *model, GtkTreeIter *iter0,
2514 GtkTreeIter *iter1, int flags)
2515 {
2516 GtkListStore *store = GTK_LIST_STORE(model);
2517 gint id0, id1, l0, l1;
2518 gchar *s0, *s1;
2519
2520 gtk_tree_model_get(model, iter0, COL_ID, &id0, COL_LAG, &l0,
2521 COL_NAME, &s0, -1);
2522 gtk_tree_model_get(model, iter1, COL_ID, &id1, COL_LAG, &l1,
2523 COL_NAME, &s1, -1);
2524 gtk_list_store_set(store, iter0, COL_ID, id1, COL_LAG, l1,
2525 COL_NAME, s1, -1);
2526 gtk_list_store_set(store, iter1, COL_ID, id0, COL_LAG, l0,
2527 COL_NAME, s0, -1);
2528
2529 g_free(s0);
2530 g_free(s1);
2531
2532 if (flags) {
2533 gtk_tree_model_get(model, iter0, COL_FLAG, &s0);
2534 gtk_tree_model_get(model, iter1, COL_FLAG, &s1);
2535 gtk_list_store_set(store, iter0, COL_FLAG, s1);
2536 gtk_list_store_set(store, iter1, COL_FLAG, s0);
2537
2538 g_free(s0);
2539 g_free(s1);
2540 }
2541
2542 return id1;
2543 }
2544
move_selected_rows(GtkMenuItem * item,GtkTreeView * view)2545 static void move_selected_rows (GtkMenuItem *item, GtkTreeView *view)
2546 {
2547 gint down = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(item), "down"));
2548 GtkTreeSelection *sel = gtk_tree_view_get_selection(view);
2549 GtkTreeModel *model = gtk_tree_view_get_model(view);
2550 GtkTreeIter iter0, iter1;
2551 GtkTreePath *path;
2552 gboolean flags = FALSE;
2553 int id, *sellist = NULL;
2554
2555 if (gtk_tree_view_get_column(view, 3) != NULL) {
2556 flags = TRUE;
2557 }
2558
2559 if (down) {
2560 tree_model_get_iter_last(model, &iter1);
2561 while (tree_model_iter_prev(model, &iter1)) {
2562 if (gtk_tree_selection_iter_is_selected(sel, &iter1)) {
2563 path = gtk_tree_model_get_path(model, &iter1);
2564 gtk_tree_path_next(path);
2565 gtk_tree_model_get_iter(model, &iter0, path);
2566 id = swap_row_content(model, &iter0, &iter1, flags);
2567 gretl_list_append_term(&sellist, id);
2568 gtk_tree_path_free(path);
2569 }
2570 }
2571 } else {
2572 gtk_tree_model_get_iter_first(model, &iter1);
2573 while (gtk_tree_model_iter_next(model, &iter1)) {
2574 if (gtk_tree_selection_iter_is_selected(sel, &iter1)) {
2575 path = gtk_tree_model_get_path(model, &iter1);
2576 gtk_tree_path_prev(path);
2577 gtk_tree_model_get_iter(model, &iter0, path);
2578 id = swap_row_content(model, &iter0, &iter1, flags);
2579 gretl_list_append_term(&sellist, id);
2580 gtk_tree_path_free(path);
2581 }
2582 }
2583 }
2584
2585 if (sellist != NULL) {
2586 set_selection_from_list(view, model, sel, sellist);
2587 free(sellist);
2588 }
2589
2590 gtk_widget_destroy(GTK_WIDGET(item));
2591 }
2592
listvar_reorder_click(GtkWidget * widget,GdkEventButton * event,gpointer data)2593 static gint listvar_reorder_click (GtkWidget *widget, GdkEventButton *event,
2594 gpointer data)
2595 {
2596 if (right_click(event)) {
2597 GtkTreeView *view = GTK_TREE_VIEW(data);
2598 GtkTreeModel *model = gtk_tree_view_get_model(view);
2599 GtkTreeSelection *sel = gtk_tree_view_get_selection(view);
2600 int r0, r1, rmin, rmax;
2601
2602 rmax = selection_get_row_info(model, sel, &r0, &r1, &rmin);
2603
2604 if (r0 >= 0 && !(rmin == 1 && r0 == 0)) {
2605 const gchar *icons[] = {
2606 GTK_STOCK_GO_UP,
2607 GTK_STOCK_GO_DOWN
2608 };
2609 GtkWidget *popup = gtk_menu_new();
2610 GtkWidget *item;
2611 int i;
2612
2613 for (i=0; i<2; i++) {
2614 if (i == 0 && r0 <= rmin) {
2615 /* can't do move up */
2616 continue;
2617 } else if (i == 1 && r1 >= rmax) {
2618 /* can't do move down */
2619 continue;
2620 }
2621 item = gtk_image_menu_item_new_from_stock(icons[i], NULL);
2622 g_object_set_data(G_OBJECT(item), "down",
2623 GINT_TO_POINTER(i));
2624 g_signal_connect(G_OBJECT(item), "activate",
2625 G_CALLBACK(move_selected_rows), view);
2626 g_signal_connect(G_OBJECT(item), "destroy",
2627 G_CALLBACK(delete_widget), popup);
2628 gtk_widget_show_all(item);
2629 gtk_menu_shell_append(GTK_MENU_SHELL(popup), item);
2630 }
2631
2632 gtk_menu_popup(GTK_MENU(popup), NULL, NULL, NULL, NULL,
2633 event->button, event->time);
2634 }
2635 return TRUE;
2636 }
2637
2638 return FALSE;
2639 }
2640
lvars_right_click(GtkWidget * widget,GdkEventButton * event,selector * sr)2641 static gint lvars_right_click (GtkWidget *widget, GdkEventButton *event,
2642 selector *sr)
2643 {
2644 if (right_click(event)) {
2645 if (widget == sr->lvars2) {
2646 if (sr->ci == MIDASREG) {
2647 add_to_rvars2_callback(widget, sr);
2648 }
2649 } else {
2650 if (NONPARAM_CODE(sr->ci)) {
2651 set_extra_var_callback(NULL, sr);
2652 } else if (sr->ci == GR_FBOX) {
2653 set_third_var_callback(NULL, sr);
2654 } else {
2655 add_to_rvars1_callback(NULL, sr);
2656 }
2657 }
2658 return TRUE;
2659 }
2660
2661 return FALSE;
2662 }
2663
2664 /* end special click callbacks */
2665
varlist_insert_const(GtkWidget * w)2666 static void varlist_insert_const (GtkWidget *w)
2667 {
2668 GtkTreeModel *mod = gtk_tree_view_get_model(GTK_TREE_VIEW(w));
2669 GtkTreeIter iter;
2670
2671 gtk_tree_model_get_iter_first(mod, &iter);
2672 gtk_list_store_append(GTK_LIST_STORE(mod), &iter);
2673 gtk_list_store_set(GTK_LIST_STORE(mod), &iter,
2674 COL_ID, 0, COL_LAG, 0, COL_NAME, "const", -1);
2675 }
2676
clear_vars(GtkWidget * w,selector * sr)2677 static void clear_vars (GtkWidget *w, selector *sr)
2678 {
2679 GtkTreeSelection *selection;
2680
2681 /* deselect all vars on left */
2682 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(sr->lvars));
2683 gtk_tree_selection_unselect_all(selection);
2684
2685 /* clear dependent var slot */
2686 if (sr->depvar != NULL) {
2687 gtk_entry_set_text(GTK_ENTRY(sr->depvar), "");
2688 if (sr->default_check != NULL) {
2689 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sr->default_check),
2690 FALSE);
2691 }
2692 default_y = -1;
2693 }
2694
2695 /* extra variable entry? */
2696 if (GTK_IS_ENTRY(sr->extra[0])) {
2697 gtk_entry_set_text(GTK_ENTRY(sr->extra[0]), "");
2698 }
2699
2700 if (THREE_VARS_CODE(sr->ci)) {
2701 /* clear special slot */
2702 gtk_entry_set_text(GTK_ENTRY(sr->rvars1), "");
2703 } else if (sr->rvars1 != NULL) {
2704 /* empty upper right variable list */
2705 clear_varlist(sr->rvars1);
2706 if (sr->add_button != NULL) {
2707 gtk_widget_set_sensitive(sr->add_button, TRUE);
2708 }
2709 }
2710
2711 if (MODEL_CODE(sr->ci) && sr->ci != ARMA && sr->ci != GARCH) {
2712 /* insert default const in regressors box */
2713 varlist_insert_const(sr->rvars1);
2714 }
2715
2716 if (sr->rvars2 != NULL) {
2717 /* empty lower right variable list */
2718 clear_varlist(sr->rvars2);
2719 if (USE_ZLIST(sr->ci)) {
2720 varlist_insert_const(sr->rvars2);
2721 }
2722 }
2723
2724 if (sr->lags_button != NULL) {
2725 gtk_widget_set_sensitive(sr->lags_button, FALSE);
2726 }
2727
2728 if (VECLAGS_CODE(sr->ci) && sr->extra[EXTRA_LAGS] != NULL) {
2729 gtk_widget_set_sensitive(sr->extra[EXTRA_LAGS], FALSE);
2730 gtk_widget_set_sensitive(sr->extra[0], TRUE);
2731 }
2732
2733 clear_selector();
2734 }
2735
varlist_row_count(selector * sr,int locus,int * realrows)2736 static gint varlist_row_count (selector *sr, int locus, int *realrows)
2737 {
2738 int lcontext = 0;
2739 GtkWidget *w;
2740 GtkTreeModel *mod;
2741 GtkTreeIter iter;
2742 gint v, lag, n = 0;
2743
2744 w = (locus == SR_RVARS1)? sr->rvars1 : sr->rvars2;
2745
2746 if (w == NULL || !gtk_widget_is_sensitive(w)) {
2747 return 0;
2748 }
2749
2750 if (realrows != NULL) {
2751 lcontext = sr_get_lag_context(sr, locus);
2752 *realrows = 0;
2753 }
2754
2755 if (w != NULL) {
2756 mod = gtk_tree_view_get_model(GTK_TREE_VIEW(w));
2757 if (GTK_IS_TREE_MODEL(mod) &&
2758 gtk_tree_model_get_iter_first(mod, &iter)) {
2759 do {
2760 n++;
2761 if (lcontext) {
2762 gtk_tree_model_get(mod, &iter, COL_ID, &v, COL_LAG, &lag, -1);
2763 if (!is_lag_dummy(v, lag, lcontext)) {
2764 *realrows += 1;
2765 }
2766 }
2767 } while (gtk_tree_model_iter_next(mod, &iter));
2768 }
2769 }
2770
2771 if (realrows != NULL && lcontext == 0) {
2772 *realrows = n;
2773 }
2774
2775 return n;
2776 }
2777
topslot_empty(int ci)2778 static void topslot_empty (int ci)
2779 {
2780 switch (ci) {
2781 case GR_XY:
2782 case GR_3D:
2783 case GR_IMP:
2784 warnbox(_("You must select an X-axis variable"));
2785 break;
2786 case SCATTERS:
2787 warnbox(_("You must select a Y-axis variable"));
2788 break;
2789 case INTREG:
2790 warnbox(_("You must select a lower bound variable"));
2791 break;
2792 default:
2793 warnbox(_("You must select a dependent variable"));
2794 }
2795 }
2796
reverse_list(char * list)2797 static void reverse_list (char *list)
2798 {
2799 char istr[VNAMELEN];
2800 char *tmp, *p;
2801
2802 p = strchr(list, ';');
2803 if (p == NULL) return;
2804
2805 tmp = malloc(strlen(list) + 4);
2806 if (tmp == NULL) return;
2807
2808 sscanf(list, "%31s", istr);
2809
2810 strcpy(tmp, p + 2);
2811 strcat(tmp, " ; ");
2812 strcat(tmp, istr);
2813
2814 strcpy(list, tmp);
2815
2816 free(tmp);
2817 }
2818
2819 enum cmdlist_codes {
2820 ADD_NOW,
2821 ADD_AT_END
2822 };
2823
add_to_cmdlist(selector * sr,const char * add)2824 static int add_to_cmdlist (selector *sr, const char *add)
2825 {
2826 size_t addlen = strlen(add);
2827 size_t req = sr->cmdlen + addlen + 1;
2828 int err = 0;
2829
2830 if (req > sr->cmdsize) {
2831 size_t newsize = sr->cmdsize + MAXLEN;
2832 char *tmp = NULL;
2833
2834 if (newsize < req) {
2835 newsize = req;
2836 }
2837
2838 tmp = realloc(sr->cmdlist, newsize);
2839 if (tmp == NULL) {
2840 err = E_ALLOC;
2841 } else {
2842 sr->cmdlist = tmp;
2843 sr->cmdsize = newsize;
2844 }
2845 }
2846
2847 if (!err) {
2848 strcat(sr->cmdlist, add);
2849 sr->cmdlen += addlen;
2850 }
2851
2852 return err;
2853 }
2854
2855 /* append a space followed by either the ID number or
2856 the name of the series */
2857
cmdlist_append_series(selector * sr,const char * s0,int id)2858 static void cmdlist_append_series (selector *sr,
2859 const char *s0,
2860 int id)
2861 {
2862 char idstr[8];
2863
2864 if (s0 != NULL) {
2865 add_to_cmdlist(sr, s0);
2866 }
2867
2868 if (LIST_USE_INTS(sr->ci)) {
2869 sprintf(idstr, "%d", id);
2870 add_to_cmdlist(sr, idstr);
2871 } else if (id > 0 && id < dataset->v) {
2872 add_to_cmdlist(sr, dataset->varname[id]);
2873 } else {
2874 sprintf(idstr, "%d", id);
2875 add_to_cmdlist(sr, idstr);
2876 }
2877 }
2878
print_list_element(selector * sr,char * targ,const char * s0,int id)2879 static void print_list_element (selector *sr,
2880 char *targ,
2881 const char *s0,
2882 int id)
2883 {
2884 if (LIST_USE_INTS(sr->ci)) {
2885 sprintf(targ, "%s%d", s0, id);
2886 } else if (id > 0 && id < dataset->v) {
2887 sprintf(targ, "%s%s", s0, dataset->varname[id]);
2888 } else {
2889 sprintf(targ, "%s%d", s0, id);
2890 }
2891 }
2892
arma_lag_string(char * targ,const char * s)2893 static char *arma_lag_string (char *targ, const char *s)
2894 {
2895 while (*s == ' ') s++;
2896
2897 if (*s == '\0') {
2898 strcpy(targ, "0 ");
2899 } else if (isalpha(*s) || *s == '{') {
2900 sprintf(targ, "%s ", s);
2901 } else {
2902 sprintf(targ, "{%s} ", s);
2903 }
2904
2905 gretl_charsub(targ, ',', ' ');
2906
2907 return targ;
2908 }
2909
arma_spec_to_cmdlist(selector * sr)2910 static void arma_spec_to_cmdlist (selector *sr)
2911 {
2912 const char *txt;
2913 char s[32];
2914
2915 free(arlags);
2916 arlags = NULL;
2917
2918 free(malags);
2919 malags = NULL;
2920
2921 if (gtk_widget_is_sensitive(sr->extra[ARMA_plist])) {
2922 /* "gappy" AR lags activated */
2923 txt = gtk_entry_get_text(GTK_ENTRY(sr->extra[ARMA_plist]));
2924 add_to_cmdlist(sr, arma_lag_string(s, txt));
2925 arlags = gretl_strdup(txt);
2926 } else {
2927 /* regular max AR lag */
2928 arma_p = spinner_get_int(sr->extra[ARMA_p]);
2929 sprintf(s, "%d ", arma_p);
2930 add_to_cmdlist(sr, s);
2931 }
2932
2933 arima_d = spinner_get_int(sr->extra[ARIMA_d]);
2934 sprintf(s, "%d ", arima_d);
2935 add_to_cmdlist(sr, s);
2936
2937 if (gtk_widget_is_sensitive(sr->extra[ARMA_qlist])) {
2938 /* "gappy" MA lags activated */
2939 txt = gtk_entry_get_text(GTK_ENTRY(sr->extra[ARMA_qlist]));
2940 add_to_cmdlist(sr, arma_lag_string(s, txt));
2941 add_to_cmdlist(sr, "; ");
2942 malags = gretl_strdup(txt);
2943 } else {
2944 /* regular max MA lag */
2945 arma_q = spinner_get_int(sr->extra[ARMA_q]);
2946 sprintf(s, "%d ; ", arma_q);
2947 add_to_cmdlist(sr, s);
2948 }
2949
2950 if (sr->extra[ARMA_P] != NULL) {
2951 arma_P = spinner_get_int(sr->extra[ARMA_P]);
2952 arima_D = spinner_get_int(sr->extra[ARIMA_D]);
2953 arma_Q = spinner_get_int(sr->extra[ARMA_Q]);
2954
2955 if (arma_P > 0 || arima_D > 0 || arma_Q > 0) {
2956 sprintf(s, "%d %d %d ; ", arma_P, arima_D, arma_Q);
2957 add_to_cmdlist(sr, s);
2958 }
2959 }
2960 }
2961
add_pdq_vals_to_cmdlist(selector * sr)2962 static void add_pdq_vals_to_cmdlist (selector *sr)
2963 {
2964 char s[32] = {0};
2965
2966 if (sr->ci == GARCH) {
2967 garch_p = spinner_get_int(sr->extra[0]);
2968 garch_q = spinner_get_int(sr->extra[1]);
2969 sprintf(s, "%d %d ; ", garch_p, garch_q);
2970 } else if (sr->ci == DPANEL) {
2971 dpd_p = spinner_get_int(sr->extra[0]);
2972 sprintf(s, "%d ; ", dpd_p);
2973 } else if (sr->ci == ARCH) {
2974 int p = spinner_get_int(sr->extra[0]);
2975
2976 sprintf(s, "%d ", p);
2977 }
2978
2979 add_to_cmdlist(sr, s);
2980 }
2981
read_ellipse_alpha(selector * sr)2982 static void read_ellipse_alpha (selector *sr)
2983 {
2984 if (sr->extra[0] != NULL) {
2985 char s[16];
2986 double cval;
2987
2988 cval = gtk_spin_button_get_value(GTK_SPIN_BUTTON(sr->extra[0]));
2989 sprintf(s, "%g", 1 - cval);
2990 add_to_cmdlist(sr, s);
2991 }
2992 }
2993
read_coint_opt_parm(selector * sr)2994 static void read_coint_opt_parm (selector *sr)
2995 {
2996 GtkWidget *combo = sr->extra[EXTRA_LAGS];
2997
2998 if (combo != NULL && gtk_widget_is_sensitive(combo)) {
2999 int method = gtk_combo_box_get_active(GTK_COMBO_BOX(combo));
3000
3001 if (method == 1) {
3002 sr->extra_data = gretl_strdup("BIC");
3003 } else if (method == 2) {
3004 sr->extra_data = gretl_strdup("tstat");
3005 }
3006 }
3007 }
3008
3009 /* Take the stored preferred laglist for a variable (if any) and
3010 convert to a string specification for adding to the regression
3011 command line.
3012 */
3013
3014 static gchar *
discrete_lags_string(const char * vname,const int * laglist,char context)3015 discrete_lags_string (const char *vname, const int *laglist,
3016 char context)
3017 {
3018 gchar *ret = NULL;
3019 int nlags = laglist[0];
3020 int i, li, len;
3021 char tmp[64];
3022
3023 /* allow 3 for space, '(' and ')' */
3024 len = 1 + nlags * (strlen(vname) + 3);
3025
3026 for (i=1; i<=nlags; i++) {
3027 li = laglist[i];
3028 sprintf(tmp, "%d", li);
3029 len += strlen(tmp) + (li > 0);
3030 }
3031
3032 ret = g_malloc0(len);
3033
3034 if (ret != NULL) {
3035 for (i=1; i<=nlags; i++) {
3036 li = laglist[i];
3037 sprintf(tmp, " %s(%s%d)", vname, (li > 0)? "-" : "", li);
3038 strcat(ret, tmp);
3039 }
3040 }
3041
3042 return ret;
3043 }
3044
selector_get_VAR_order(const selector * sr)3045 int selector_get_VAR_order (const selector *sr)
3046 {
3047 return spinner_get_int(sr->extra[0]);
3048 }
3049
3050 /* for use in constructing command list, possibly with
3051 embedded lags */
3052
get_lagpref_string(int v,char context,selector * sr)3053 static char *get_lagpref_string (int v, char context,
3054 selector *sr)
3055 {
3056 const char *vname = dataset->varname[v];
3057 const int *laglist;
3058 int lmin, lmax;
3059 char *s = NULL;
3060
3061 if (v == 0) {
3062 if (context == LAG_Y_X || context == LAG_Y_W) {
3063 /* const as dependent: empty lags string */
3064 return g_strdup("");
3065 } else {
3066 /* const as indep var: just return itself */
3067 return g_strdup(" 0");
3068 }
3069 }
3070
3071 get_lag_preference(v, &lmin, &lmax, &laglist, context, sr);
3072
3073 if (laglist != NULL) {
3074 s = discrete_lags_string(vname, laglist, context);
3075 } else if (lmin != lmax) {
3076 s = g_strdup_printf(" %s(%s%d to -%d)", vname, (lmin > 0)? "-" : "",
3077 lmin, lmax);
3078 } else if (lmin != 0) {
3079 s = g_strdup_printf(" %s(%s%d)", vname, (lmin > 0)? "-" : "",
3080 lmin);
3081 } else if (context != LAG_Y_X && context != LAG_Y_W) {
3082 s = g_strdup_printf(" %s", vname);
3083 }
3084
3085 #if LDEBUG
3086 if (s != NULL) {
3087 fprintf(stderr, "get_lagpref_string for v=%d (%s), context=%d:\n"
3088 " constructed s = '%s'\n", v, vname, (int) context, s);
3089 }
3090 #endif
3091
3092 return s;
3093 }
3094
maybe_resize_recorder_lists(selector * sr,int n)3095 static int maybe_resize_recorder_lists (selector *sr, int n)
3096 {
3097 int err = 0;
3098
3099 if (MODEL_CODE(sr->ci) || VEC_CODE(sr->ci)) {
3100 int *newlist;
3101
3102 if (MODEL_CODE(sr->ci)) {
3103 newlist = gretl_list_resize(&xlist, n);
3104 } else {
3105 newlist = gretl_list_resize(&veclist, n);
3106 }
3107 if (newlist == NULL) {
3108 err = E_ALLOC;
3109 }
3110 }
3111
3112 return err;
3113 }
3114
maybe_resize_exog_recorder_lists(selector * sr,int n)3115 static int maybe_resize_exog_recorder_lists (selector *sr, int n)
3116 {
3117 int err = 0;
3118
3119 if (USE_ZLIST(sr->ci) || USE_VECXLIST(sr->ci)) {
3120 int *newlist;
3121
3122 if (USE_ZLIST(sr->ci)) {
3123 newlist = gretl_list_resize(&instlist, n);
3124 } else {
3125 /* FIXME not needed for VECM? */
3126 newlist = gretl_list_resize(&vecxlist, n);
3127 }
3128 if (newlist == NULL) {
3129 err = E_ALLOC;
3130 }
3131 }
3132
3133 return err;
3134 }
3135
nonparam_record_xvar(const char * s)3136 static void nonparam_record_xvar (const char *s)
3137 {
3138 int k;
3139
3140 if (sscanf(s, "%d", &k) == 1 && k > 0) {
3141 np_xvar = k;
3142 }
3143 }
3144
get_rvars1_data(selector * sr,int rows,int context)3145 static void get_rvars1_data (selector *sr, int rows, int context)
3146 {
3147 GtkTreeModel *model;
3148 GtkTreeIter iter;
3149 gint rvar, lag;
3150 gchar *rvstr;
3151 int added = 0;
3152 int i, j = 1;
3153
3154 if ((SAVE_DATA_ACTION(sr->ci) || sr->ci == EXPORT) &&
3155 sr->ci != COPY_CSV && rows == sr->n_left) {
3156 /* saving/exporting all available series: leave the
3157 list blank in case it overflows
3158 */
3159 return;
3160 }
3161
3162 sr->n_left = 0;
3163
3164 model = gtk_tree_view_get_model(GTK_TREE_VIEW(sr->rvars1));
3165 gtk_tree_model_get_iter_first(model, &iter);
3166
3167 for (i=0; i<rows; i++) {
3168 gtk_tree_model_get(model, &iter, COL_ID, &rvar, COL_LAG, &lag, -1);
3169
3170 if (is_lag_dummy(rvar, lag, context)) {
3171 gtk_tree_model_iter_next(model, &iter);
3172 continue;
3173 }
3174
3175 if (context) {
3176 rvstr = get_lagpref_string(rvar, context, sr);
3177 if (rvstr == NULL) {
3178 sr->error = E_ALLOC;
3179 break;
3180 } else {
3181 add_to_cmdlist(sr, rvstr);
3182 g_free(rvstr);
3183 added++;
3184 }
3185 } else {
3186 cmdlist_append_series(sr, " ", rvar);
3187 added++;
3188 }
3189
3190 /* save for future reference */
3191 if (MODEL_CODE(sr->ci) && xlist != NULL) {
3192 xlist[j++] = rvar;
3193 } else if (VEC_CODE(sr->ci) && veclist != NULL) {
3194 veclist[j++] = rvar;
3195 }
3196
3197 gtk_tree_model_iter_next(model, &iter);
3198 }
3199
3200 #if 0
3201 if (MODEL_CODE(sr->ci)) {
3202 printlist(xlist, "xlist");
3203 }
3204 #endif
3205
3206 if (sr->ci == ARMA && added && !(sr->opts & OPT_N)) {
3207 /* add const explicitly unless forbidden */
3208 add_to_cmdlist(sr, " 0");
3209 }
3210 }
3211
3212 /* VECM: parse out the exogenous vars as either restricted
3213 or unrestricted */
3214
get_vecm_exog_list(selector * sr,int rows,GtkTreeModel * mod)3215 static int get_vecm_exog_list (selector *sr, int rows,
3216 GtkTreeModel *mod)
3217 {
3218 GtkTreeIter iter;
3219 int *xlist = NULL;
3220 int *rlist = NULL;
3221 int i, v;
3222 int err = 0;
3223
3224 gtk_tree_model_get_iter_first(mod, &iter);
3225
3226 for (i=0; i<rows && !err; i++) {
3227 gchar *flag = NULL;
3228 int lag = 0;
3229
3230 gtk_tree_model_get(mod, &iter, COL_ID, &v, COL_LAG, &lag,
3231 COL_FLAG, &flag, -1);
3232
3233 if (flag == NULL) {
3234 err = E_DATA;
3235 } else if (lag != 0) {
3236 v = laggenr(v, lag, dataset);
3237 if (v < 0) {
3238 err = E_DATA;
3239 }
3240 }
3241
3242 if (!err) {
3243 if (*flag == 'U') {
3244 /* unrestricted terms */
3245 gretl_list_append_term(&xlist, v);
3246 if (xlist == NULL) {
3247 err = E_ALLOC;
3248 }
3249 } else if (*flag == 'R') {
3250 /* restricted terms */
3251 gretl_list_append_term(&rlist, v);
3252 if (rlist == NULL) {
3253 err = E_ALLOC;
3254 }
3255 } else {
3256 err = E_DATA;
3257 }
3258 }
3259
3260 g_free(flag);
3261 gtk_tree_model_iter_next(mod, &iter);
3262 }
3263
3264 if (!err) {
3265 if (xlist != NULL) {
3266 for (i=1; i<=xlist[0]; i++) {
3267 cmdlist_append_series(sr, " ", xlist[i]);
3268 }
3269 }
3270 if (rlist != NULL) {
3271 add_to_cmdlist(sr, " ;");
3272 for (i=1; i<=rlist[0]; i++) {
3273 cmdlist_append_series(sr, " ", rlist[i]);
3274 }
3275 }
3276
3277 free(vecxlist);
3278 vecxlist = NULL;
3279
3280 if (xlist != NULL && rlist != NULL) {
3281 vecxlist = gretl_lists_join_with_separator(xlist, rlist);
3282 } else if (xlist != NULL) {
3283 vecxlist = xlist;
3284 xlist = NULL;
3285 }
3286 }
3287
3288 free(xlist);
3289 free(rlist);
3290
3291 if (err) {
3292 gui_errmsg(err);
3293 }
3294
3295 return err;
3296 }
3297
3298 /* get the component of the model (or whatever) specification from the
3299 secondary list box on the right, if applicable */
3300
get_rvars2_data(selector * sr,int rows,int context)3301 static int get_rvars2_data (selector *sr, int rows, int context)
3302 {
3303 GtkTreeModel *model;
3304 GtkTreeIter iter;
3305 gint exog, lag, ynum;
3306 int *reclist = NULL;
3307 gchar *tmp;
3308 int ncols, i, j = 1;
3309 int err = 0;
3310
3311 model = gtk_tree_view_get_model(GTK_TREE_VIEW(sr->rvars2));
3312 ncols = gtk_tree_model_get_n_columns(model);
3313
3314 if (USE_RXLIST(sr->ci) && ncols == 4) {
3315 return get_vecm_exog_list(sr, rows, model);
3316 }
3317
3318 gtk_tree_model_get_iter_first(model, &iter);
3319
3320 if (USE_ZLIST(sr->ci)) {
3321 reclist = instlist;
3322 } else if (USE_VECXLIST(sr->ci)) {
3323 reclist = vecxlist;
3324 }
3325
3326 ynum = selector_get_depvar_number(sr);
3327
3328 for (i=0; i<rows; i++) {
3329
3330 gtk_tree_model_get(model, &iter, COL_ID, &exog, COL_LAG, &lag, -1);
3331
3332 if (IV_MODEL(sr->ci) && exog == ynum && lag == 0) {
3333 /* HECKIT? */
3334 errbox(_("You can't use the dependent variable as an instrument"));
3335 err = 1;
3336 break;
3337 }
3338
3339 if (is_lag_dummy(exog, lag, context)) {
3340 gtk_tree_model_iter_next(model, &iter);
3341 continue;
3342 }
3343
3344 if (context) {
3345 tmp = get_lagpref_string(exog, context, sr);
3346 add_to_cmdlist(sr, tmp);
3347 g_free(tmp);
3348 } else {
3349 cmdlist_append_series(sr, " ", exog);
3350 }
3351
3352 if (reclist != NULL) {
3353 reclist[j++] = exog;
3354 }
3355
3356 gtk_tree_model_iter_next(model, &iter);
3357 }
3358
3359 return err;
3360 }
3361
clear_midas_spec(void)3362 static void clear_midas_spec (void)
3363 {
3364 *mds_listname = '\0';
3365 mds_quad[0] = 0;
3366 mds_quad[1] = 0;
3367 mds_quad[2] = 1;
3368 mds_quad[3] = 2;
3369 mds_order = 1;
3370 }
3371
get_midas_specs(selector * sr)3372 static void get_midas_specs (selector *sr)
3373 {
3374 gui_midas_spec *specs;
3375 GtkTreeModel *model;
3376 GtkTreeIter iter;
3377 gchar *vname;
3378 int i, rows = 0;
3379
3380 model = gtk_tree_view_get_model(GTK_TREE_VIEW(sr->rvars2));
3381 if (gtk_tree_model_get_iter_first(model, &iter)) {
3382 do {
3383 rows++;
3384 } while (gtk_tree_model_iter_next(model, &iter));
3385 }
3386
3387 if (rows == 0) {
3388 warnbox("You must specify at least one MIDAS term");
3389 sr->error = 1;
3390 return;
3391 }
3392
3393 specs = malloc(rows * sizeof *specs);
3394 if (specs == NULL) {
3395 nomem();
3396 sr->error = E_ALLOC;
3397 return;
3398 }
3399
3400 gtk_tree_model_get_iter_first(model, &iter);
3401
3402 for (i=0; i<rows; i++) {
3403 specs[i].nterms = rows;
3404 gtk_tree_model_get(model, &iter,
3405 COL_ID, &specs[i].leadvar,
3406 MCOL_M, &specs[i].fratio,
3407 MCOL_NAME, &vname,
3408 MCOL_MINLAG, &specs[i].minlag,
3409 MCOL_MAXLAG, &specs[i].maxlag,
3410 MCOL_TYPE, &specs[i].ptype,
3411 MCOL_K, &specs[i].nparm, -1);
3412 if (i == 0) {
3413 /* remember some stuff */
3414 mds_quad[0] = specs[i].minlag;
3415 mds_quad[1] = specs[i].maxlag;
3416 mds_quad[2] = specs[i].ptype;
3417 mds_quad[3] = specs[i].nparm;
3418 }
3419 if (specs[i].leadvar > 0) {
3420 specs[i].listname[0] = '\0';
3421 } else {
3422 strcpy(specs[i].listname, vname);
3423 specs[i].leadvar = 0;
3424 }
3425 gtk_tree_model_iter_next(model, &iter);
3426 }
3427
3428 if (sr->extra_data != NULL) {
3429 free(sr->extra_data);
3430 }
3431
3432 sr->extra_data = specs;
3433 }
3434
check_midas_rvars2(GtkTreeModel * model,gboolean * have_beta1)3435 static int check_midas_rvars2 (GtkTreeModel *model,
3436 gboolean *have_beta1)
3437 {
3438 GtkTreeIter iter;
3439 int ptype = -1;
3440 int nterms = 0;
3441
3442 if (gtk_tree_model_get_iter_first(model, &iter)) {
3443 do {
3444 nterms++;
3445 if (have_beta1 != NULL) {
3446 gtk_tree_model_get(model, &iter, MCOL_TYPE,
3447 &ptype, -1);
3448 if (ptype == MIDAS_BETA1) {
3449 *have_beta1 = 1;
3450 }
3451 }
3452 } while (gtk_tree_model_iter_next(model, &iter));
3453 }
3454
3455 return nterms;
3456 }
3457
3458 static gretl_bundle *regls_bundle;
3459
selector_get_regls_bundle(void)3460 void *selector_get_regls_bundle (void)
3461 {
3462 return regls_bundle;
3463 }
3464
3465 /* add "advanced" options from @src, if present */
3466
regls_transcribe_advanced(gretl_bundle * rb,gretl_bundle * src,int xvalidate,int eid)3467 static void regls_transcribe_advanced (gretl_bundle *rb,
3468 gretl_bundle *src,
3469 int xvalidate,
3470 int eid)
3471 {
3472 int ccd = 0;
3473
3474 if (gretl_bundle_get_int(src, "timer", NULL)) {
3475 gretl_bundle_set_int(rb, "timer", 1);
3476 }
3477
3478 if ((eid == 0 && gretl_bundle_get_int(src, "lccd", NULL)) ||
3479 (eid == 1 && gretl_bundle_get_int(src, "rccd", NULL))) {
3480 ccd = 1;
3481 }
3482 gretl_bundle_set_int(rb, "ccd", ccd);
3483
3484 if (xvalidate) {
3485 int use_1se = gretl_bundle_get_int(src, "use_1se", NULL);
3486 double s = gretl_bundle_get_scalar(src, "seed", NULL);
3487
3488 gretl_bundle_set_int(rb, "use_1se", use_1se);
3489 if (gretl_bundle_get_int(src, "set_seed", NULL)) {
3490 gretl_bundle_set_scalar(rb, "seed", s);
3491 } else {
3492 gretl_bundle_delete_data(rb, "seed");
3493 }
3494 }
3495
3496 #ifdef HAVE_MPI
3497 if (xvalidate) {
3498 int no_mpi = gretl_bundle_get_int(src, "no_mpi", NULL);
3499
3500 gretl_bundle_set_int(rb, "no_mpi", no_mpi);
3501 }
3502 #endif
3503 }
3504
read_regls_extras(selector * sr)3505 static void read_regls_extras (selector *sr)
3506 {
3507 GtkWidget *w = sr->extra[REGLS_EST];
3508 gchar *estr = combo_box_get_active_text(w);
3509 gretl_bundle *rb = regls_bundle;
3510 int xvalidate = 0;
3511 int eid = 0;
3512
3513 gretl_bundle_void_content(rb);
3514 gretl_bundle_set_int(rb, "gui", 1);
3515
3516 if (!strcmp(estr, _("Elastic net"))) {
3517 GtkWidget *aspin = sr->extra[REGLS_ALPHA];
3518 double a = gtk_spin_button_get_value(GTK_SPIN_BUTTON(aspin));
3519
3520 if (a == 1.0) {
3521 ; /* LASSO */
3522 } else if (a == 0) {
3523 gretl_bundle_set_int(rb, "ridge", 1);
3524 eid = 1;
3525 } else {
3526 gretl_bundle_set_scalar(rb, "alpha", a);
3527 eid = 2;
3528 }
3529 } else if (!strcmp(estr, _("Ridge"))) {
3530 gretl_bundle_set_int(rb, "ridge", 1);
3531 eid = 1;
3532 }
3533
3534 if (gtk_widget_is_sensitive(sr->extra[REGLS_LAMVAL])) {
3535 GtkWidget *w = sr->extra[REGLS_LAMVAL];
3536 double lf = gtk_spin_button_get_value(GTK_SPIN_BUTTON(w));
3537
3538 gretl_bundle_set_scalar(rb, "lfrac", lf);
3539 } else {
3540 int nlam = spinner_get_int(sr->extra[REGLS_NLAM]);
3541
3542 gretl_bundle_set_int(rb, "nlambda", nlam);
3543 }
3544
3545 if (gtk_widget_is_sensitive(sr->extra[REGLS_NFOLDS])) {
3546 int nfolds = spinner_get_int(sr->extra[REGLS_NFOLDS]);
3547 gchar *ft = combo_box_get_active_text(sr->extra[REGLS_FTYPE]);
3548
3549 gretl_bundle_set_int(rb, "xvalidate", 1);
3550 gretl_bundle_set_int(rb, "nfolds", nfolds);
3551 if (!strcmp(ft, _("random"))) {
3552 gretl_bundle_set_int(rb, "randfolds", 1);
3553 }
3554 xvalidate = 1;
3555 }
3556
3557 if (gtk_widget_is_sensitive(sr->extra[REGLS_PLOT]) &&
3558 button_is_active(sr->extra[REGLS_PLOT])) {
3559 gretl_bundle_set_int(rb, "crit_plot", 1);
3560 }
3561
3562 if (regls_adv != NULL) {
3563 regls_transcribe_advanced(rb, regls_adv, xvalidate, eid);
3564 }
3565
3566 g_free(estr);
3567 }
3568
read_quantreg_extras(selector * sr)3569 static void read_quantreg_extras (selector *sr)
3570 {
3571 GtkWidget *w = gtk_bin_get_child(GTK_BIN(sr->extra[0]));
3572 const gchar *s = gtk_entry_get_text(GTK_ENTRY(w));
3573
3574 if (s == NULL || *s == '\0') {
3575 warnbox(_("You must specify a quantile"));
3576 sr->error = 1;
3577 } else {
3578 /* convert the GUI string to what ought to be a valid
3579 numerical matrix specification */
3580 gchar *tmp = g_strdup_printf("{%s}", s);
3581 gretl_matrix *m;
3582
3583 comma_separate_numbers(tmp);
3584 m = generate_matrix(tmp, dataset, &sr->error);
3585 gretl_matrix_free(m);
3586
3587 if (sr->error) {
3588 warnbox(_("Invalid quantile specification"));
3589 } else {
3590 add_to_cmdlist(sr, tmp);
3591 add_to_cmdlist(sr, " ");
3592 }
3593 g_free(tmp);
3594 }
3595
3596 w = sr->extra[1];
3597
3598 if (!sr->error && w != NULL && gtk_widget_is_sensitive(w)) {
3599 GtkAdjustment *adj;
3600
3601 adj = gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(w));
3602 set_optval_double(QUANTREG, OPT_I, gtk_adjustment_get_value(adj));
3603 }
3604 }
3605
read_logistic_extras(selector * sr)3606 static void read_logistic_extras (selector *sr)
3607 {
3608 GtkWidget *w = sr->extra[1];
3609
3610 if (w != NULL && gtk_widget_is_sensitive(w)) {
3611 GtkAdjustment *adj;
3612
3613 adj = gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(w));
3614 set_optval_double(sr->ci, OPT_M, gtk_adjustment_get_value(adj));
3615 }
3616 }
3617
read_omit_cutoff(selector * sr)3618 static void read_omit_cutoff (selector *sr)
3619 {
3620 if (sr->extra[0] != NULL && gtk_widget_is_sensitive(sr->extra[0])) {
3621 double val, orig;
3622 int err = 0;
3623
3624 orig = get_optval_double(OMIT, OPT_A, &err);
3625 val = gtk_spin_button_get_value(GTK_SPIN_BUTTON(sr->extra[0]));
3626 if (val != orig) {
3627 set_optval_double(OMIT, OPT_A, val);
3628 }
3629 }
3630 }
3631
read_reprobit_quadpoints(selector * sr)3632 static void read_reprobit_quadpoints (selector *sr)
3633 {
3634 if (sr->extra[0] != NULL && GTK_IS_SPIN_BUTTON(sr->extra[0])) {
3635 int qp = spinner_get_int(sr->extra[0]);
3636
3637 set_optval_int(PROBIT, OPT_G, qp);
3638 }
3639 }
3640
3641 #define TOBIT_UNSET -1.0e300
3642
read_tobit_limits(selector * sr)3643 static void read_tobit_limits (selector *sr)
3644 {
3645 double lval = 0, rval = NADBL;
3646 const char *s;
3647 int err = 0;
3648
3649 s = gtk_entry_get_text(GTK_ENTRY(sr->extra[0]));
3650 if (*s != '\0') {
3651 if (strcmp(s, "NA") == 0) {
3652 lval = TOBIT_UNSET;
3653 } else {
3654 err = check_atof(s);
3655 if (err) {
3656 warnbox(gretl_errmsg_get());
3657 sr->error = 1;
3658 return;
3659 } else {
3660 lval = atof(s);
3661 }
3662 }
3663 }
3664
3665 s = gtk_entry_get_text(GTK_ENTRY(sr->extra[1]));
3666 if (*s != '\0' && strcmp(s, "NA")) {
3667 err = check_atof(s);
3668 if (err) {
3669 warnbox(gretl_errmsg_get());
3670 sr->error = 1;
3671 return;
3672 } else {
3673 rval = atof(s);
3674 }
3675 }
3676
3677 /* record the user's choices */
3678 tobit_lo = (lval == TOBIT_UNSET)? NADBL : lval;
3679 tobit_hi = rval;
3680
3681 if (lval == 0 && na(rval)) {
3682 ; /* the default, no-op */
3683 } else {
3684 if (lval != TOBIT_UNSET) {
3685 sr->opts |= OPT_L;
3686 set_optval_double(TOBIT, OPT_L, lval);
3687 }
3688 if (!na(rval)) {
3689 sr->opts |= OPT_M;
3690 set_optval_double(TOBIT, OPT_M, rval);
3691 }
3692 }
3693 }
3694
read_np_extras(selector * sr)3695 static void read_np_extras (selector *sr)
3696 {
3697 char s[32];
3698
3699 if (sr->ci == LOESS) {
3700 int d = spinner_get_int(sr->extra[1]);
3701 double q;
3702
3703 q = gtk_spin_button_get_value(GTK_SPIN_BUTTON(sr->extra[2]));
3704 sprintf(s, " d=%d q=%g", d, q);
3705 add_to_cmdlist(sr, s);
3706 if (button_is_active(sr->extra[3])) {
3707 sr->opts |= OPT_R;
3708 }
3709 } else if (sr->ci == NADARWAT) {
3710 GtkWidget *w = sr->extra[1];
3711 double h;
3712
3713 if (w != NULL && gtk_widget_is_sensitive(w)) {
3714 h = gtk_spin_button_get_value(GTK_SPIN_BUTTON(w));
3715 sprintf(s, " h=%g", h);
3716 add_to_cmdlist(sr, s);
3717 }
3718 if (button_is_active(sr->extra[2])) {
3719 sr->opts |= OPT_O;
3720 }
3721 }
3722 }
3723
cluster_option_is_active(selector * sr)3724 static int cluster_option_is_active (selector *sr)
3725 {
3726 GtkWidget *hcb = sr->hccme_button;
3727
3728 if (hcb != NULL && gtk_widget_is_sensitive(hcb) &&
3729 GTK_IS_BUTTON(hcb)) {
3730 const gchar *s = gtk_button_get_label(GTK_BUTTON(hcb));
3731
3732 return s != NULL && strcmp(s, _("Cluster")) == 0;
3733 } else {
3734 return 0;
3735 }
3736 }
3737
maybe_read_cluster_var(selector * sr)3738 static void maybe_read_cluster_var (selector *sr)
3739 {
3740 if (cluster_option_is_active(sr)) {
3741 set_optval_string(sr->ci, OPT_C, cluster_var);
3742 sr->opts |= OPT_C;
3743 }
3744 }
3745
maybe_read_var_hac_option(selector * sr)3746 static void maybe_read_var_hac_option (selector *sr)
3747 {
3748 GtkWidget *b = sr->hccme_button;
3749
3750 if (b != NULL && gtk_widget_is_sensitive(b) &&
3751 GTK_IS_COMBO_BOX(b)) {
3752 gint i = gtk_combo_box_get_active(GTK_COMBO_BOX(b));
3753
3754 if (i == 1) {
3755 sr->opts |= OPT_H;
3756 }
3757 }
3758 }
3759
3760 #define extra_widget_get_int(c) (c == HECKIT || \
3761 c == BIPROBIT || \
3762 c == INTREG || \
3763 c == COUNTMOD || \
3764 c == DURATION || \
3765 c == WLS || \
3766 THREE_VARS_CODE(c) || \
3767 NONPARAM_CODE(c))
3768
3769 #define offer_cluster_option(c) (dataset_is_cross_section(dataset) && \
3770 cluster_option_ok(c))
3771
parse_extra_widgets(selector * sr,char * endbit)3772 static void parse_extra_widgets (selector *sr, char *endbit)
3773 {
3774 const gchar *txt = NULL;
3775 int k = 0;
3776
3777 if (offer_cluster_option(sr->ci)) {
3778 maybe_read_cluster_var(sr);
3779 }
3780
3781 if (sr->ci == QUANTREG) {
3782 read_quantreg_extras(sr);
3783 return;
3784 } else if (sr->ci == REGLS) {
3785 read_regls_extras(sr);
3786 return;
3787 }
3788
3789 if (sr->ci == LOGISTIC || sr->ci == FE_LOGISTIC) {
3790 read_logistic_extras(sr);
3791 return;
3792 }
3793
3794 if (sr->ci == ELLIPSE) {
3795 read_ellipse_alpha(sr);
3796 return;
3797 }
3798
3799 if (sr->ci == OMIT) {
3800 read_omit_cutoff(sr);
3801 return;
3802 }
3803
3804 if (sr->ci == TOBIT) {
3805 read_tobit_limits(sr);
3806 return;
3807 }
3808
3809 if (sr->ci == REPROBIT) {
3810 read_reprobit_quadpoints(sr);
3811 return;
3812 }
3813
3814 if (sr->ci == WLS || sr->ci == COUNTMOD || sr->ci == DURATION ||
3815 sr->ci == AR || sr->ci == HECKIT || sr->ci == BIPROBIT ||
3816 sr->ci == INTREG || THREE_VARS_CODE(sr->ci) ||
3817 NONPARAM_CODE(sr->ci)) {
3818 txt = gtk_entry_get_text(GTK_ENTRY(sr->extra[0]));
3819 if (txt == NULL || *txt == '\0') {
3820 if (sr->ci == WLS) {
3821 warnbox(_("You must select a weight variable"));
3822 sr->error = 1;
3823 } else if (sr->ci == AR) {
3824 warnbox(_("You must specify a list of lags"));
3825 sr->error = 1;
3826 } else if (sr->ci == HECKIT) {
3827 warnbox(_("You must specify a selection variable"));
3828 sr->error = 1;
3829 } else if (sr->ci == BIPROBIT) {
3830 warnbox(_("You must specify a second dependent variable"));
3831 sr->error = 1;
3832 } else if (sr->ci == INTREG) {
3833 warnbox(_("You must specify an upper bound variable"));
3834 sr->error = 1;
3835 } else if (sr->ci == ANOVA) {
3836 warnbox(_("You must specify a treatment variable"));
3837 sr->error = 1;
3838 } else if (NONPARAM_CODE(sr->ci)) {
3839 warnbox(_("You must specify an independent variable"));
3840 sr->error = 1;
3841 } else if (THREE_VARS_CODE(sr->ci)) {
3842 warnbox(("You must select a Y-axis variable"));
3843 sr->error = 1;
3844 } else if (sr->ci == COUNTMOD || sr->ci == DURATION) {
3845 /* empty 'extra' field is OK */
3846 return;
3847 }
3848 }
3849 }
3850
3851 if (sr->error) {
3852 return;
3853 }
3854
3855 if (extra_widget_get_int(sr->ci)) {
3856 k = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(sr->extra[0]), "data"));
3857 }
3858
3859 if (sr->ci == ANOVA) {
3860 /* treatment var */
3861 cmdlist_append_series(sr, " ", k);
3862 } else if (sr->ci == WLS || THREE_VARS_CODE(sr->ci)) {
3863 /* weight or y-axis var */
3864 cmdlist_append_series(sr, NULL, k);
3865 add_to_cmdlist(sr, " ");
3866 if (sr->ci == WLS) {
3867 wtvar = k;
3868 }
3869 } else if (sr->ci == INTREG) {
3870 /* upper-bound var */
3871 cmdlist_append_series(sr, " ", k);
3872 add_to_cmdlist(sr, " ");
3873 hivar = k;
3874 } else if (sr->ci == COUNTMOD) {
3875 /* offset variable */
3876 print_list_element(sr, endbit, " ; ", k);
3877 offvar = k;
3878 } else if (sr->ci == DURATION) {
3879 /* censoring variable */
3880 print_list_element(sr, endbit, " ; ", k);
3881 censvar = k;
3882 } else if (sr->ci == HECKIT) {
3883 /* selection variable */
3884 print_list_element(sr, endbit, " ", k);
3885 selvar = k;
3886 } else if (sr->ci == BIPROBIT) {
3887 /* depvar #2 */
3888 print_list_element(sr, endbit, " ", k);
3889 } else if (NONPARAM_CODE(sr->ci)) {
3890 /* independent var */
3891 print_list_element(sr, endbit, " ", k);
3892 } else if (sr->ci == AR) {
3893 /* lags */
3894 free(arlags);
3895 arlags = gretl_strdup(txt);
3896 add_to_cmdlist(sr, txt);
3897 add_to_cmdlist(sr, " ; ");
3898 }
3899 }
3900
vec_get_spinner_data(selector * sr,int * order)3901 static void vec_get_spinner_data (selector *sr, int *order)
3902 {
3903 const int *llist;
3904 char numstr[16];
3905
3906 /* check for list of specific lags */
3907 llist = get_VAR_lags_list();
3908
3909 if (llist != NULL) {
3910 /* "gappy" lag specification for VAR */
3911 char *dvlags;
3912
3913 dvlags = gretl_list_to_lags_string(llist, &sr->error);
3914 if (dvlags != NULL) {
3915 add_to_cmdlist(sr, dvlags);
3916 free(dvlags);
3917 }
3918 } else {
3919 *order = spinner_get_int(sr->extra[0]);
3920 sprintf(numstr, "%d", *order);
3921 add_to_cmdlist(sr, numstr);
3922 }
3923
3924 if (sr->ci == VECM) {
3925 /* cointegration rank */
3926 jrank = spinner_get_int(sr->extra[1]);
3927 sprintf(numstr, " %d", jrank);
3928 add_to_cmdlist(sr, numstr);
3929 }
3930 }
3931
parse_depvar_widget(selector * sr,char * endbit,char ** dvlags,char ** idvlags)3932 static void parse_depvar_widget (selector *sr, char *endbit,
3933 char **dvlags,
3934 char **idvlags)
3935 {
3936 int ynum = selector_get_depvar_number(sr);
3937
3938 if (ynum < 0) {
3939 topslot_empty(sr->ci);
3940 sr->error = 1;
3941 } else {
3942 if (sr->ci == GR_XY || sr->ci == GR_IMP) {
3943 print_list_element(sr, endbit, " ", ynum);
3944 } else if (sr->ci == BIPROBIT) {
3945 cmdlist_append_series(sr, NULL, ynum);
3946 add_to_cmdlist(sr, endbit);
3947 *endbit = '\0';
3948 } else {
3949 cmdlist_append_series(sr, NULL, ynum);
3950 }
3951
3952 if (select_lags_depvar(sr->ci) && dataset_lags_ok(dataset)) {
3953 *dvlags = get_lagpref_string(ynum, LAG_Y_X, NULL);
3954 if (USE_ZLIST(sr->ci)) {
3955 *idvlags = get_lagpref_string(ynum, LAG_Y_W, NULL);
3956 }
3957 }
3958
3959 if (sr->default_check != NULL) {
3960 if (button_is_active(sr->default_check)) {
3961 default_y = ynum;
3962 } else {
3963 default_y = -1;
3964 }
3965 } else if (sr->ci == INTREG) {
3966 lovar = ynum;
3967 }
3968 }
3969 }
3970
parse_third_var_slot(selector * sr)3971 static void parse_third_var_slot (selector *sr)
3972 {
3973 const gchar *txt = gtk_entry_get_text(GTK_ENTRY(sr->rvars1));
3974
3975 if (txt == NULL || *txt == '\0') {
3976 if (sr->ci == ANOVA) {
3977 /* third var is optional */
3978 return;
3979 } else if (sr->ci == GR_3D) {
3980 warnbox(_("You must select a Z-axis variable"));
3981 } else if (sr->ci == GR_DUMMY || sr->ci == GR_FBOX) {
3982 warnbox(_("You must select a factor variable"));
3983 } else {
3984 warnbox(_("You must select a control variable"));
3985 }
3986 sr->error = 1;
3987 } else {
3988 int v = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(sr->rvars1),
3989 "data"));
3990
3991 cmdlist_append_series(sr, " ", v);
3992 }
3993 }
3994
3995 /* lag order for the dependent variable in midasreg */
3996
midas_process_AR_spin(selector * sr)3997 static void midas_process_AR_spin (selector *sr)
3998 {
3999 int yno = selector_get_depvar_number(sr);
4000
4001 if (sr->extra[0] != NULL && yno > 0 && yno < dataset->v) {
4002 const char *yname = dataset->varname[yno];
4003 int p = spinner_get_int(sr->extra[0]);
4004 gchar *bit = NULL;
4005
4006 if (p == 1) {
4007 bit = g_strdup_printf(" %s(-1)", yname);
4008 } else if (p > 1) {
4009 bit = g_strdup_printf(" %s(-1 to -%d)", yname, p);
4010 }
4011 if (bit != NULL) {
4012 add_to_cmdlist(sr, bit);
4013 g_free(bit);
4014 }
4015 mds_order = p;
4016 }
4017 }
4018
selector_cancel_unavailable_options(selector * sr)4019 static void selector_cancel_unavailable_options (selector *sr)
4020 {
4021 if (sr->ci == ARMA) {
4022 if ((sr->opts & OPT_H) && !gtk_widget_is_sensitive(sr->hess_button)) {
4023 sr->opts ^= OPT_H;
4024 }
4025 } else if (sr->ci == CORR) {
4026 if (sr->opts & OPT_N && !gtk_widget_is_sensitive(sr->extra[0])) {
4027 sr->opts ^= OPT_N;
4028 }
4029 }
4030 }
4031
get_anova_list(selector * sr)4032 static void get_anova_list (selector *sr)
4033 {
4034 /* get response var */
4035 parse_depvar_widget(sr, NULL, NULL, NULL);
4036 if (sr->error < 0) {
4037 return;
4038 }
4039
4040 /* get treatment var */
4041 parse_extra_widgets(sr, NULL);
4042 if (sr->error) {
4043 return;
4044 }
4045
4046 /* get (optional) block var */
4047 parse_third_var_slot(sr);
4048 }
4049
4050 /* main function for building a command list from information stored
4051 in the various selector widgets */
4052
compose_cmdlist(selector * sr)4053 static void compose_cmdlist (selector *sr)
4054 {
4055 gint rows = 0, realrows = 0;
4056 char endbit[64] = {0};
4057 char *dvlags = NULL;
4058 char *idvlags = NULL;
4059 int context = 0;
4060 int order = 0;
4061
4062 sr->error = 0;
4063 sr->cmdlist = mymalloc(MAXLEN);
4064
4065 if (sr->cmdlist == NULL) {
4066 return;
4067 }
4068
4069 sr->cmdsize = MAXLEN;
4070 sr->cmdlen = 0;
4071 *sr->cmdlist = '\0';
4072
4073 if (sr->ci == INTREG) {
4074 parse_depvar_widget(sr, endbit, &dvlags, &idvlags);
4075 if (!sr->error) {
4076 parse_extra_widgets(sr, endbit);
4077 }
4078 goto int_next;
4079 }
4080
4081 if (sr->ci == ANOVA) {
4082 /* special: either 2 or 3 variables selected */
4083 get_anova_list(sr);
4084 return;
4085 }
4086
4087 /* deal with content of "extra" widgets */
4088 if (sr->ci == ARMA) {
4089 arma_spec_to_cmdlist(sr);
4090 } else if (sr->ci == ARCH ||
4091 sr->ci == GARCH ||
4092 sr->ci == DPANEL) {
4093 add_pdq_vals_to_cmdlist(sr);
4094 } else if (VEC_CODE(sr->ci)) {
4095 vec_get_spinner_data(sr, &order);
4096 if (!sr->error) {
4097 if (sr->ci == VAR) {
4098 maybe_read_var_hac_option(sr);
4099 } else if (sr->ci == COINT && !sr->error) {
4100 read_coint_opt_parm(sr);
4101 }
4102 }
4103 } else {
4104 parse_extra_widgets(sr, endbit);
4105 }
4106
4107 /* deal with the "depvar" widget */
4108 if (!sr->error && sr->depvar != NULL) {
4109 parse_depvar_widget(sr, endbit, &dvlags, &idvlags);
4110 }
4111
4112 int_next:
4113
4114 /* bail out if things have gone wrong already */
4115 if (sr->error) {
4116 return;
4117 }
4118
4119 if (sr->ci == GR_FBOX || THREE_VARS_CODE(sr->ci)) {
4120 parse_third_var_slot(sr);
4121 return;
4122 }
4123
4124 /* count the rows (variables) in the "primary" right-hand selection
4125 list box */
4126 rows = varlist_row_count(sr, SR_RVARS1, &realrows);
4127
4128 if (sr->ci == SCATTERS) {
4129 if (rows > 0) {
4130 add_to_cmdlist(sr, " ;");
4131 } else {
4132 sr->error = E_ARGS;
4133 gui_errmsg(sr->error);
4134 return;
4135 }
4136 }
4137
4138 if ((sr->ci == COINT || sr->ci == COINT2 || sr->ci == VECM) && rows < 2) {
4139 warnbox(_("You must select two or more endogenous variables"));
4140 sr->error = 1;
4141 return;
4142 } else if ((sr->ci == VAR || sr->ci == VLAGSEL) && rows < 1) {
4143 warnbox(_("You must select a dependent variable"));
4144 sr->error = 1;
4145 return;
4146 } else if (MODEL_NEEDS_X(sr->ci) && rows < 1) {
4147 warnbox(_("You must specify an independent variable"));
4148 sr->error = 1;
4149 return;
4150 }
4151
4152 if (realrows > 0) {
4153 maybe_resize_recorder_lists(sr, realrows);
4154 }
4155
4156 /* primary RHS varlist */
4157 if (sr->rvars1 != NULL) {
4158 context = sr_get_lag_context(sr, SR_RVARS1);
4159 get_rvars1_data(sr, rows, context);
4160 }
4161
4162 if (sr->ci == MIDASREG) {
4163 /* FIXME placement of this? */
4164 midas_process_AR_spin(sr);
4165 }
4166
4167 if (sr->ci == MIDASREG) {
4168 /* read special material from lower right */
4169 get_midas_specs(sr);
4170 } else if (USE_ZLIST(sr->ci) || USE_VECXLIST(sr->ci)) {
4171 /* cases with a (possibly optional) secondary RHS list */
4172 rows = varlist_row_count(sr, SR_RVARS2, &realrows);
4173 if (rows > 0) {
4174 if (realrows > 0) {
4175 maybe_resize_exog_recorder_lists(sr, realrows);
4176 }
4177 context = sr_get_lag_context(sr, SR_RVARS2);
4178
4179 if (USE_ZLIST(sr->ci) && dvlags != NULL) {
4180 add_to_cmdlist(sr, dvlags);
4181 free(dvlags);
4182 dvlags = NULL;
4183 }
4184
4185 if (sr->ci == HECKIT) {
4186 add_to_cmdlist(sr, " ;");
4187 add_to_cmdlist(sr, endbit);
4188 *endbit = '\0';
4189 } else if (*sr->cmdlist != '\0') {
4190 add_to_cmdlist(sr, " ;");
4191 }
4192
4193 sr->error = get_rvars2_data(sr, rows, context);
4194 } else if (IV_MODEL(sr->ci)) {
4195 warnbox(_("You must specify a set of instrumental variables"));
4196 sr->error = 1;
4197 } else if (sr->ci == HECKIT) {
4198 warnbox(_("You must specify regressors for the selection equation"));
4199 sr->error = 1;
4200 }
4201 }
4202
4203 /* deal with any trailing strings */
4204 if (!sr->error) {
4205 if (endbit[0] != '\0') {
4206 add_to_cmdlist(sr, endbit);
4207 } else if (dvlags != NULL) {
4208 add_to_cmdlist(sr, dvlags);
4209 free(dvlags);
4210 } else if (idvlags != NULL) {
4211 add_to_cmdlist(sr, idvlags);
4212 free(idvlags);
4213 }
4214 if (NONPARAM_CODE(sr->ci)) {
4215 read_np_extras(sr);
4216 }
4217 }
4218
4219 if ((sr->ci == SCATTERS) && !sr->error) {
4220 int xstate;
4221
4222 xstate = gtk_combo_box_get_active(GTK_COMBO_BOX(multiplot_menu));
4223 if (xstate) {
4224 reverse_list(sr->cmdlist);
4225 }
4226 }
4227
4228 #if 0
4229 fprintf(stderr, "sr->cmdlist:\n'%s'\n", sr->cmdlist);
4230 #endif
4231
4232 if (!sr->error) {
4233 /* record some choices as defaults */
4234 if (sr->ci == VECM || sr->ci == VAR || sr->ci == VLAGSEL) {
4235 want_seasonals = (sr->opts & OPT_D)? 1 : 0;
4236 }
4237 if (sr->ci == VECM || sr->ci == VAR || sr->ci == ARCH) {
4238 default_order = (order < 0)? -order : order;
4239 }
4240 if (sr->ci == VAR || sr->ci == VLAGSEL) {
4241 vartrend = (sr->opts & OPT_T)? 1 : 0;
4242 } else if (sr->ci == ARMA) {
4243 arma_const = (sr->opts & OPT_N)? 0 : 1;
4244 arma_hessian = (sr->opts & OPT_G)? 0 : 1;
4245 arima_xdiff = (sr->opts & OPT_Y)? 0 : 1;
4246 arma_x12 = (sr->opts & OPT_X)? 1 : 0;
4247 } else if (sr->ci == GARCH) {
4248 garch_const = (sr->opts & OPT_N)? 0 : 1;
4249 } else if (sr->ci == LOGIT || sr->ci == PROBIT) {
4250 lp_pvals = (sr->opts & OPT_P)? 1 : 0;
4251 } else if (sr->ci == DPANEL) {
4252 dpd_2step = (sr->opts & OPT_T)? 1 : 0;
4253 dpd_asy = (sr->opts & OPT_A)? 1 : 0;
4254 dpd_dpd = (sr->opts & OPT_X)? 1 : 0;
4255 } else if (NONPARAM_CODE(sr->ci)) {
4256 nonparam_record_xvar(endbit);
4257 }
4258
4259 /* panel: scrub --nerlove if not doing random effects */
4260 if (sr->ci == PANEL) {
4261 if ((sr->opts & OPT_N) && !(sr->opts & OPT_U)) {
4262 sr->opts &= ~OPT_N;
4263 }
4264 }
4265
4266 verbose = (sr->opts & OPT_V)? 1 : 0;
4267 }
4268
4269 selector_cancel_unavailable_options(sr);
4270 }
4271
cancel_selector(GtkWidget * widget,selector * sr)4272 static void cancel_selector (GtkWidget *widget, selector *sr)
4273 {
4274 if (open_selector != NULL) {
4275 gtk_widget_destroy(sr->dlg);
4276 }
4277 }
4278
destroy_selector(GtkWidget * w,selector * sr)4279 static void destroy_selector (GtkWidget *w, selector *sr)
4280 {
4281 if (sr->blocking) {
4282 gtk_main_quit();
4283 }
4284
4285 if (sr->state_pushed) {
4286 pop_program_state();
4287 }
4288
4289 free(sr->cmdlist);
4290 free(sr->extra_data);
4291 free(sr);
4292
4293 open_selector = NULL;
4294 }
4295
estimator_label(int ci)4296 static char *estimator_label (int ci)
4297 {
4298 switch (ci) {
4299 case OLS:
4300 return N_("OLS");
4301 case HSK:
4302 return N_("Heteroskedasticity corrected");
4303 case AR1:
4304 return N_("AR(1) errors");
4305 case LOGIT:
4306 return N_("Logit");
4307 case OLOGIT:
4308 return N_("Ordered Logit");
4309 case MLOGIT:
4310 return N_("Multinomial Logit");
4311 case PROBIT:
4312 return N_("Probit");
4313 case OPROBIT:
4314 return N_("Ordered Probit");
4315 case REPROBIT:
4316 return N_("Random effects (binary) probit");
4317 case TOBIT:
4318 return N_("Tobit");
4319 case HECKIT:
4320 return N_("Heckit");
4321 case BIPROBIT:
4322 return N_("Bivariate probit");
4323 case LOGISTIC:
4324 return N_("Logistic");
4325 case FE_LOGISTIC:
4326 return N_("Fixed effects logistic model");
4327 case COUNTMOD:
4328 return N_("Count data model");
4329 case DURATION:
4330 return N_("Duration model");
4331 case PANEL:
4332 return N_("Panel model");
4333 case PANEL_WLS:
4334 return N_("Groupwise WLS");
4335 case PANEL_B:
4336 return N_("Between-groups model");
4337 case DPANEL:
4338 return N_("Dynamic panel model");
4339 case WLS:
4340 return N_("Weighted least squares");
4341 case IVREG:
4342 return N_("Two-stage least squares");
4343 case IV_LIML:
4344 return N_("Limited information maximum likelihood");
4345 case IV_GMM:
4346 return N_("Generalized method of moments");
4347 case AR:
4348 return N_("Autoregressive errors");
4349 case ARMA:
4350 return N_("ARIMA");
4351 case ARCH:
4352 return N_("ARCH");
4353 case GARCH:
4354 return N_("GARCH");
4355 case VAR:
4356 return N_("VAR");
4357 case VLAGSEL:
4358 return N_("VAR lag selection");
4359 case VECM:
4360 return N_("VECM");
4361 case LAD:
4362 return N_("LAD");
4363 case QUANTREG:
4364 return N_("Quantile regression");
4365 case INTREG:
4366 return N_("Interval regression");
4367 case COINT:
4368 return N_("Cointegration (Engle-Granger)");
4369 case COINT2:
4370 return N_("Cointegration (Johansen)");
4371 case MPOLS:
4372 return N_("Multiple precision OLS");
4373 case LOESS:
4374 return N_("Loess");
4375 case NADARWAT:
4376 return N_("Nadaraya-Watson");
4377 case MIDASREG:
4378 return N_("MIDAS regression");
4379 case REGLS:
4380 return N_("Regularized least squares");
4381 default:
4382 return "";
4383 }
4384 }
4385
extra_var_string(int ci)4386 static char *extra_var_string (int ci)
4387 {
4388 switch (ci) {
4389 case WLS:
4390 return N_("Weight variable");
4391 case COUNTMOD:
4392 return N_("Offset variable");
4393 case DURATION:
4394 return N_("Censoring variable");
4395 case HECKIT:
4396 return N_("Selection variable");
4397 case BIPROBIT:
4398 return N_("Dependent variable 2");
4399 case AR:
4400 return N_("List of AR lags");
4401 case QUANTREG:
4402 return N_("Desired quantile(s)");
4403 case INTREG:
4404 return N_("Upper bound variable");
4405 case GR_DUMMY:
4406 case GR_3D:
4407 case GR_XYZ:
4408 return N_("Y-axis variable");
4409 case ANOVA:
4410 return N_("Treatment variable");
4411 case LOESS:
4412 case NADARWAT:
4413 return N_("Independent variable");
4414 default:
4415 return NULL;
4416 }
4417 }
4418
flip_multiplot_axis(GtkComboBox * box,gpointer p)4419 static gint flip_multiplot_axis (GtkComboBox *box, gpointer p)
4420 {
4421 gint xstate = gtk_combo_box_get_active(box);
4422
4423 if (xstate) {
4424 gtk_label_set_text(GTK_LABEL(multiplot_label), _("Y-axis variables"));
4425 } else {
4426 gtk_label_set_text(GTK_LABEL(multiplot_label), _("X-axis variables"));
4427 }
4428
4429 return FALSE;
4430 }
4431
multiplot_popdown(int ci)4432 static GtkWidget *multiplot_popdown (int ci)
4433 {
4434 GtkWidget *w = gtk_combo_box_text_new();
4435
4436 combo_box_append_text(w, _("Y-axis variable"));
4437 combo_box_append_text(w, _("X-axis variable"));
4438 gtk_combo_box_set_active(GTK_COMBO_BOX(w), 0);
4439
4440 g_signal_connect(G_OBJECT(GTK_COMBO_BOX(w)), "changed",
4441 G_CALLBACK(flip_multiplot_axis), NULL);
4442
4443 multiplot_menu = w;
4444
4445 return w;
4446 }
4447
set_count_data_option(GtkComboBox * box,selector * sr)4448 static gint set_count_data_option (GtkComboBox *box, selector *sr)
4449 {
4450 gint i = gtk_combo_box_get_active(box);
4451
4452 if (i == 0) {
4453 /* Poisson */
4454 sr->opts &= ~(OPT_N | OPT_M);
4455 } else if (i == 1) {
4456 /* NegBin 2 */
4457 sr->opts &= ~OPT_M;
4458 sr->opts |= OPT_N;
4459 } else {
4460 /* NegBin 1 */
4461 sr->opts |= OPT_M;
4462 }
4463
4464 return FALSE;
4465 }
4466
build_count_data_popdown(selector * sr)4467 static void build_count_data_popdown (selector *sr)
4468 {
4469 GtkWidget *w = gtk_combo_box_text_new();
4470 GtkWidget *hbox, *label;
4471
4472 combo_box_append_text(w, _("Poisson"));
4473 combo_box_append_text(w, _("NegBin 2"));
4474 combo_box_append_text(w, _("NegBin 1"));
4475
4476 g_signal_connect(G_OBJECT(GTK_COMBO_BOX(w)), "changed",
4477 G_CALLBACK(set_count_data_option), sr);
4478
4479 hbox = gtk_hbox_new(FALSE, 5);
4480 label = gtk_label_new(_("Distribution:"));
4481 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
4482 gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 0);
4483 gtk_box_pack_start(GTK_BOX(sr->vbox), hbox, FALSE, FALSE, 5);
4484
4485 if (model_opt & OPT_M) {
4486 sr->opts |= OPT_M;
4487 gtk_combo_box_set_active(GTK_COMBO_BOX(w), 2);
4488 } else if (model_opt & OPT_N) {
4489 sr->opts |= OPT_N;
4490 gtk_combo_box_set_active(GTK_COMBO_BOX(w), 1);
4491 } else {
4492 gtk_combo_box_set_active(GTK_COMBO_BOX(w), 0);
4493 }
4494 }
4495
set_duration_option(GtkComboBox * box,selector * sr)4496 static gint set_duration_option (GtkComboBox *box, selector *sr)
4497 {
4498 gint i = gtk_combo_box_get_active(box);
4499
4500 if (i == 0) {
4501 /* Weibull */
4502 sr->opts &= ~(OPT_E | OPT_L | OPT_Z);
4503 } else if (i == 1) {
4504 /* Exponential */
4505 sr->opts &= ~(OPT_L | OPT_Z);
4506 sr->opts |= OPT_E;
4507 } else if (i == 2) {
4508 /* Log-logistic */
4509 sr->opts &= ~(OPT_E | OPT_Z);
4510 sr->opts |= OPT_L;
4511 } else {
4512 /* Log-normal */
4513 sr->opts &= ~(OPT_E | OPT_L);
4514 sr->opts |= OPT_Z;
4515 }
4516
4517 return FALSE;
4518 }
4519
build_duration_popdown(selector * sr)4520 static void build_duration_popdown (selector *sr)
4521 {
4522 GtkWidget *w = gtk_combo_box_text_new();
4523 GtkWidget *hbox, *label;
4524
4525 combo_box_append_text(w, _("Weibull"));
4526 combo_box_append_text(w, _("Exponential"));
4527 combo_box_append_text(w, _("Log-logistic"));
4528 combo_box_append_text(w, _("Log-normal"));
4529
4530 g_signal_connect(G_OBJECT(GTK_COMBO_BOX(w)), "changed",
4531 G_CALLBACK(set_duration_option), sr);
4532
4533 hbox = gtk_hbox_new(FALSE, 5);
4534 label = gtk_label_new(_("Distribution:"));
4535 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
4536 gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 0);
4537 gtk_box_pack_start(GTK_BOX(sr->vbox), hbox, FALSE, FALSE, 5);
4538
4539 if (model_opt & OPT_E) {
4540 sr->opts |= OPT_E;
4541 gtk_combo_box_set_active(GTK_COMBO_BOX(w), 1);
4542 } else if (model_opt & OPT_L) {
4543 sr->opts |= OPT_L;
4544 gtk_combo_box_set_active(GTK_COMBO_BOX(w), 2);
4545 } else if (model_opt & OPT_Z) {
4546 sr->opts |= OPT_Z;
4547 gtk_combo_box_set_active(GTK_COMBO_BOX(w), 3);
4548 } else {
4549 gtk_combo_box_set_active(GTK_COMBO_BOX(w), 0);
4550 }
4551 }
4552
set_gmm_est_option(GtkComboBox * box,selector * sr)4553 static gint set_gmm_est_option (GtkComboBox *box, selector *sr)
4554 {
4555 gint i = gtk_combo_box_get_active(box);
4556
4557 if (i == 0) {
4558 /* 1-step */
4559 sr->opts &= ~(OPT_I | OPT_T);
4560 } else if (i == 1) {
4561 /* 2-step */
4562 sr->opts |= OPT_T;
4563 } else {
4564 /* iterated */
4565 sr->opts |= OPT_I;
4566 }
4567
4568 return FALSE;
4569 }
4570
build_gmm_popdown(selector * sr)4571 static void build_gmm_popdown (selector *sr)
4572 {
4573 GtkWidget *w = gtk_combo_box_text_new();
4574 GtkWidget *hbox;
4575
4576 combo_box_append_text(w, _("One-step estimation"));
4577 combo_box_append_text(w, _("Two-step estimation"));
4578 combo_box_append_text(w, _("Iterated estimation"));
4579
4580 g_signal_connect(G_OBJECT(GTK_COMBO_BOX(w)), "changed",
4581 G_CALLBACK(set_gmm_est_option), sr);
4582
4583 hbox = gtk_hbox_new(FALSE, 5);
4584 gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 0);
4585 gtk_box_pack_start(GTK_BOX(sr->vbox), hbox, FALSE, FALSE, 5);
4586
4587 if (model_opt & OPT_I) {
4588 sr->opts |= OPT_I;
4589 gtk_combo_box_set_active(GTK_COMBO_BOX(w), 2);
4590 } else if (model_opt & OPT_T) {
4591 sr->opts |= OPT_T;
4592 gtk_combo_box_set_active(GTK_COMBO_BOX(w), 1);
4593 } else {
4594 gtk_combo_box_set_active(GTK_COMBO_BOX(w), 0);
4595 }
4596 }
4597
table_add_left(selector * sr,GtkWidget * child,int startrow,int endrow)4598 static void table_add_left (selector *sr,
4599 GtkWidget *child,
4600 int startrow,
4601 int endrow)
4602 {
4603 guint xpad = 4, ypad = 2;
4604
4605 gtk_table_attach(GTK_TABLE(sr->table), child,
4606 0, 1, startrow, endrow,
4607 GTK_EXPAND | GTK_SHRINK | GTK_FILL,
4608 GTK_EXPAND | GTK_SHRINK | GTK_FILL,
4609 xpad, ypad);
4610 }
4611
maybe_add_row(selector * sr)4612 static void maybe_add_row (selector *sr)
4613 {
4614 if (sr->row + 1 > sr->n_rows) {
4615 sr->n_rows += 1;
4616 gtk_table_resize(GTK_TABLE(sr->table),
4617 sr->n_rows, 3);
4618 }
4619 }
4620
table_add_mid(selector * sr,GtkWidget * child)4621 static void table_add_mid (selector *sr,
4622 GtkWidget *child)
4623 {
4624 guint xpad = 4, ypad = 2;
4625
4626 maybe_add_row(sr);
4627 gtk_table_attach(GTK_TABLE(sr->table), child,
4628 1, 2, sr->row, sr->row+1,
4629 0, 0,
4630 xpad, ypad);
4631 }
4632
table_add_right(selector * sr,GtkWidget * child,int fixed)4633 static void table_add_right (selector *sr,
4634 GtkWidget *child,
4635 int fixed)
4636 {
4637 guint xpad = 4, ypad = 2;
4638
4639 maybe_add_row(sr);
4640 gtk_table_attach(GTK_TABLE(sr->table), child,
4641 2, 3, sr->row, sr->row+1,
4642 GTK_EXPAND | GTK_SHRINK | GTK_FILL,
4643 fixed ? 0 : (GTK_EXPAND | GTK_SHRINK | GTK_FILL),
4644 xpad, ypad);
4645 /* finished a row, so advance */
4646 sr->row += 1;
4647 }
4648
alt_table_add_left(selector * sr,GtkWidget * child,int startrow,int endrow)4649 static void alt_table_add_left (selector *sr,
4650 GtkWidget *child,
4651 int startrow,
4652 int endrow)
4653 {
4654 guint xpad = 4, ypad = 2;
4655
4656 gtk_table_attach(GTK_TABLE(sr->table), child,
4657 0, 1, startrow, endrow,
4658 GTK_EXPAND | GTK_SHRINK | GTK_FILL,
4659 GTK_EXPAND | GTK_SHRINK | GTK_FILL,
4660 xpad, ypad);
4661 sr->row += 1;
4662 }
4663
table_add_vwedge(selector * sr)4664 static void table_add_vwedge (selector *sr)
4665 {
4666 GtkWidget *h = gtk_hbox_new(FALSE, 0);
4667
4668 maybe_add_row(sr);
4669 gtk_table_attach(GTK_TABLE(sr->table), h,
4670 2, 3, sr->row, sr->row+1,
4671 0, 0, 0, 2);
4672 sr->row += 1;
4673 }
4674
vbox_add_vwedge(GtkWidget * vbox)4675 static void vbox_add_vwedge (GtkWidget *vbox)
4676 {
4677 GtkWidget *h = gtk_hbox_new(FALSE, 0);
4678
4679 gtk_box_pack_start(GTK_BOX(vbox), h, FALSE, FALSE, 2);
4680 gtk_widget_show(h);
4681 }
4682
pix_button(const guint8 * src,gchar * tip)4683 static GtkWidget *pix_button (const guint8 *src, gchar *tip)
4684 {
4685 GtkWidget *img, *button;
4686 GdkPixbuf *pbuf;
4687
4688 pbuf = gdk_pixbuf_new_from_inline(-1, src, FALSE, NULL);
4689 img = gtk_image_new_from_pixbuf(pbuf);
4690 button = gtk_button_new();
4691 gtk_widget_set_size_request(button, BUTTON_WIDTH, -1);
4692 gtk_container_add(GTK_CONTAINER(button), img);
4693 gretl_tooltips_add(button, tip);
4694 g_object_unref(pbuf);
4695
4696 return button;
4697 }
4698
name_entry_in_hbox(GtkWidget ** pentry)4699 static GtkWidget *name_entry_in_hbox (GtkWidget **pentry)
4700 {
4701 GtkWidget *hbox, *entry;
4702
4703 hbox = gtk_hbox_new(FALSE, 0);
4704 entry = gtk_entry_new();
4705 gtk_entry_set_max_length(GTK_ENTRY(entry), VNAMELEN - 1);
4706 gtk_entry_set_width_chars(GTK_ENTRY(entry), VNAME_WIDTH);
4707 gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
4708
4709 if (pentry != NULL) {
4710 *pentry = entry;
4711 }
4712
4713 return hbox;
4714 }
4715
4716 static GtkWidget *
entry_with_label_and_chooser(selector * sr,gchar * label_string,int label_active,void (* clickfunc)())4717 entry_with_label_and_chooser (selector *sr,
4718 gchar *label_string,
4719 int label_active,
4720 void (*clickfunc)())
4721 {
4722 GtkWidget *tmp, *hbox, *entry;
4723
4724 if (label_active) {
4725 tmp = multiplot_popdown(sr->ci);
4726 table_add_right(sr, tmp, 1);
4727 } else if (label_string != NULL) {
4728 tmp = gtk_label_new(label_string);
4729 table_add_right(sr, tmp, 1);
4730 }
4731
4732 tmp = pix_button(choose_inline, _("Choose"));
4733 table_add_mid(sr, tmp);
4734 g_signal_connect(G_OBJECT(tmp), "clicked",
4735 G_CALLBACK(clickfunc), sr);
4736
4737 hbox = name_entry_in_hbox(&entry);
4738 table_add_right(sr, hbox, 1);
4739
4740 if (label_active || label_string != NULL) {
4741 if (clickfunc != set_third_var_callback) {
4742 table_add_vwedge(sr);
4743 }
4744 }
4745
4746 return entry;
4747 }
4748
build_x_axis_section(selector * sr,int v)4749 static void build_x_axis_section (selector *sr, int v)
4750 {
4751 if (sr->ci == SCATTERS) {
4752 sr->depvar = entry_with_label_and_chooser(sr, NULL, 1,
4753 set_dependent_var_callback);
4754 } else if (sr->ci == GR_FBOX) {
4755 sr->depvar = entry_with_label_and_chooser(sr, _("Variable to plot"), 0,
4756 set_dependent_var_callback);
4757 } else {
4758 sr->depvar = entry_with_label_and_chooser(sr, _("X-axis variable"), 0,
4759 set_dependent_var_callback);
4760 }
4761
4762 if (v > 0 && v < dataset->v) {
4763 gtk_entry_set_text(GTK_ENTRY(sr->depvar), dataset->varname[v]);
4764 }
4765 }
4766
maybe_activate_depvar_lags(GtkWidget * w,selector * sr)4767 static void maybe_activate_depvar_lags (GtkWidget *w, selector *sr)
4768 {
4769 if (select_lags_depvar(sr->ci) && sr->lags_button != NULL) {
4770 const gchar *txt = gtk_entry_get_text(GTK_ENTRY(w));
4771
4772 if (txt != NULL && *txt != 0) {
4773 gtk_widget_set_sensitive(sr->lags_button, TRUE);
4774 }
4775 }
4776 }
4777
4778 /* returns ID number of variable pre-inserted as dependent, or -1 */
4779
build_depvar_section(selector * sr,int preselect)4780 static int build_depvar_section (selector *sr, int preselect)
4781 {
4782 GtkWidget *tmp, *hbox;
4783 int defvar;
4784
4785 if (sr->ci == INTREG) {
4786 defvar = (lovar > 0 && lovar < dataset->v)? lovar : -1;
4787 } else {
4788 if (default_y >= dataset->v) {
4789 default_y = -1;
4790 }
4791 defvar = (preselect)? preselect : default_y;
4792 }
4793
4794 if (sr->ci == INTREG) {
4795 tmp = gtk_label_new(_("Lower bound variable"));
4796 } else if (sr->ci == ANOVA) {
4797 tmp = gtk_label_new(_("Response variable"));
4798 } else if (sr->ci == BIPROBIT) {
4799 tmp = gtk_label_new(_("Dependent variable 1"));
4800 } else {
4801 tmp = gtk_label_new(_("Dependent variable"));
4802 }
4803
4804 table_add_right(sr, tmp, 1);
4805
4806 tmp = pix_button(choose_inline, _("Choose"));
4807 table_add_mid(sr, tmp);
4808 g_signal_connect(G_OBJECT(tmp), "clicked",
4809 G_CALLBACK(set_dependent_var_callback), sr);
4810
4811 hbox = name_entry_in_hbox(&sr->depvar);
4812 g_signal_connect(G_OBJECT(sr->depvar), "changed",
4813 G_CALLBACK(maybe_activate_depvar_lags), sr);
4814 if (defvar >= 0) {
4815 gtk_entry_set_text(GTK_ENTRY(sr->depvar), dataset->varname[defvar]);
4816 }
4817 table_add_right(sr, hbox, 1);
4818
4819 if (sr->ci != INTREG && sr->ci != BIPROBIT) {
4820 sr->default_check = gtk_check_button_new_with_label(_("Set as default"));
4821 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sr->default_check),
4822 default_y >= 0);
4823 table_add_right(sr, sr->default_check, 1);
4824 }
4825
4826 if (sr->ci != DPANEL && sr->ci != BIPROBIT && sr->ci != TOBIT) {
4827 table_add_vwedge(sr);
4828 }
4829
4830 return defvar;
4831 }
4832
4833 /* In case we have a saved preference for the max lag of the
4834 endogenous vars in a VAR, set via the lags dialog, update this
4835 value from the global spinner
4836 */
4837
lag_order_sync(GtkSpinButton * b,selector * sr)4838 static void lag_order_sync (GtkSpinButton *b, selector *sr)
4839 {
4840 if (gtk_widget_is_sensitive(GTK_WIDGET(b)) &&
4841 sr->extra[EXTRA_LAGS] != NULL) {
4842 int lmax = gtk_spin_button_get_value_as_int(b);
4843
4844 set_VAR_max_lag(lmax);
4845 }
4846 }
4847
4848 enum {
4849 LAG_ONLY,
4850 LAG_AND_RANK
4851 };
4852
lag_order_spin(selector * sr,int which)4853 static void lag_order_spin (selector *sr, int which)
4854 {
4855 gdouble lag, minlag, maxlag;
4856 GtkWidget *hbox, *label, *spin;
4857 GtkAdjustment *adj;
4858 const char *labels[] = {
4859 N_("lag order:"),
4860 N_("rank:")
4861 };
4862 int i, nspin = (which == LAG_AND_RANK)? 2 : 1;
4863
4864 maxlag = (dataset->n < 72)? (dataset->n / 2) : 36;
4865 minlag = (sr->ci == COINT)? 0 : 1;
4866
4867 if (default_order > 0 && default_order <= maxlag) {
4868 lag = default_order;
4869 } else {
4870 lag = (dataset->pd > 12)? 12 : dataset->pd;
4871 }
4872
4873 if (sr->ci == VLAGSEL) {
4874 minlag = 2;
4875 lag *= 2;
4876 if (lag > maxlag) {
4877 lag = maxlag;
4878 }
4879 }
4880
4881 for (i=0; i<nspin; i++) {
4882 hbox = gtk_hbox_new(FALSE, 5);
4883 if (sr->ci == VLAGSEL) {
4884 label = gtk_label_new(_("maximum lag:"));
4885 } else {
4886 label = gtk_label_new(_(labels[i]));
4887 }
4888 if (i == 0) {
4889 /* lag order */
4890 adj = (GtkAdjustment *) gtk_adjustment_new(lag, minlag, maxlag,
4891 1, 1, 0);
4892 } else {
4893 /* rank */
4894 adj = (GtkAdjustment *) gtk_adjustment_new(jrank, 1, 10,
4895 1, 1, 0);
4896 }
4897 spin = gtk_spin_button_new(adj, 1, 0);
4898 if (i == 1) {
4899 gretl_tooltips_add(label, _("Number of cointegrating vectors"));
4900 }
4901 gtk_box_pack_end(GTK_BOX(hbox), spin, FALSE, FALSE, 5);
4902 gtk_box_pack_end(GTK_BOX(hbox), label, FALSE, FALSE, 0);
4903 if (i == 0) {
4904 /* cross-connect with lag preferences dialog */
4905 if (get_VAR_lags_list() != NULL) {
4906 gtk_widget_set_sensitive(spin, FALSE);
4907 }
4908 g_signal_connect(G_OBJECT(spin), "value-changed",
4909 G_CALLBACK(lag_order_sync), sr);
4910 }
4911 sr->extra[i] = spin;
4912 table_add_right(sr, hbox, 1);
4913 }
4914 }
4915
AR_order_spin(selector * sr)4916 static void AR_order_spin (selector *sr)
4917 {
4918 GtkWidget *tmp, *hbox;
4919 GtkAdjustment *adj;
4920 gdouble val, minlag, maxlag;
4921
4922 hbox = gtk_hbox_new(FALSE, 5);
4923
4924 if (sr->ci == ARCH) {
4925 tmp = gtk_label_new(_("ARCH order:"));
4926 val = dataset->pd;
4927 minlag = 1;
4928 maxlag = 2 * dataset->pd;
4929 } else if (sr->ci == MIDASREG) {
4930 tmp = gtk_label_new(_("AR order:"));
4931 val = mds_order;
4932 minlag = 0;
4933 maxlag = 100;
4934 } else {
4935 /* dpanel */
4936 tmp = gtk_label_new(_("AR order:"));
4937 val = dpd_p;
4938 minlag = 1;
4939 maxlag = 10;
4940 if (maxlag < dataset->pd - 2) {
4941 maxlag = dataset->pd - 2;
4942 }
4943 }
4944
4945 if (default_order > 0 && default_order <= maxlag) {
4946 val = default_order;
4947 }
4948
4949 gtk_box_pack_start(GTK_BOX(hbox), tmp, TRUE, TRUE, 5);
4950 gtk_misc_set_alignment(GTK_MISC(tmp), 0.0, 0.5);
4951 adj = (GtkAdjustment *) gtk_adjustment_new(val, minlag, maxlag, 1, 1, 0);
4952 sr->extra[0] = gtk_spin_button_new(adj, 1, 0);
4953 gtk_box_pack_start(GTK_BOX(hbox), sr->extra[0], FALSE, FALSE, 5);
4954
4955 table_add_right(sr, hbox, 1);
4956 }
4957
extra_plotvar_box(selector * sr)4958 static void extra_plotvar_box (selector *sr)
4959 {
4960 const gchar *label;
4961
4962 if (sr->ci == GR_3D) {
4963 label = N_("Z-axis variable");
4964 } else if (sr->ci == GR_DUMMY || sr->ci == GR_FBOX) {
4965 label = _("Factor (discrete)");
4966 } else if (sr->ci == GR_XYZ) {
4967 label = N_("Control variable");
4968 } else if (sr->ci == ANOVA) {
4969 label = N_("Block variable (optional)");
4970 } else {
4971 return;
4972 }
4973
4974 sr->rvars1 = entry_with_label_and_chooser(sr, _(label), 0,
4975 set_third_var_callback);
4976 }
4977
get_nonparam_xvar(void)4978 static int get_nonparam_xvar (void)
4979 {
4980 if (np_xvar > 0) {
4981 return np_xvar;
4982 } else if (xlist != NULL) {
4983 int i;
4984
4985 for (i=1; i<=xlist[0]; i++) {
4986 if (xlist[i] != 0) {
4987 return xlist[i];
4988 }
4989 }
4990 }
4991
4992 return 0;
4993 }
4994
get_setvar_value(int v)4995 static int get_setvar_value (int v)
4996 {
4997 if (v > 0 && v < dataset->v) {
4998 return v;
4999 } else {
5000 return 0;
5001 }
5002 }
5003
5004 /* selector for auxiliary series of some kind */
5005
extra_var_box(selector * sr)5006 static void extra_var_box (selector *sr)
5007 {
5008 int setvar = 0;
5009
5010 sr->extra[0] = entry_with_label_and_chooser(sr, NULL, 0,
5011 set_extra_var_callback);
5012
5013 if (sr->ci == WLS) {
5014 setvar = get_setvar_value(wtvar);
5015 } else if (sr->ci == HECKIT) {
5016 setvar = get_setvar_value(selvar);
5017 } else if (sr->ci == INTREG) {
5018 setvar = get_setvar_value(hivar);
5019 } else if (sr->ci == COUNTMOD) {
5020 setvar = get_setvar_value(offvar);
5021 } else if (sr->ci == DURATION) {
5022 setvar = get_setvar_value(censvar);
5023 } else if (sr->ci == BIPROBIT) {
5024 setvar = get_setvar_value(y2var);
5025 } else if (NONPARAM_CODE(sr->ci)) {
5026 setvar = get_nonparam_xvar();
5027 }
5028
5029 if (setvar > 0) {
5030 gtk_entry_set_text(GTK_ENTRY(sr->extra[0]), dataset->varname[setvar]);
5031 g_object_set_data(G_OBJECT(sr->extra[0]), "data",
5032 GINT_TO_POINTER(setvar));
5033 }
5034 }
5035
accept_right_arrow(GtkWidget * w,GdkEventKey * key,gpointer p)5036 static gboolean accept_right_arrow (GtkWidget *w, GdkEventKey *key,
5037 gpointer p)
5038 {
5039 if (key->keyval == GDK_Right) {
5040 gtk_button_clicked(GTK_BUTTON(p));
5041 return TRUE;
5042 } else {
5043 return FALSE;
5044 }
5045 }
5046
accept_left_arrow(GtkWidget * w,GdkEventKey * key,gpointer p)5047 static gboolean accept_left_arrow (GtkWidget *w, GdkEventKey *key,
5048 gpointer p)
5049 {
5050 if (key->keyval == GDK_Left) {
5051 gtk_button_clicked(GTK_BUTTON(p));
5052 return TRUE;
5053 } else {
5054 return FALSE;
5055 }
5056 }
5057
push_pull_buttons(selector * sr,void (* addfunc)(),void (* remfunc)(),GtkWidget ** lags_button,gretlopt opt)5058 static void push_pull_buttons (selector *sr,
5059 void (*addfunc)(),
5060 void (*remfunc)(),
5061 GtkWidget **lags_button,
5062 gretlopt opt)
5063 {
5064 GtkWidget *align, *vbox;
5065 GtkWidget *button;
5066 int spacing = 5;
5067
5068 if ((opt & OPT_A) || lags_button == NULL) {
5069 spacing = 15;
5070 }
5071
5072 align = gtk_alignment_new(0.5, 0.5, 0, 0);
5073 gtk_alignment_set_padding(GTK_ALIGNMENT(align),
5074 0, 0, 0, 0);
5075 vbox = gtk_vbox_new(TRUE, 5);
5076
5077 /* "Add" button */
5078 button = pix_button(add_inline, _("Add"));
5079 g_signal_connect(G_OBJECT(button), "clicked",
5080 G_CALLBACK(addfunc), sr);
5081 g_signal_connect(G_OBJECT(sr->dlg), "key-press-event",
5082 G_CALLBACK(accept_right_arrow), button);
5083 gtk_box_pack_start(GTK_BOX(vbox), button, 0, 0, spacing);
5084 if (opt & OPT_A) {
5085 sr->add_button = button;
5086 }
5087
5088 /* "All" button? */
5089 if (SAVE_DATA_ACTION(sr->ci) || sr->ci == EXPORT) {
5090 button = gtk_button_new_with_label(_("All ->"));
5091 g_signal_connect(G_OBJECT(button), "clicked",
5092 G_CALLBACK(add_all_to_rvars1_callback), sr);
5093 gtk_box_pack_start(GTK_BOX(vbox), button, 0, 0, spacing);
5094 }
5095
5096 /* "Remove" button */
5097 button = pix_button(remove_inline, _("Remove"));
5098 g_signal_connect(G_OBJECT(button), "clicked",
5099 G_CALLBACK(remfunc), sr);
5100 g_signal_connect(G_OBJECT(sr->dlg), "key-press-event",
5101 G_CALLBACK(accept_left_arrow), button);
5102 gtk_box_pack_start(GTK_BOX(vbox), button, 0, 0, spacing);
5103 if (opt & OPT_R) {
5104 sr->remove_button = button;
5105 }
5106
5107 /* "Lags" button? */
5108 if (lags_button != NULL) {
5109 button = gtk_button_new_with_label(_("lags..."));
5110 g_signal_connect(G_OBJECT(button), "clicked",
5111 G_CALLBACK(lags_dialog_driver), sr);
5112 gtk_widget_set_sensitive(button, FALSE);
5113 *lags_button = button;
5114 gtk_box_pack_start(GTK_BOX(vbox), button, 0, 0, spacing);
5115 }
5116
5117 gtk_container_add(GTK_CONTAINER(align), vbox);
5118 table_add_mid(sr, align);
5119 }
5120
secondary_rhs_varlist(selector * sr)5121 static void secondary_rhs_varlist (selector *sr)
5122 {
5123 GtkTreeModel *mod;
5124 GtkListStore *store;
5125 GtkTreeIter iter;
5126 GtkWidget *hbox;
5127 GtkWidget *tmp = NULL;
5128 GtkWidget **lptr = NULL;
5129 int i;
5130
5131 if (USE_VECXLIST(sr->ci)) {
5132 tmp = gtk_label_new(_("Exogenous variables"));
5133 } else if (IV_MODEL(sr->ci)) {
5134 tmp = gtk_label_new(_("Instruments"));
5135 } else if (sr->ci == HECKIT) {
5136 tmp = gtk_label_new(_("Selection regressors"));
5137 } else if (sr->ci == BIPROBIT) {
5138 tmp = gtk_label_new(_("Equation 2 regressors"));
5139 } else if (sr->ci == MIDASREG) {
5140 tmp = gtk_label_new(_("High-frequency"));
5141 } else if (FNPKG_CODE(sr->ci)) {
5142 tmp = gtk_label_new(_("Helper functions"));
5143 }
5144
5145 if (tmp != NULL) {
5146 table_add_right(sr, tmp, 1);
5147 }
5148
5149 hbox = gtk_hbox_new(FALSE, 5);
5150
5151 sr->rvars2 = var_list_box_new(GTK_BOX(hbox), sr, SR_RVARS2);
5152 mod = gtk_tree_view_get_model(GTK_TREE_VIEW(sr->rvars2));
5153
5154 if (sr->ci == VAR || sr->ci == VECM || sr->ci == VLAGSEL) {
5155 lptr = &sr->lags_button;
5156 }
5157
5158 /* add push-pull buttons */
5159 push_pull_buttons(sr, add_to_rvars2_callback,
5160 remove_from_rvars2_callback,
5161 lptr, OPT_NONE);
5162
5163 store = GTK_LIST_STORE(mod);
5164 gtk_list_store_clear(store);
5165 gtk_tree_model_get_iter_first(mod, &iter);
5166
5167 if (sr->ci == MIDASREG) {
5168 ; /* FIXME do something here? */
5169 } else if (USE_ZLIST(sr->ci) && instlist != NULL) {
5170 for (i=1; i<=instlist[0]; i++) {
5171 if (instlist[i] < dataset->v) {
5172 list_append_var(mod, &iter, instlist[i], sr, SR_RVARS2);
5173 }
5174 }
5175 } else if (USE_VECXLIST(sr->ci) && vecxlist != NULL) {
5176 set_varflag(UNRESTRICTED);
5177 for (i=1; i<=vecxlist[0]; i++) {
5178 if (vecxlist[i] == LISTSEP) {
5179 set_varflag(RESTRICTED);
5180 } else if (vecxlist[i] > 0) {
5181 list_append_var(mod, &iter, vecxlist[i], sr, SR_RVARS2);
5182 if (sr->lags_button != NULL) {
5183 gtk_widget_set_sensitive(sr->lags_button, TRUE);
5184 }
5185 }
5186 }
5187 set_varflag(UNRESTRICTED);
5188 } else if (!VEC_CODE(sr->ci) && !FNPKG_CODE(sr->ci)) {
5189 list_append_var(mod, &iter, 0, sr, SR_RVARS2);
5190 }
5191
5192 table_add_right(sr, hbox, 0);
5193 }
5194
make_tau_list(GtkWidget * box)5195 static void make_tau_list (GtkWidget *box)
5196 {
5197 combo_box_append_text(box, "0.25 0.50 0.75");
5198 combo_box_append_text(box, ".05, .25 .50 .75, .95");
5199 combo_box_append_text(box, ".1 .2 .3 .4 .5 .6 .7 .8 .9");
5200 }
5201
tobit_limits_selector(selector * sr)5202 static void tobit_limits_selector (selector *sr)
5203 {
5204 const char *bstrs[] = {
5205 N_("left bound"),
5206 N_("right bound")
5207 };
5208 GtkWidget *hbox, *entry, *label;
5209 gchar *valstr;
5210 double val;
5211 int i;
5212
5213 for (i=0; i<2; i++) {
5214 hbox = gtk_hbox_new(FALSE, 5);
5215 entry = gtk_entry_new();
5216 gtk_entry_set_width_chars(GTK_ENTRY(entry), 5);
5217 val = (i == 0)? tobit_lo : tobit_hi;
5218 valstr = na(val)? g_strdup("NA") : g_strdup_printf("%g", val);
5219 gtk_entry_set_text(GTK_ENTRY(entry), valstr);
5220 g_free(valstr);
5221 gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
5222 gtk_box_pack_end(GTK_BOX(hbox), entry, FALSE, FALSE, 5);
5223 label = gtk_label_new(_(bstrs[i]));
5224 gtk_box_pack_end(GTK_BOX(hbox), label, FALSE, FALSE, 5);
5225 table_add_right(sr, hbox, 1);
5226 sr->extra[i] = entry;
5227 }
5228 }
5229
add_np_controls(selector * sr)5230 static void add_np_controls (selector *sr)
5231 {
5232 GtkAdjustment *adj;
5233 GtkWidget *hbox, *w;
5234 double bmin = 0.01;
5235 double bmax = 1.0;
5236 const char *optstr;
5237 int i = 1;
5238
5239 if (sr->ci == LOESS) {
5240 /* polynomial order is specific to loess */
5241 hbox = gtk_hbox_new(FALSE, 5);
5242 w = gtk_label_new(_("Polynomial order"));
5243 gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 5);
5244 adj = (GtkAdjustment *) gtk_adjustment_new(1, 0, 2, 1, 1, 0);
5245 sr->extra[i] = gtk_spin_button_new(adj, 1, 0);
5246 gtk_box_pack_end(GTK_BOX(hbox), sr->extra[i], FALSE, FALSE, 5);
5247 table_add_right(sr, hbox, 1);
5248 i++;
5249 }
5250
5251 /* bandwidth specification */
5252 if (sr->ci == LOESS) {
5253 hbox = gtk_hbox_new(FALSE, 5);
5254 w = gtk_label_new(_("Bandwidth"));
5255 gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 5);
5256 adj = (GtkAdjustment *) gtk_adjustment_new(0.5, bmin, bmax, 0.01, 0.1, 0);
5257 sr->extra[i] = gtk_spin_button_new(adj, 0.01, 2);
5258 gtk_box_pack_end(GTK_BOX(hbox), sr->extra[i], FALSE, FALSE, 5);
5259 table_add_right(sr, hbox, 1);
5260 i++;
5261 } else {
5262 double b0 = pow(sample_size(dataset), -0.2);
5263 GtkWidget *b1, *b2;
5264 GSList *group;
5265
5266 hbox = gtk_hbox_new(FALSE, 5);
5267 b1 = gtk_radio_button_new_with_label(NULL, _("Automatic bandwidth"));
5268 gtk_box_pack_start(GTK_BOX(hbox), b1, FALSE, FALSE, 5);
5269 table_add_right(sr, hbox, 1);
5270 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(b1));
5271 hbox = gtk_hbox_new(FALSE, 5);
5272 b2 = gtk_radio_button_new_with_label(group,
5273 _("User-specified"));
5274 adj = (GtkAdjustment *) gtk_adjustment_new(b0, bmin, bmax, 0.01, 0.1, 0);
5275 w = sr->extra[i] = gtk_spin_button_new(adj, 0.01, 2);
5276 gtk_box_pack_start(GTK_BOX(hbox), b2, FALSE, FALSE, 5);
5277 gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 5);
5278 table_add_right(sr, hbox, 1);
5279 gtk_widget_set_sensitive(w, FALSE);
5280 sensitize_conditional_on(w, b2);
5281 i++;
5282 }
5283
5284 optstr = (sr->ci == LOESS)? N_("Use robust weights") :
5285 N_("Use \"leave one out\"");
5286
5287 /* option checkbox */
5288 hbox = gtk_hbox_new(FALSE, 5);
5289 w = sr->extra[i] = gtk_check_button_new_with_label(_(optstr));
5290 gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 5);
5291 table_add_right(sr, hbox, 1);
5292 }
5293
maybe_set_entry_text(GtkWidget * w,const char * s)5294 static int maybe_set_entry_text (GtkWidget *w, const char *s)
5295 {
5296 if (s != NULL && *s != '\0') {
5297 gtk_entry_set_text(GTK_ENTRY(w), s + (*s == ' '));
5298 return 1;
5299 } else {
5300 return 0;
5301 }
5302 }
5303
build_mid_section(selector * sr)5304 static void build_mid_section (selector *sr)
5305 {
5306 const char *str = _(extra_var_string(sr->ci));
5307 GtkWidget *tmp;
5308
5309 if (str != NULL) {
5310 tmp = gtk_label_new(str);
5311 table_add_right(sr, tmp, 1);
5312 }
5313
5314 if (sr->ci == HECKIT || sr->ci == BIPROBIT) {
5315 extra_var_box(sr);
5316 table_add_vwedge(sr);
5317 primary_rhs_varlist(sr);
5318 } else if (sr->ci == WLS || sr->ci == INTREG ||
5319 sr->ci == COUNTMOD || sr->ci == DURATION ||
5320 THREE_VARS_CODE(sr->ci)) {
5321 extra_var_box(sr);
5322 } else if (NONPARAM_CODE(sr->ci)) {
5323 extra_var_box(sr);
5324 table_add_vwedge(sr);
5325 add_np_controls(sr);
5326 } else if (sr->ci == TOBIT) {
5327 tobit_limits_selector(sr);
5328 table_add_vwedge(sr);
5329 } else if (sr->ci == MIDASREG) {
5330 AR_order_spin(sr);
5331 primary_rhs_varlist(sr);
5332 } else if (USE_ZLIST(sr->ci)) {
5333 primary_rhs_varlist(sr);
5334 } else if (sr->ci == AR) {
5335 sr->extra[0] = gtk_entry_new();
5336 maybe_set_entry_text(sr->extra[0], arlags);
5337 table_add_right(sr, sr->extra[0], 1);
5338 } else if (sr->ci == QUANTREG) {
5339 GtkWidget *child;
5340
5341 sr->extra[0] = combo_box_text_new_with_entry();
5342 make_tau_list(sr->extra[0]);
5343 child = gtk_bin_get_child(GTK_BIN(sr->extra[0]));
5344 gtk_entry_set_text(GTK_ENTRY(child), "0.5");
5345 table_add_right(sr, sr->extra[0], 1);
5346 } else if (sr->ci == VAR || sr->ci == VLAGSEL) {
5347 lag_order_spin(sr, LAG_ONLY);
5348 table_add_vwedge(sr);
5349 primary_rhs_varlist(sr);
5350 } else if (sr->ci == VECM) {
5351 lag_order_spin(sr, LAG_AND_RANK);
5352 table_add_vwedge(sr);
5353 primary_rhs_varlist(sr);
5354 } else if (sr->ci == COINT2) {
5355 lag_order_spin(sr, LAG_ONLY);
5356 table_add_vwedge(sr);
5357 primary_rhs_varlist(sr);
5358 } else if (VEC_CODE(sr->ci)) {
5359 lag_order_spin(sr, LAG_ONLY);
5360 } else if (sr->ci == DPANEL || sr->ci == ARCH) {
5361 AR_order_spin(sr);
5362 }
5363
5364 table_add_vwedge(sr);
5365 }
5366
5367 enum {
5368 SELECTOR_SIMPLE,
5369 SELECTOR_FULL
5370 };
5371
selector_dialog_new(selector * sr)5372 static GtkWidget *selector_dialog_new (selector *sr)
5373 {
5374 GtkWidget *d = gretl_gtk_dialog();
5375 GtkWidget *base, *ca, *aa;
5376
5377 g_signal_connect(G_OBJECT(d), "key-press-event",
5378 G_CALLBACK(esc_kills_window), NULL);
5379
5380 base = gtk_dialog_get_content_area(GTK_DIALOG(d));
5381 gtk_box_set_homogeneous(GTK_BOX(base), FALSE);
5382 gtk_box_set_spacing(GTK_BOX(base), 5);
5383
5384 ca = gtk_vbox_new(FALSE, 0);
5385 gtk_box_pack_start(GTK_BOX(base), ca, TRUE, TRUE, 0);
5386 gtk_container_set_border_width(GTK_CONTAINER(ca), 5);
5387 gtk_box_set_spacing(GTK_BOX(ca), 5);
5388
5389 aa = gtk_dialog_get_action_area(GTK_DIALOG(d));
5390 gtk_button_box_set_layout(GTK_BUTTON_BOX(aa), GTK_BUTTONBOX_END);
5391 gtk_box_set_spacing(GTK_BOX(aa), 10);
5392 gtk_container_set_border_width(GTK_CONTAINER(aa), 5);
5393
5394 sr->vbox = ca;
5395 sr->action_area = aa;
5396
5397 return d;
5398 }
5399
maybe_increase_vsize(selector * sr,float vsize)5400 static int maybe_increase_vsize (selector *sr, float vsize)
5401 {
5402 int ch = get_char_height(sr->dlg);
5403 float try = (ch / 18.0) * vsize;
5404 int sh = get_screen_height();
5405 int ret = vsize;
5406
5407 if (try > vsize) {
5408 ret = (try <= 0.6 * sh)? (int) try : (int) (0.6 * sh);
5409 }
5410
5411 return ret;
5412 }
5413
selector_init(selector * sr,guint ci,const char * title,int (* callback)(),GtkWidget * parent,gpointer data,int selcode)5414 static void selector_init (selector *sr, guint ci, const char *title,
5415 int (*callback)(), GtkWidget *parent,
5416 gpointer data, int selcode)
5417 {
5418 int i, dlgx = -1, dlgy = 340;
5419 float x;
5420
5421 sr->row = 0;
5422 sr->n_rows = 1;
5423
5424 sr->blocking = 0;
5425 sr->ci = ci;
5426 sr->opts = OPT_NONE;
5427 sr->parent = parent;
5428 sr->data = data;
5429 sr->extra_data = NULL;
5430
5431 if (MODEL_CODE(ci)) {
5432 if (dataset->v > 9) {
5433 dlgy += 80;
5434 }
5435 }
5436
5437 if (ci == ARMA) {
5438 dlgy += 80;
5439 } else if (ci == WLS || ci == INTREG || ci == COUNTMOD ||
5440 ci == DURATION || ci == AR) {
5441 dlgy += 30;
5442 } else if (ci == HECKIT || ci == TOBIT) {
5443 dlgy += 80;
5444 } else if (ci == BIPROBIT) {
5445 dlgy += 110;
5446 } else if (IV_MODEL(ci)) {
5447 dlgy += 60;
5448 } else if (ci == ANOVA) {
5449 dlgy -= 60;
5450 } else if (ci == PANEL_WLS) {
5451 sr->opts |= OPT_H;
5452 } else if (VEC_CODE(ci)) {
5453 dlgy = 450;
5454 if (ci == VAR || ci == VECM) {
5455 dlgy += 50;
5456 } else if (ci == VLAGSEL) {
5457 dlgy += 40;
5458 }
5459 }
5460
5461 if (WANT_TOGGLES(ci) && ci != COINT) {
5462 dlgy += 40;
5463 }
5464
5465 if (want_radios(sr)) {
5466 if (ci == REGLS) {
5467 /* more stuff to show */
5468 dlgy += 240;
5469 } else {
5470 dlgy += 60;
5471 }
5472 }
5473
5474 if (want_combo(sr)) {
5475 dlgy += 20;
5476 }
5477
5478 if (ci == ARMA && dataset->pd > 1) {
5479 /* seasonal spinners */
5480 dlgy += 60;
5481 }
5482
5483 if (ci == GARCH) {
5484 /* extra check boxes */
5485 dlgy += 50;
5486 }
5487
5488 if (dataset_lags_ok(dataset)) {
5489 if (MODEL_CODE(ci) && ci != ARMA) {
5490 /* lag selector button at foot */
5491 dlgy += 30;
5492 }
5493 }
5494
5495 if (ci == DPANEL) {
5496 /* lots of option buttons */
5497 dlgy += 50;
5498 }
5499
5500 sr->lvars = NULL;
5501 sr->lvars2 = NULL;
5502 sr->depvar = NULL;
5503 sr->rvars1 = NULL;
5504 sr->rvars2 = NULL;
5505 sr->default_check = NULL;
5506 sr->add_button = NULL;
5507 sr->remove_button = NULL;
5508 sr->lags_button = NULL;
5509 sr->hess_button = NULL;
5510 sr->x12a_button = NULL;
5511 sr->xdiff_button = NULL;
5512 sr->hccme_button = NULL;
5513
5514 for (i=0; i<N_EXTRA; i++) {
5515 sr->extra[i] = NULL;
5516 }
5517
5518 sr->cmdlist = NULL;
5519 sr->cmdlen = sr->cmdsize = 0;
5520 sr->callback = callback;
5521
5522 sr->active_var = 0;
5523 sr->error = 0;
5524 sr->n_left = 0;
5525 sr->state_pushed = 0;
5526
5527 if (ci == ARMA && push_program_state() == 0) {
5528 if (model_opt & OPT_L) {
5529 libset_set_bool(USE_LBFGS, 1);
5530 }
5531 sr->state_pushed = 1;
5532 }
5533
5534 if (selcode == SELECTOR_SIMPLE) {
5535 sr->dlg = selector_dialog_new(sr);
5536 if (parent != NULL) {
5537 gtk_window_set_transient_for(GTK_WINDOW(sr->dlg),
5538 GTK_WINDOW(parent));
5539 gtk_window_set_destroy_with_parent(GTK_WINDOW(sr->dlg),
5540 TRUE);
5541 } else {
5542 gtk_window_set_transient_for(GTK_WINDOW(sr->dlg),
5543 GTK_WINDOW(mdata->main));
5544 }
5545 } else {
5546 sr->dlg = gretl_gtk_window();
5547 gretl_emulated_dialog_add_structure(sr->dlg,
5548 &sr->vbox,
5549 &sr->action_area);
5550 }
5551
5552 gtk_window_set_title(GTK_WINDOW(sr->dlg), title);
5553 open_selector = sr;
5554
5555 x = dlgy * gui_scale;
5556 dlgy = maybe_increase_vsize(sr, x);
5557
5558 if (FNPKG_CODE(ci)) {
5559 x = 460 * gui_scale;
5560 dlgx = x;
5561 }
5562
5563 gtk_window_set_default_size(GTK_WINDOW(sr->dlg), dlgx, dlgy);
5564 #ifndef G_OS_WIN32
5565 set_wm_icon(sr->dlg);
5566 #endif
5567 gtk_window_set_position(GTK_WINDOW(sr->dlg), GTK_WIN_POS_MOUSE);
5568
5569 g_signal_connect(G_OBJECT(sr->dlg), "destroy",
5570 G_CALLBACK(destroy_selector),
5571 sr);
5572 }
5573
option_callback(GtkWidget * w,selector * sr)5574 static void option_callback (GtkWidget *w, selector *sr)
5575 {
5576 gint i = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w), "opt"));
5577 gretlopt opt = i;
5578
5579 if (button_is_active(w)) {
5580 sr->opts |= opt;
5581 } else {
5582 sr->opts &= ~opt;
5583 }
5584 }
5585
reverse_option_callback(GtkWidget * w,selector * sr)5586 static void reverse_option_callback (GtkWidget *w, selector *sr)
5587 {
5588 gint i = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w), "opt"));
5589 gretlopt opt = i;
5590
5591 if (button_is_active(w)) {
5592 sr->opts &= ~opt;
5593 } else {
5594 sr->opts |= opt;
5595 }
5596 }
5597
garch_spin_check(GtkSpinButton * b,selector * sr)5598 static void garch_spin_check (GtkSpinButton *b, selector *sr)
5599 {
5600 int p = gtk_spin_button_get_value(GTK_SPIN_BUTTON(sr->extra[0]));
5601 int q = gtk_spin_button_get_value(GTK_SPIN_BUTTON(sr->extra[1]));
5602 int i = (GTK_WIDGET(b) == sr->extra[1])? 1 : 0;
5603
5604 if (p + q > 5) {
5605 /* limit p + q to 5 */
5606 if (i == 0) {
5607 gtk_spin_button_set_value(GTK_SPIN_BUTTON(sr->extra[1]),
5608 (gdouble) --q);
5609 } else {
5610 gtk_spin_button_set_value(GTK_SPIN_BUTTON(sr->extra[0]),
5611 (gdouble) --p);
5612 }
5613 } else if (p > 0 && q == 0) {
5614 /* rule out pure AR in variance */
5615 gtk_spin_button_set_value(GTK_SPIN_BUTTON(sr->extra[1]), 1);
5616 }
5617 }
5618
build_garch_spinners(selector * sr)5619 static void build_garch_spinners (selector *sr)
5620 {
5621 GtkWidget *tmp, *hbox;
5622 GtkAdjustment *adj;
5623 gdouble val;
5624 const char *strs[] = {
5625 N_("GARCH p:"),
5626 N_("ARCH q:")
5627 };
5628 int i;
5629
5630 hbox = gtk_hbox_new(FALSE, 5);
5631
5632 for (i=0; i<2; i++) {
5633 tmp = gtk_label_new(_(strs[i]));
5634 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
5635 val = (i==0)? garch_p : garch_q;
5636 adj = (GtkAdjustment *) gtk_adjustment_new(val, 0, 4, 1, 1, 0);
5637 sr->extra[i] = gtk_spin_button_new(adj, 1, 0);
5638 gtk_box_pack_start(GTK_BOX(hbox), sr->extra[i], FALSE, FALSE, 5);
5639 g_signal_connect(GTK_SPIN_BUTTON(sr->extra[i]), "value-changed",
5640 G_CALLBACK(garch_spin_check), sr);
5641 }
5642
5643 gtk_box_pack_start(GTK_BOX(sr->vbox), hbox, FALSE, FALSE, 5);
5644 }
5645
arma_aux_label(int i)5646 static GtkWidget *arma_aux_label (int i)
5647 {
5648 GtkWidget *hbox;
5649 GtkWidget *lbl;
5650 const char *strs[] = {
5651 N_("Non-seasonal"),
5652 N_("Seasonal"),
5653 N_("Orders")
5654 };
5655
5656 hbox = gtk_hbox_new(FALSE, 5);
5657 lbl = gtk_label_new(_(strs[i]));
5658 gtk_box_pack_start(GTK_BOX(hbox), lbl, FALSE, FALSE, 5);
5659
5660 return hbox;
5661 }
5662
toggle_p(GtkWidget * w,selector * sr)5663 static void toggle_p (GtkWidget *w, selector *sr)
5664 {
5665 gboolean s = button_is_active(w);
5666
5667 gtk_widget_set_sensitive(sr->extra[ARMA_p], !s);
5668 gtk_widget_set_sensitive(sr->extra[ARMA_plist], s);
5669 }
5670
toggle_q(GtkWidget * w,selector * sr)5671 static void toggle_q (GtkWidget *w, selector *sr)
5672 {
5673 gboolean s = button_is_active(w);
5674
5675 gtk_widget_set_sensitive(sr->extra[ARMA_q], !s);
5676 gtk_widget_set_sensitive(sr->extra[ARMA_qlist], s);
5677 }
5678
arima_callback(GtkWidget * w,selector * sr)5679 static void arima_callback (GtkWidget *w, selector *sr)
5680 {
5681 gtk_widget_set_sensitive(sr->xdiff_button, arima_selected(sr) &&
5682 rvars1_n_vars(sr) > 0);
5683 }
5684
build_arma_spinners(selector * sr)5685 static void build_arma_spinners (selector *sr)
5686 {
5687 GtkWidget *lbl, *chk, *tab;
5688 GtkAdjustment *adj;
5689 gdouble vmax, val;
5690 gboolean freeform;
5691 const char *strs[] = {
5692 N_("AR"),
5693 N_("I"),
5694 N_("MA")
5695 };
5696 int nrows, ncols = 7;
5697 int seasonals;
5698 int c, i, j;
5699
5700 seasonals = dataset->pd > 1;
5701 nrows = seasonals ? 3 : 2;
5702
5703 tab = gtk_table_new(nrows, ncols, FALSE);
5704 gtk_table_set_row_spacings(GTK_TABLE(tab), 5);
5705 gtk_table_set_col_spacings(GTK_TABLE(tab), 5);
5706 gtk_box_pack_start(GTK_BOX(sr->vbox), tab, FALSE, FALSE, 0);
5707
5708 lbl = arma_aux_label(seasonals? 0 : 2);
5709 gtk_table_attach_defaults(GTK_TABLE(tab), lbl, 0, 1, 0, 1);
5710 c = 1;
5711
5712 /* non-seasonal AR, I, MA spin-buttons */
5713 for (i=0; i<3; i++) {
5714 lbl = gtk_label_new(_(strs[i]));
5715 gtk_table_attach_defaults(GTK_TABLE(tab), lbl, c, c+1, 0, 1);
5716 c++;
5717 val = (i==0)? arma_p : (i==1)? arima_d : arma_q;
5718 vmax = (i == 1)? 2 : 10;
5719 adj = (GtkAdjustment *) gtk_adjustment_new(val, 0, vmax, 1, 1, 0);
5720 sr->extra[i] = gtk_spin_button_new(adj, 1, 0);
5721 if (i == 1) {
5722 g_signal_connect(G_OBJECT(sr->extra[i]), "value-changed",
5723 G_CALLBACK(arima_callback), sr);
5724 }
5725 gtk_table_attach_defaults(GTK_TABLE(tab), sr->extra[i], c, c+1, 0, 1);
5726 c++;
5727 }
5728
5729 lbl = gtk_label_new(_("specific lags"));
5730 gtk_table_attach_defaults(GTK_TABLE(tab), lbl, 0, 1, 1, 2);
5731
5732 c = 1;
5733 j = 3;
5734
5735 /* check buttons and entries for free-form lags */
5736 for (i=0; i<2; i++) {
5737 GCallback cb = (i == 0)? G_CALLBACK(toggle_p) : G_CALLBACK(toggle_q);
5738 char *fill = (i == 0)? arlags : malags;
5739
5740 chk = gtk_check_button_new();
5741 g_signal_connect(G_OBJECT(chk), "clicked", cb, sr);
5742 gtk_table_attach_defaults(GTK_TABLE(tab), chk, c, c+1, 1, 2);
5743 c++;
5744 sr->extra[j] = gtk_entry_new();
5745 gtk_entry_set_max_length(GTK_ENTRY(sr->extra[j]), 16);
5746 gtk_entry_set_width_chars(GTK_ENTRY(sr->extra[j]), 8);
5747 gtk_widget_set_sensitive(sr->extra[j], FALSE);
5748 freeform = maybe_set_entry_text(sr->extra[j], fill);
5749 gtk_table_attach_defaults(GTK_TABLE(tab), sr->extra[j], c, c+1, 1, 2);
5750 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chk), freeform);
5751 j++;
5752 c += 3;
5753 }
5754
5755 if (seasonals) {
5756 gtk_table_set_row_spacing(GTK_TABLE(tab), 1, 10);
5757 lbl = arma_aux_label(1);
5758 gtk_table_attach_defaults(GTK_TABLE(tab), lbl, 0, 1, 2, 3);
5759 c = 1;
5760 for (i=0; i<3; i++) {
5761 lbl = gtk_label_new(_(strs[i]));
5762 gtk_table_attach_defaults(GTK_TABLE(tab), lbl, c, c+1, 2, 3);
5763 c++;
5764 val = (i==0)? arma_P : (i==1)? arima_D : arma_Q;
5765 vmax = (i == 1)? 2 : 4;
5766 adj = (GtkAdjustment *) gtk_adjustment_new(val, 0, vmax, 1, 1, 0);
5767 sr->extra[j] = gtk_spin_button_new(adj, 1, 0);
5768 if (i == 1) {
5769 g_signal_connect(G_OBJECT(sr->extra[j]), "value-changed",
5770 G_CALLBACK(arima_callback), sr);
5771 }
5772 gtk_table_attach_defaults(GTK_TABLE(tab), sr->extra[j++], c, c+1, 2, 3);
5773 c++;
5774 }
5775 }
5776 }
5777
reset_arma_spinners(selector * sr)5778 static void reset_arma_spinners (selector *sr)
5779 {
5780 if (sr->extra[ARMA_p] != NULL && GTK_IS_SPIN_BUTTON(sr->extra[ARMA_p])) {
5781 gtk_spin_button_set_value(GTK_SPIN_BUTTON(sr->extra[ARMA_p]),
5782 (gdouble) arma_p);
5783 }
5784 if (sr->extra[ARIMA_d] != NULL && GTK_IS_SPIN_BUTTON(sr->extra[ARIMA_d])) {
5785 gtk_spin_button_set_value(GTK_SPIN_BUTTON(sr->extra[ARIMA_d]),
5786 (gdouble) arima_d);
5787 }
5788 if (sr->extra[ARMA_q] != NULL && GTK_IS_SPIN_BUTTON(sr->extra[ARMA_q])) {
5789 gtk_spin_button_set_value(GTK_SPIN_BUTTON(sr->extra[ARMA_q]),
5790 (gdouble) arma_q);
5791 }
5792 if (sr->extra[ARMA_plist] != NULL && GTK_IS_ENTRY(sr->extra[ARMA_plist])) {
5793 gtk_entry_set_text(GTK_ENTRY(sr->extra[ARMA_plist]), "");
5794 }
5795 if (sr->extra[ARMA_qlist] != NULL && GTK_IS_ENTRY(sr->extra[ARMA_qlist])) {
5796 gtk_entry_set_text(GTK_ENTRY(sr->extra[ARMA_qlist]), "");
5797 }
5798 if (sr->extra[ARMA_P] != NULL && GTK_IS_SPIN_BUTTON(sr->extra[ARMA_P])) {
5799 gtk_spin_button_set_value(GTK_SPIN_BUTTON(sr->extra[ARMA_P]),
5800 (gdouble) arma_P);
5801 }
5802 if (sr->extra[ARIMA_D] != NULL && GTK_IS_SPIN_BUTTON(sr->extra[ARIMA_D])) {
5803 gtk_spin_button_set_value(GTK_SPIN_BUTTON(sr->extra[ARIMA_D]),
5804 (gdouble) arima_D);
5805 }
5806 if (sr->extra[ARMA_Q] != NULL && GTK_IS_SPIN_BUTTON(sr->extra[ARMA_Q])) {
5807 gtk_spin_button_set_value(GTK_SPIN_BUTTON(sr->extra[ARMA_Q]),
5808 (gdouble) arma_Q);
5809 }
5810 }
5811
hc_config(GtkWidget * w,selector * sr)5812 static void hc_config (GtkWidget *w, selector *sr)
5813 {
5814 if (offer_cluster_option(sr->ci)) {
5815 gboolean rconf = robust_conf(sr->ci);
5816 gretlopt c_opt = OPT_NONE;
5817 int resp;
5818
5819 if (*cluster_var != '\0') {
5820 int v = current_series_index(dataset, cluster_var);
5821
5822 if (v < 1) {
5823 *cluster_var = '\0';
5824 } else if (cluster_option_is_active(sr)) {
5825 c_opt = OPT_C;
5826 }
5827 }
5828
5829 resp = hc_config_dialog(cluster_var, c_opt, rconf, sr->dlg);
5830
5831 if (resp == 0) {
5832 /* regular HCCME */
5833 if (rconf) {
5834 preferences_dialog(TAB_VCV, NULL, sr->dlg);
5835 } else {
5836 gtk_button_set_label(GTK_BUTTON(sr->hccme_button),
5837 get_default_hc_string(sr->ci));
5838 }
5839 } else if (resp == 1) {
5840 /* cluster option selected */
5841 gtk_button_set_label(GTK_BUTTON(sr->hccme_button), _("Cluster"));
5842 }
5843 } else {
5844 preferences_dialog(TAB_VCV, NULL, sr->dlg);
5845 }
5846 }
5847
5848 /* Callback for when the user selects something in the VCV
5849 tab of the preferences dialog: make sure that if there's
5850 a selection dialog open, and it's showing an HCCME
5851 button, the text on the button is synced with the
5852 user's selection.
5853 */
5854
selector_register_hc_choice(void)5855 void selector_register_hc_choice (void)
5856 {
5857 selector *sr = open_selector;
5858
5859 if (sr != NULL && sr->hccme_button != NULL) {
5860 const char *txt = get_default_hc_string(sr->ci);
5861 GtkWidget *w = sr->hccme_button;
5862
5863 if (GTK_IS_BUTTON(w)) {
5864 gtk_button_set_label(GTK_BUTTON(w), txt);
5865 } else if (GTK_IS_COMBO_BOX(w)) {
5866 gint i = gtk_combo_box_get_active(GTK_COMBO_BOX(w));
5867
5868 combo_box_remove(w, 0);
5869 combo_box_prepend_text(w, txt);
5870 gtk_combo_box_set_active(GTK_COMBO_BOX(w), i);
5871 }
5872 }
5873 }
5874
pack_switch(GtkWidget * b,selector * sr,gboolean checked,gboolean reversed,gretlopt opt,int child)5875 static GtkWidget *pack_switch (GtkWidget *b, selector *sr,
5876 gboolean checked, gboolean reversed,
5877 gretlopt opt, int child)
5878 {
5879 GtkWidget *hbox = gtk_hbox_new(FALSE, 5);
5880 gint offset = (child)? 15 : 0;
5881 gint i = opt;
5882
5883 g_object_set_data(G_OBJECT(b), "opt", GINT_TO_POINTER(i));
5884
5885 if (reversed) {
5886 g_signal_connect(G_OBJECT(b), "toggled",
5887 G_CALLBACK(reverse_option_callback), sr);
5888 if (checked) {
5889 sr->opts &= ~opt;
5890 } else {
5891 sr->opts |= opt;
5892 }
5893 } else {
5894 g_signal_connect(G_OBJECT(b), "toggled",
5895 G_CALLBACK(option_callback), sr);
5896 if (checked) {
5897 sr->opts |= opt;
5898 } else {
5899 sr->opts &= ~opt;
5900 }
5901 }
5902
5903 gtk_box_pack_start(GTK_BOX(hbox), b, TRUE, TRUE, offset);
5904 gtk_box_pack_start(GTK_BOX(sr->vbox), hbox, FALSE, FALSE, 0);
5905
5906 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b), checked);
5907
5908 return hbox;
5909 }
5910
pack_switch_in(GtkWidget * hbox,GtkWidget * b,selector * sr,gboolean checked,gboolean reversed,gretlopt opt,int child)5911 static void pack_switch_in (GtkWidget *hbox, GtkWidget *b, selector *sr,
5912 gboolean checked, gboolean reversed,
5913 gretlopt opt, int child)
5914 {
5915 gint offset = (child)? 15 : 0;
5916 gint i = opt;
5917
5918 g_object_set_data(G_OBJECT(b), "opt", GINT_TO_POINTER(i));
5919
5920 if (reversed) {
5921 g_signal_connect(G_OBJECT(b), "toggled",
5922 G_CALLBACK(reverse_option_callback), sr);
5923 if (checked) {
5924 sr->opts &= ~opt;
5925 } else {
5926 sr->opts |= opt;
5927 }
5928 } else {
5929 g_signal_connect(G_OBJECT(b), "toggled",
5930 G_CALLBACK(option_callback), sr);
5931 if (checked) {
5932 sr->opts |= opt;
5933 } else {
5934 sr->opts &= ~opt;
5935 }
5936 }
5937
5938 gtk_box_pack_start(GTK_BOX(hbox), b, TRUE, TRUE, offset);
5939 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b), checked);
5940 }
5941
call_iters_dialog(GtkWidget * w,GtkWidget * combo)5942 static void call_iters_dialog (GtkWidget *w, GtkWidget *combo)
5943 {
5944 static int optim = BFGS_MAX;
5945 selector *sr;
5946 int active, maxit, lmem = 0;
5947 double tol;
5948 int resp;
5949
5950 if (w == NULL) {
5951 /* clean-up signal */
5952 optim = libset_get_bool(USE_LBFGS)? LBFGS_MAX : BFGS_MAX;
5953 return;
5954 }
5955
5956 sr = g_object_get_data(G_OBJECT(combo), "selector");
5957 active = gtk_combo_box_get_active(GTK_COMBO_BOX(combo));
5958
5959 if (sr->ci == ARMA && active == 1) {
5960 maxit = libset_get_int(BHHH_MAXITER);
5961 tol = libset_get_double(BHHH_TOLER);
5962 optim = BHHH_MAX;
5963 } else {
5964 optim = BFGS_MAX;
5965 BFGS_defaults(&maxit, &tol, sr->ci);
5966 lmem = libset_get_int(LBFGS_MEM);
5967 }
5968
5969 if (maxit <= 0) {
5970 maxit = 1000;
5971 }
5972
5973 if (optim == BFGS_MAX && libset_get_bool(USE_LBFGS)) {
5974 optim = LBFGS_MAX;
5975 }
5976
5977 resp = iter_control_dialog(&optim, &maxit, &tol,
5978 &lmem, sr->dlg);
5979
5980 if (!canceled(resp)) {
5981 int err = 0;
5982
5983 if (optim == BHHH_MAX) {
5984 err = libset_set_int(BHHH_MAXITER, maxit);
5985 err += libset_set_double(BHHH_TOLER, tol);
5986 } else {
5987 err = libset_set_int(BFGS_MAXITER, maxit);
5988 err += libset_set_double(BFGS_TOLER, tol);
5989 }
5990
5991 if (optim == LBFGS_MAX) {
5992 libset_set_int(LBFGS_MEM, lmem);
5993 sr->opts |= OPT_L;
5994 } else {
5995 sr->opts &= ~OPT_L;
5996 }
5997
5998 if (err) {
5999 errbox("Error setting values");
6000 }
6001 }
6002 }
6003
6004 #ifdef HAVE_X12A
6005
x12a_vs_native_opts(GtkWidget * w,selector * sr)6006 static gboolean x12a_vs_native_opts (GtkWidget *w, selector *sr)
6007 {
6008 gboolean s = button_is_active(w);
6009
6010 if (sr->hess_button != NULL) {
6011 gtk_widget_set_sensitive(sr->hess_button, !s);
6012 }
6013
6014 if (sr->xdiff_button != NULL) {
6015 if (s) {
6016 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sr->xdiff_button), s);
6017 }
6018 gtk_widget_set_sensitive(sr->xdiff_button, !s && arima_selected(sr));
6019 }
6020
6021 return FALSE;
6022 }
6023
6024 #endif
6025
gui_set_mp_bits(GtkComboBox * cb,gpointer p)6026 static void gui_set_mp_bits (GtkComboBox *cb, gpointer p)
6027 {
6028 gint i = gtk_combo_box_get_active(cb);
6029 int j, b = 256;
6030
6031 for (j=0; j<i; j++) {
6032 b *= 2;
6033 }
6034
6035 libset_set_int(GMP_BITS, b);
6036 }
6037
mpols_bits_selector(void)6038 static GtkWidget *mpols_bits_selector (void)
6039 {
6040 GtkWidget *w, *hbox, *combo;
6041 char bstr[16];
6042 int bits = get_mp_bits();
6043 int b, i, deflt = 0;
6044
6045 hbox = gtk_hbox_new(FALSE, 5);
6046 w = gtk_label_new(_("Bits per floating-point value"));
6047 gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 5);
6048
6049 combo = gtk_combo_box_text_new();
6050
6051 i = 0;
6052 for (b=256; b<=4096; b*=2) {
6053 sprintf(bstr, "%d", b);
6054 combo_box_append_text(combo, bstr);
6055 if (b == bits) {
6056 deflt = i;
6057 }
6058 i++;
6059 }
6060
6061 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), deflt);
6062 g_signal_connect(G_OBJECT(GTK_COMBO_BOX(combo)), "changed",
6063 G_CALLBACK(gui_set_mp_bits), NULL);
6064 gtk_box_pack_start(GTK_BOX(hbox), combo, FALSE, FALSE, 5);
6065
6066 return hbox;
6067 }
6068
pack_adf_test_down_sel(GtkWidget * hbox)6069 static GtkWidget *pack_adf_test_down_sel (GtkWidget *hbox)
6070 {
6071 GtkWidget *combo = gtk_combo_box_text_new();
6072
6073 gtk_box_pack_start(GTK_BOX(hbox), combo, FALSE, FALSE, 5);
6074 combo_box_append_text(combo, _("AIC"));
6075 combo_box_append_text(combo, _("BIC"));
6076 combo_box_append_text(combo, _("t-statistic"));
6077 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0);
6078 return combo;
6079 }
6080
vbox_add_hwedge(GtkWidget * vbox)6081 void vbox_add_hwedge (GtkWidget *vbox)
6082 {
6083 GtkWidget *h = gtk_hbox_new(FALSE, 0);
6084
6085 gtk_box_pack_start(GTK_BOX(vbox), h, FALSE, FALSE, 2);
6086 gtk_widget_show(h);
6087 }
6088
build_selector_switches(selector * sr)6089 static void build_selector_switches (selector *sr)
6090 {
6091 GtkWidget *hbox, *tmp;
6092
6093 if (sr->ci == REPROBIT) {
6094 /* number of quadrature points for random effects probit */
6095 vbox_add_hwedge(sr->vbox);
6096 hbox = gtk_hbox_new(FALSE, 5);
6097 tmp = gtk_label_new(_("Quadrature points"));
6098 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 0);
6099 sr->extra[0] = tmp = gtk_spin_button_new_with_range(3, 64, 1);
6100 gtk_spin_button_set_value(GTK_SPIN_BUTTON(tmp), 8);
6101 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 0);
6102 gtk_box_pack_start(GTK_BOX(sr->vbox), hbox, FALSE, FALSE, 0);
6103 sr->opts |= OPT_G;
6104 }
6105
6106 if (sr->ci == OLS || sr->ci == WLS || sr->ci == INTREG ||
6107 sr->ci == GARCH || sr->ci == IVREG || sr->ci == VAR ||
6108 sr->ci == LOGIT || sr->ci == PROBIT || sr->ci == MLOGIT ||
6109 sr->ci == OLOGIT || sr->ci == OPROBIT || sr->ci == COUNTMOD ||
6110 sr->ci == DURATION || sr->ci == PANEL || sr->ci == QUANTREG ||
6111 sr->ci == HECKIT || sr->ci == BIPROBIT || sr->ci == TOBIT ||
6112 sr->ci == MIDASREG || sr->ci == LOGISTIC ||
6113 sr->ci == FE_LOGISTIC) {
6114 GtkWidget *b1;
6115
6116 /* FIXME arma robust variant? (and REPROBIT should be here?) */
6117
6118 vbox_add_hwedge(sr->vbox);
6119
6120 if (sr->ci == QUANTREG) {
6121 b1 = gtk_check_button_new_with_label(_("Robust standard errors/intervals"));
6122 } else {
6123 b1 = gtk_check_button_new_with_label(_("Robust standard errors"));
6124 }
6125
6126 g_object_set_data(G_OBJECT(b1), "opt", GINT_TO_POINTER(OPT_R));
6127 g_signal_connect(G_OBJECT(b1), "toggled",
6128 G_CALLBACK(option_callback), sr);
6129
6130 if (robust_conf(sr->ci) && using_hc_by_default()) {
6131 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b1), TRUE);
6132 } else if (model_opt & OPT_R) {
6133 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b1), TRUE);
6134 }
6135
6136 if (sr->ci == PANEL) {
6137 g_object_set_data(G_OBJECT(sr->dlg), "robust-button", b1);
6138 }
6139
6140 hbox = gtk_hbox_new(FALSE, 5);
6141 gtk_box_pack_start(GTK_BOX(hbox), b1, FALSE, FALSE, 0);
6142
6143 if (sr->ci == VAR) {
6144 /* special: we don't use HAC by default */
6145 GtkWidget *b2 = gtk_combo_box_text_new();
6146
6147 sr->hccme_button = b2;
6148 combo_box_append_text(b2, get_default_hc_string(VAR));
6149 combo_box_append_text(b2, "HAC");
6150 gtk_combo_box_set_active(GTK_COMBO_BOX(b2), 0);
6151 gtk_widget_set_sensitive(b2, using_hc_by_default());
6152 sensitize_conditional_on(b2, b1);
6153 if (model_opt & OPT_R) {
6154 gtk_widget_set_sensitive(b2, TRUE);
6155 }
6156 gtk_box_pack_start(GTK_BOX(hbox), b2, FALSE, FALSE, 0);
6157 } else if (robust_conf(sr->ci) || offer_cluster_option(sr->ci)) {
6158 const char *deftxt;
6159 GtkWidget *b2;
6160
6161 deftxt = get_default_hc_string(sr->ci);
6162 sr->hccme_button = b2 = gtk_button_new_with_label(deftxt);
6163 g_signal_connect(G_OBJECT(b2), "clicked",
6164 G_CALLBACK(hc_config), sr);
6165 gtk_widget_set_sensitive(b2, using_hc_by_default());
6166 sensitize_conditional_on(b2, b1);
6167 if (model_opt & OPT_R) {
6168 gtk_widget_set_sensitive(b2, TRUE);
6169 }
6170 gtk_box_pack_start(GTK_BOX(hbox), b2, FALSE, FALSE, 0);
6171 }
6172
6173 gtk_box_pack_start(GTK_BOX(sr->vbox), hbox, FALSE, FALSE, 0);
6174 }
6175
6176 if (sr->ci == ARMA) {
6177 hbox = gtk_hbox_new(FALSE, 5);
6178 vbox_add_vwedge(sr->vbox);
6179 tmp = gtk_check_button_new_with_label(_("Include a constant"));
6180 pack_switch_in(hbox, tmp, sr, arma_const, TRUE, OPT_N, 0);
6181 tmp = gtk_check_button_new_with_label(_("Show details of iterations"));
6182 pack_switch_in(hbox, tmp, sr, verbose, FALSE, OPT_V, 0);
6183 gtk_box_pack_start(GTK_BOX(sr->vbox), hbox, FALSE, FALSE, 0);
6184 } else if (sr->ci == TOBIT || sr->ci == GARCH ||
6185 sr->ci == LOGIT || sr->ci == PROBIT || sr->ci == HECKIT ||
6186 sr->ci == OLOGIT || sr->ci == OPROBIT || sr->ci == MLOGIT ||
6187 sr->ci == BIPROBIT || sr->ci == REPROBIT) {
6188 if (sr->ci == GARCH) {
6189 tmp = gtk_check_button_new_with_label(_("Include a constant"));
6190 pack_switch(tmp, sr, garch_const, TRUE, OPT_N, 0);
6191 }
6192 tmp = gtk_check_button_new_with_label(_("Show details of iterations"));
6193 pack_switch(tmp, sr, verbose, FALSE, OPT_V, 0);
6194 } else if (sr->ci == COINT2 || sr->ci == VECM ||
6195 sr->ci == VAR || sr->ci == VLAGSEL) {
6196 if (sr->ci == VAR || sr->ci == VLAGSEL) {
6197 tmp = gtk_check_button_new_with_label(_("Include a constant"));
6198 pack_switch(tmp, sr, varconst, TRUE, OPT_N, 0);
6199 tmp = gtk_check_button_new_with_label(_("Include a trend"));
6200 pack_switch(tmp, sr, vartrend, FALSE, OPT_T, 0);
6201 } else {
6202 tmp = gtk_check_button_new_with_label(_("Show details of regressions"));
6203 pack_switch(tmp, sr, verbose, FALSE, OPT_V, 0);
6204 }
6205 tmp = gtk_check_button_new_with_label(_("Include seasonal dummies"));
6206 pack_switch(tmp, sr,
6207 want_seasonals && (dataset->pd == 4 || dataset->pd == 12),
6208 FALSE, OPT_D, 0);
6209 if (dataset->pd != 4 && dataset->pd != 12) {
6210 gtk_widget_set_sensitive(tmp, FALSE);
6211 }
6212 } else if (sr->ci == COINT) {
6213 GtkWidget *combo;
6214
6215 hbox = gtk_hbox_new(FALSE, 5);
6216 tmp = gtk_check_button_new_with_label(_("Test down from maximum lag order"));
6217 pack_switch_in(hbox, tmp, sr, FALSE, FALSE, OPT_E, 0);
6218 sr->extra[EXTRA_LAGS] = combo = pack_adf_test_down_sel(hbox);
6219 gtk_widget_set_sensitive(combo, button_is_active(tmp));
6220 sensitize_conditional_on(combo, tmp);
6221 gtk_box_pack_start(GTK_BOX(sr->vbox), hbox, FALSE, FALSE, 0);
6222 tmp = gtk_check_button_new_with_label(_("Skip initial DF tests"));
6223 pack_switch(tmp, sr, FALSE, FALSE, OPT_S, 0);
6224 tmp = gtk_check_button_new_with_label(_("Show details of regressions"));
6225 pack_switch(tmp, sr, verbose, FALSE, OPT_V, 0);
6226 tmp = gtk_check_button_new_with_label(_("Include seasonal dummies"));
6227 pack_switch(tmp, sr,
6228 want_seasonals && (dataset->pd == 4 || dataset->pd == 12),
6229 FALSE, OPT_D, 0);
6230 if (dataset->pd != 4 && dataset->pd != 12) {
6231 gtk_widget_set_sensitive(tmp, FALSE);
6232 }
6233 } else if (sr->ci == PANEL_WLS) {
6234 tmp = gtk_check_button_new_with_label(_("Iterated weighted least squares"));
6235 pack_switch(tmp, sr, FALSE, FALSE, OPT_I, 0);
6236 } else if (sr->ci == PANEL || (sr->ci == OLS && dataset_is_panel(dataset))) {
6237 tmp = gtk_check_button_new_with_label(_("Include time dummies"));
6238 pack_switch(tmp, sr, (model_opt & OPT_D), FALSE, OPT_D, 0);
6239 } else if (sr->ci == DPANEL) {
6240 tmp = gtk_check_button_new_with_label(_("Include time dummies"));
6241 pack_switch(tmp, sr, (model_opt & OPT_D), FALSE, OPT_D, 0);
6242 tmp = gtk_check_button_new_with_label(_("Include levels equations (GMM-SYS)"));
6243 pack_switch(tmp, sr, (model_opt & OPT_L), FALSE, OPT_L, 0);
6244 tmp = gtk_check_button_new_with_label(_("Asymptotic standard errors"));
6245 pack_switch(tmp, sr, (dpd_asy || (model_opt & OPT_A)), FALSE, OPT_A, 0);
6246 tmp = gtk_check_button_new_with_label(_("DPD-style initial covariance matrix"));
6247 pack_switch(tmp, sr, (dpd_dpd || (model_opt & OPT_X)), FALSE, OPT_X, 0);
6248 } else if (sr->ci == XTAB) {
6249 tmp = gtk_check_button_new_with_label(_("Show zeros explicitly"));
6250 pack_switch(tmp, sr, FALSE, FALSE, OPT_Z, 0);
6251 } else if (sr->ci == CORR) {
6252 sr->extra[0] = gtk_check_button_new_with_label(_("Ensure uniform sample size"));
6253 pack_switch(sr->extra[0], sr, verbose, FALSE, OPT_N, 0);
6254 gtk_widget_set_sensitive(sr->extra[0], get_n_rvars1() > 2);
6255 } else if (sr->ci == GR_3D) {
6256 tmp = gtk_check_button_new_with_label(_("Make plot interactive"));
6257 pack_switch(tmp, sr, TRUE, FALSE, OPT_I, 0);
6258 } else if (sr->ci == GR_BOX) {
6259 tmp = gtk_check_button_new_with_label(_("Show interval for median"));
6260 pack_switch(tmp, sr, FALSE, FALSE, OPT_O, 0);
6261 } else if (sr->ci == HSK) {
6262 tmp = gtk_check_button_new_with_label(_("Variance equation includes squares"));
6263 pack_switch(tmp, sr, TRUE, TRUE, OPT_N, 0);
6264 }
6265
6266 if (sr->ci == ARMA) {
6267 sr->hess_button =
6268 gtk_check_button_new_with_label(_("Parameter covariance matrix via Hessian"));
6269 pack_switch(sr->hess_button, sr, arma_hessian, TRUE, OPT_G, 0);
6270 sr->xdiff_button = gtk_check_button_new_with_label(_("Difference the independent variables"));
6271 pack_switch(sr->xdiff_button, sr, arima_xdiff, TRUE, OPT_Y, 0);
6272 gtk_widget_set_sensitive(sr->xdiff_button, (arima_d > 0 || arima_D > 0) && !arma_x12);
6273 #ifdef HAVE_X12A
6274 sr->x12a_button = gtk_check_button_new_with_label(_("Use X-12-ARIMA"));
6275 pack_switch(sr->x12a_button, sr, arma_x12, FALSE, OPT_X, 0);
6276 g_signal_connect(G_OBJECT(sr->x12a_button), "toggled",
6277 G_CALLBACK(x12a_vs_native_opts), sr);
6278 #endif
6279 } else if (sr->ci == GARCH) {
6280 tmp = gtk_check_button_new_with_label(_("Standardize the residuals"));
6281 pack_switch(tmp, sr, (model_opt & OPT_Z), FALSE, OPT_Z, 0);
6282 tmp = gtk_check_button_new_with_label(_("Use Fiorentini et al algorithm"));
6283 pack_switch(tmp, sr, (model_opt & OPT_F), FALSE, OPT_F, 0);
6284 } else if (sr->ci == MPOLS) {
6285 hbox = mpols_bits_selector();
6286 gtk_box_pack_start(GTK_BOX(sr->vbox), hbox, FALSE, FALSE, 5);
6287 } else if (sr->ci == MIDASREG) {
6288 tmp = gtk_check_button_new_with_label(_("Prefer NLS via Levenberg-Marquardt"));
6289 pack_switch(tmp, sr, (model_opt & OPT_L), FALSE, OPT_L, 0);
6290 }
6291 }
6292
unhide_lags_callback(GtkWidget * w,selector * sr)6293 static void unhide_lags_callback (GtkWidget *w, selector *sr)
6294 {
6295 int i, imin, show_lags;
6296 GtkListStore *store;
6297 GtkTreeIter iter;
6298
6299 store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(sr->lvars)));
6300 gtk_list_store_clear(store);
6301 gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter);
6302
6303 imin = (sr->ci == DEFINE_LIST)? 0 : 1;
6304 show_lags = button_is_active(w);
6305
6306 for (i=imin; i<dataset->v; i++) {
6307 if (list_show_var(i, sr->ci, show_lags)) {
6308 list_append_var_simple(store, &iter, i);
6309 }
6310 }
6311 }
6312
unhide_lags_switch(selector * sr)6313 static void unhide_lags_switch (selector *sr)
6314 {
6315 GtkWidget *hbox;
6316 GtkWidget *b;
6317
6318 vbox_add_vwedge(sr->vbox);
6319
6320 b = gtk_check_button_new_with_label(_("Show lagged variables"));
6321 g_signal_connect(G_OBJECT(b), "toggled",
6322 G_CALLBACK(unhide_lags_callback), sr);
6323
6324 hbox = gtk_hbox_new(FALSE, 5);
6325 gtk_box_pack_start(GTK_BOX(hbox), b, FALSE, FALSE, 0);
6326 gtk_box_pack_start(GTK_BOX(sr->vbox), hbox, FALSE, FALSE, 0);
6327 }
6328
6329 #if 0 /* not ready */
6330
6331 static void boot_switch_callback (GtkWidget *w, selector *sr)
6332 {
6333 if (button_is_active(w)) {
6334 sr->opts |= OPT_P;
6335 } else {
6336 sr->opts &= ~OPT_P;
6337 }
6338 }
6339
6340 static void test_boot_switch (selector *sr)
6341 {
6342 GtkWidget *hbox;
6343 GtkWidget *b;
6344
6345 vbox_add_vwedge(sr->vbox);
6346
6347 b = gtk_check_button_new_with_label(_("Use bootstrap"));
6348 g_signal_connect(G_OBJECT(b), "toggled",
6349 G_CALLBACK(boot_switch_callback), sr);
6350
6351 hbox = gtk_hbox_new(FALSE, 5);
6352 gtk_box_pack_start(GTK_BOX(hbox), b, FALSE, FALSE, 0);
6353 gtk_box_pack_start(GTK_BOX(sr->vbox), hbox, FALSE, FALSE, 0);
6354 }
6355
6356 #endif
6357
pack_switch_with_extra(GtkWidget * b,selector * sr,gboolean checked,gretlopt opt,int child,GtkWidget * extra,const gchar * extra_text)6358 static void pack_switch_with_extra (GtkWidget *b, selector *sr,
6359 gboolean checked, gretlopt opt,
6360 int child, GtkWidget *extra,
6361 const gchar *extra_text)
6362 {
6363 GtkWidget *hbox = gtk_hbox_new(FALSE, 5);
6364 gint offset = (child)? 15 : 0;
6365 gint i = opt;
6366
6367 g_object_set_data(G_OBJECT(b), "opt", GINT_TO_POINTER(i));
6368 g_signal_connect(G_OBJECT(b), "toggled",
6369 G_CALLBACK(option_callback), sr);
6370 if (checked) {
6371 sr->opts |= opt;
6372 } else {
6373 sr->opts &= ~opt;
6374 }
6375 gtk_box_pack_start(GTK_BOX(hbox), b, TRUE, TRUE, offset);
6376
6377 if (extra_text != NULL) {
6378 GtkWidget *w = gtk_label_new(extra_text);
6379
6380 gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 5);
6381 }
6382
6383 gtk_box_pack_start(GTK_BOX(hbox), extra, TRUE, TRUE, offset);
6384 gtk_box_pack_start(GTK_BOX(sr->vbox), hbox, FALSE, FALSE, 0);
6385
6386 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b), checked);
6387 }
6388
alpha_spinner(double deflt,double minval)6389 static GtkWidget *alpha_spinner (double deflt, double minval)
6390 {
6391 GtkAdjustment *adj;
6392
6393 adj = (GtkAdjustment *) gtk_adjustment_new(deflt, minval, 0.99,
6394 0.01, 0.1, 0);
6395 return gtk_spin_button_new(adj, 1, 2);
6396 }
6397
build_quantreg_radios(selector * sr)6398 static void build_quantreg_radios (selector *sr)
6399 {
6400 GtkWidget *b1, *b2;
6401 GSList *group;
6402
6403 b1 = gtk_radio_button_new_with_label(NULL, _("Compute standard errors"));
6404 pack_switch(b1, sr, TRUE, FALSE, OPT_NONE, 0);
6405
6406 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(b1));
6407 b2 = gtk_radio_button_new_with_label(group,
6408 _("Compute confidence intervals"));
6409 sr->extra[1] = alpha_spinner(0.90, 0.70);
6410 pack_switch_with_extra(b2, sr, FALSE, OPT_I, 0, sr->extra[1], "1 - α =");
6411 gtk_widget_set_sensitive(sr->extra[1], FALSE);
6412 sensitize_conditional_on(sr->extra[1], b2);
6413 }
6414
ymax_spinner(void)6415 static GtkWidget *ymax_spinner (void)
6416 {
6417 GtkAdjustment *adj;
6418
6419 adj = (GtkAdjustment *) gtk_adjustment_new(1.0, 0, 1e+10, 0.01, 0.1, 0);
6420 return gtk_spin_button_new(adj, 1, 1);
6421 }
6422
single_lambda_spinner(double lam)6423 static GtkWidget *single_lambda_spinner (double lam)
6424 {
6425 GtkAdjustment *adj;
6426
6427 adj = (GtkAdjustment *) gtk_adjustment_new(lam, 0, 1, 0.001, 0.1, 0);
6428 return gtk_spin_button_new(adj, 1, 3);
6429 }
6430
multi_lambda_spinner(int nlam)6431 static GtkWidget *multi_lambda_spinner (int nlam)
6432 {
6433 GtkAdjustment *adj;
6434
6435 adj = (GtkAdjustment *) gtk_adjustment_new(nlam, 4, 100, 1, 10, 0);
6436 return gtk_spin_button_new(adj, 1, 0);
6437 }
6438
regls_alpha_spinner(double alpha)6439 static GtkWidget *regls_alpha_spinner (double alpha)
6440 {
6441 GtkAdjustment *adj;
6442
6443 adj = (GtkAdjustment *) gtk_adjustment_new(alpha, 0, 1, 0.1, 0.1, 0);
6444 return gtk_spin_button_new(adj, 1, 1);
6445 }
6446
build_logistic_radios(selector * sr)6447 static void build_logistic_radios (selector *sr)
6448 {
6449 GtkWidget *b1, *b2;
6450 GSList *group;
6451
6452 vbox_add_vwedge(sr->vbox);
6453
6454 b1 = gtk_radio_button_new_with_label(NULL, _("Automatic maximum"));
6455 pack_switch(b1, sr, TRUE, FALSE, OPT_NONE, 0);
6456
6457 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(b1));
6458 b2 = gtk_radio_button_new_with_label(group,
6459 _("Specified maximum"));
6460 sr->extra[1] = ymax_spinner();
6461 pack_switch_with_extra(b2, sr, FALSE, OPT_M, 0, sr->extra[1], NULL);
6462 gtk_widget_set_sensitive(sr->extra[1], FALSE);
6463 sensitize_conditional_on(sr->extra[1], b2);
6464 }
6465
regls_estim_switch(GtkComboBox * cb,selector * sr)6466 static void regls_estim_switch (GtkComboBox *cb, selector *sr)
6467 {
6468 GtkWidget *aspin = sr->extra[REGLS_ALPHA];
6469 gchar *estr = combo_box_get_active_text(cb);
6470
6471 if (!strcmp(estr, _("LASSO"))) {
6472 gtk_spin_button_set_value(GTK_SPIN_BUTTON(aspin), 1);
6473 gtk_widget_set_sensitive(aspin, FALSE);
6474 } else if (!strcmp(estr, _("Ridge"))) {
6475 gtk_spin_button_set_value(GTK_SPIN_BUTTON(aspin), 0);
6476 gtk_widget_set_sensitive(aspin, FALSE);
6477 } else {
6478 /* elastic net */
6479 double a = gtk_spin_button_get_value(GTK_SPIN_BUTTON(aspin));
6480
6481 if (a == 0 || a == 1) {
6482 gtk_spin_button_set_value(GTK_SPIN_BUTTON(aspin), 0.5);
6483 }
6484 gtk_widget_set_sensitive(aspin, TRUE);
6485 }
6486
6487 g_free(estr);
6488 }
6489
xvalidation_ok(GtkToggleButton * b,GtkWidget * targ)6490 static void xvalidation_ok (GtkToggleButton *b, GtkWidget *targ)
6491 {
6492 gtk_widget_set_sensitive(targ, button_is_active(b));
6493 }
6494
call_regls_advanced(GtkWidget * w,selector * sr)6495 static void call_regls_advanced (GtkWidget *w, selector *sr)
6496 {
6497 if (regls_adv == NULL) {
6498 double seed = (double) gretl_rand_get_seed();
6499
6500 regls_adv = gretl_bundle_new();
6501 gretl_bundle_set_int(regls_adv, "lccd", 0);
6502 gretl_bundle_set_int(regls_adv, "rccd", 0);
6503 gretl_bundle_set_int(regls_adv, "use_1se", 0);
6504 gretl_bundle_set_int(regls_adv, "timer", 0);
6505 gretl_bundle_set_int(regls_adv, "set_seed", 0);
6506 gretl_bundle_set_scalar(regls_adv, "seed", seed);
6507 #ifdef HAVE_MPI
6508 gretl_bundle_set_int(regls_adv, "no_mpi", 0);
6509 #endif
6510 }
6511
6512 regls_advanced_dialog(regls_adv, sr->dlg);
6513 }
6514
regls_int_default(const char * key)6515 static int regls_int_default (const char *key)
6516 {
6517 if (gretl_bundle_has_key(regls_bundle, key)) {
6518 return gretl_bundle_get_int(regls_bundle, key, NULL);
6519 } else if (!strcmp(key, "nlambda")) {
6520 return 25;
6521 } else if (!strcmp(key, "nfolds")) {
6522 return 10;
6523 } else if (!strcmp(key, "randfolds")) {
6524 return 1;
6525 } else if (!strcmp(key, "crit_plot")) {
6526 return 1;
6527 } else if (!strcmp(key, "eid")) {
6528 if (gretl_bundle_get_int(regls_bundle, "ridge", NULL)) {
6529 return 1;
6530 } else if (gretl_bundle_has_key(regls_bundle, "alpha")) {
6531 return 2;
6532 }
6533 }
6534
6535 return 0;
6536 }
6537
regls_scalar_default(const char * key)6538 static double regls_scalar_default (const char *key)
6539 {
6540 if (gretl_bundle_has_key(regls_bundle, key)) {
6541 return gretl_bundle_get_scalar(regls_bundle, key, NULL);
6542 } else if (!strcmp(key, "lfrac")) {
6543 return 0.5;
6544 } else if (!strcmp(key, "alpha")) {
6545 return 1.0;
6546 } else {
6547 return 0.0;
6548 }
6549 }
6550
build_regls_controls(selector * sr)6551 static void build_regls_controls (selector *sr)
6552 {
6553 GtkWidget *w, *hbox, *b1, *b2, *b3;
6554 int nlambda, xvalidate, nfolds, randfolds;
6555 int eid, crit_plot;
6556 double lfrac, alpha;
6557 GSList *group;
6558
6559 if (regls_bundle == NULL) {
6560 regls_bundle = gretl_bundle_new();
6561 }
6562
6563 eid = regls_int_default("eid");
6564 nlambda = regls_int_default("nlambda");
6565 xvalidate = regls_int_default("xvalidate");
6566 nfolds = regls_int_default("nfolds");
6567 randfolds = regls_int_default("randfolds");
6568 crit_plot = regls_int_default("crit_plot");
6569
6570 lfrac = regls_scalar_default("lfrac");
6571 alpha = regls_scalar_default("alpha");
6572
6573 vbox_add_vwedge(sr->vbox);
6574
6575 /* choice of estimator */
6576 hbox = gtk_hbox_new(FALSE, 5);
6577 w = gtk_label_new("Estimator");
6578 gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 5);
6579 sr->extra[REGLS_EST] = w = gtk_combo_box_text_new();
6580 combo_box_append_text(w, _("LASSO"));
6581 combo_box_append_text(w, _("Ridge"));
6582 combo_box_append_text(w, _("Elastic net"));
6583 gtk_combo_box_set_active(GTK_COMBO_BOX(w), eid);
6584 gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 5);
6585 w = gtk_label_new("α =");
6586 gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 5);
6587 sr->extra[REGLS_ALPHA] = w = regls_alpha_spinner(alpha);
6588 gtk_widget_set_sensitive(w, (eid == 2));
6589 gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 0);
6590 gtk_box_pack_start(GTK_BOX(sr->vbox), hbox, FALSE, FALSE, 0);
6591 g_signal_connect(G_OBJECT(sr->extra[REGLS_EST]), "changed",
6592 G_CALLBACK(regls_estim_switch), sr);
6593
6594 vbox_add_vwedge(sr->vbox);
6595
6596 /* single lambda value */
6597 hbox = gtk_hbox_new(FALSE, 5);
6598 b1 = gtk_radio_button_new_with_label(NULL, _("Single λ-fraction"));
6599 gtk_box_pack_start(GTK_BOX(hbox), b1, FALSE, FALSE, 5);
6600 w = sr->extra[REGLS_LAMVAL] = single_lambda_spinner(lfrac);
6601 sensitize_conditional_on(w, b1);
6602 gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 0);
6603 gtk_box_pack_start(GTK_BOX(sr->vbox), hbox, FALSE, FALSE, 0);
6604
6605 /* multiple lambda values */
6606 hbox = gtk_hbox_new(FALSE, 5);
6607 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(b1));
6608 b2 = gtk_radio_button_new_with_label(group, _("Multiple λ values"));
6609 gtk_box_pack_start(GTK_BOX(hbox), b2, FALSE, FALSE, 5);
6610 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b2), xvalidate);
6611 w = sr->extra[REGLS_NLAM] = multi_lambda_spinner(nlambda);
6612 gtk_widget_set_sensitive(w, xvalidate);
6613 sensitize_conditional_on(w, b2);
6614 gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 0);
6615 gtk_box_pack_start(GTK_BOX(sr->vbox), hbox, FALSE, FALSE, 0);
6616
6617 /* cross validation */
6618 hbox = gtk_hbox_new(FALSE, 5);
6619 b3 = gtk_check_button_new_with_label(_("Optimize via cross-validation"));
6620 gtk_widget_set_sensitive(b3, xvalidate);
6621 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b3), xvalidate);
6622 gtk_box_pack_start(GTK_BOX(hbox), b3, FALSE, FALSE, 5);
6623 gtk_box_pack_start(GTK_BOX(sr->vbox), hbox, FALSE, FALSE, 0);
6624 hbox = gtk_hbox_new(FALSE, 5);
6625 w = gtk_label_new(_("Folds:"));
6626 gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 5);
6627 sr->extra[REGLS_NFOLDS] = w = gtk_spin_button_new_with_range(4, 20, 1);
6628 gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), nfolds);
6629 gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 5);
6630 w = gtk_label_new(_("type:"));
6631 gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 5);
6632 sr->extra[REGLS_FTYPE] = w = gtk_combo_box_text_new();
6633 combo_box_append_text(w, _("random"));
6634 combo_box_append_text(w, _("contiguous"));
6635 gtk_combo_box_set_active(GTK_COMBO_BOX(w), randfolds? 0 : 1);
6636 gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 5);
6637 gtk_box_pack_start(GTK_BOX(sr->vbox), hbox, FALSE, FALSE, 0);
6638 gtk_widget_set_sensitive(hbox, xvalidate);
6639 sensitize_conditional_on(hbox, b3);
6640
6641 /* optional plot */
6642 hbox = gtk_hbox_new(FALSE, 5);
6643 w = gtk_check_button_new_with_label(_("Show criterion plot"));
6644 sr->extra[REGLS_PLOT] = w;
6645 gtk_widget_set_sensitive(w, xvalidate);
6646 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), xvalidate && crit_plot);
6647 gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 5);
6648 gtk_box_pack_start(GTK_BOX(sr->vbox), hbox, FALSE, FALSE, 0);
6649 sensitize_conditional_on(hbox, b2);
6650
6651 /* note: b2 = multiple lambdas, b3 = xvalidate, w = plot */
6652 g_signal_connect(G_OBJECT(b2), "toggled",
6653 G_CALLBACK(xvalidation_ok), b3);
6654 g_signal_connect(G_OBJECT(b2), "toggled",
6655 G_CALLBACK(xvalidation_ok), w);
6656
6657 /* "advanced" controls */
6658 hbox = gtk_hbox_new(FALSE, 5);
6659 w = gtk_button_new_with_label("Advanced...");
6660 g_signal_connect(G_OBJECT(w), "clicked",
6661 G_CALLBACK(call_regls_advanced), sr);
6662 gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 5);
6663 gtk_box_pack_start(GTK_BOX(sr->vbox), hbox, FALSE, FALSE, 5);
6664 }
6665
build_ellipse_spinner(selector * sr)6666 static void build_ellipse_spinner (selector *sr)
6667 {
6668 GtkWidget *hbox = gtk_hbox_new(FALSE, 5);
6669 GtkWidget *label;
6670
6671 vbox_add_vwedge(sr->vbox);
6672
6673 label = gtk_label_new("");
6674 gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
6675
6676 label = gtk_label_new(_("Confidence level"));
6677 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
6678
6679 label = gtk_label_new("1 - α =");
6680 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
6681
6682 sr->extra[0] = alpha_spinner(0.95, 0.70);
6683 gtk_box_pack_start(GTK_BOX(hbox), sr->extra[0], FALSE, FALSE, 0);
6684
6685 gtk_box_pack_start(GTK_BOX(sr->vbox), hbox, FALSE, FALSE, 0);
6686 }
6687
build_pca_radios(selector * sr)6688 static void build_pca_radios (selector *sr)
6689 {
6690 GtkWidget *b1, *b2;
6691 GSList *group;
6692
6693 b1 = gtk_radio_button_new_with_label(NULL, _("Use correlation matrix"));
6694 pack_switch(b1, sr, TRUE, FALSE, OPT_NONE, 0);
6695
6696 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(b1));
6697 b2 = gtk_radio_button_new_with_label(group, _("Use covariance matrix"));
6698 pack_switch(b2, sr, FALSE, FALSE, OPT_C, 0);
6699 }
6700
build_pvalues_radios(selector * sr)6701 static void build_pvalues_radios (selector *sr)
6702 {
6703 GtkWidget *b1, *b2;
6704 GSList *group;
6705
6706 b1 = gtk_radio_button_new_with_label(NULL, _("Show slopes at mean"));
6707 pack_switch(b1, sr, TRUE, FALSE, OPT_NONE, 0);
6708
6709 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(b1));
6710 b2 = gtk_radio_button_new_with_label(group, _("Show p-values"));
6711 pack_switch(b2, sr, FALSE, FALSE, OPT_P, 0);
6712
6713 if (lp_pvals) {
6714 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b2), TRUE);
6715 } else {
6716 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b1), TRUE);
6717 }
6718 }
6719
build_scatters_radios(selector * sr)6720 static void build_scatters_radios (selector *sr)
6721 {
6722 GtkWidget *b1, *b2;
6723 GSList *group;
6724
6725 b1 = gtk_radio_button_new_with_label(NULL, _("Use points"));
6726 pack_switch(b1, sr, TRUE, FALSE, OPT_NONE, 0);
6727
6728 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(b1));
6729 b2 = gtk_radio_button_new_with_label(group, _("Use lines"));
6730 pack_switch(b2, sr, FALSE, FALSE, OPT_O, 0);
6731 }
6732
auto_omit_restrict_callback(GtkWidget * w,selector * sr)6733 static void auto_omit_restrict_callback (GtkWidget *w, selector *sr)
6734 {
6735 gboolean r = button_is_active(w);
6736
6737 if (sr->lvars != NULL) {
6738 gtk_widget_set_sensitive(sr->lvars, r);
6739 }
6740
6741 if (sr->rvars1 != NULL) {
6742 gtk_widget_set_sensitive(sr->rvars1, r);
6743 }
6744
6745 gtk_widget_set_sensitive(sr->add_button, r);
6746 gtk_widget_set_sensitive(sr->remove_button, r);
6747 }
6748
auto_omit_callback(GtkWidget * w,selector * sr)6749 static void auto_omit_callback (GtkWidget *w, selector *sr)
6750 {
6751 gboolean s = button_is_active(w);
6752 gboolean arrows = !s;
6753
6754 if (sr->extra[0] != NULL) {
6755 gtk_widget_set_sensitive(sr->extra[0], s);
6756 }
6757
6758 if (sr->extra[1] != NULL) {
6759 if (button_is_active(sr->extra[1])) {
6760 arrows = TRUE;
6761 }
6762 gtk_widget_set_sensitive(sr->extra[1], s);
6763 }
6764
6765 if (sr->lvars != NULL) {
6766 gtk_widget_set_sensitive(sr->lvars, arrows);
6767 }
6768
6769 if (sr->rvars1 != NULL) {
6770 gtk_widget_set_sensitive(sr->rvars1, arrows);
6771 }
6772
6773 gtk_widget_set_sensitive(sr->add_button, arrows);
6774 gtk_widget_set_sensitive(sr->remove_button, arrows);
6775 }
6776
build_add_test_radios(selector * sr)6777 static void build_add_test_radios (selector *sr)
6778 {
6779 GtkWidget *b1, *b2;
6780 GSList *group;
6781
6782 vbox_add_vwedge(sr->vbox);
6783
6784 b1 = gtk_radio_button_new_with_label(NULL, _("Estimate augmented model"));
6785 pack_switch(b1, sr, TRUE, FALSE, OPT_NONE, 0);
6786
6787 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(b1));
6788 b2 = gtk_radio_button_new_with_label(group, _("LM test using auxiliary regression"));
6789 pack_switch(b2, sr, FALSE, FALSE, OPT_L, 0);
6790 }
6791
build_omit_test_radios(selector * sr)6792 static void build_omit_test_radios (selector *sr)
6793 {
6794 windata_t *vwin = (windata_t *) sr->data;
6795 GtkWidget *b1, *b2, *b3;
6796 GSList *group;
6797 int auto_ok = 0;
6798
6799 vbox_add_vwedge(sr->vbox);
6800
6801 b1 = gtk_radio_button_new_with_label(NULL, _("Estimate reduced model"));
6802 pack_switch(b1, sr, TRUE, FALSE, OPT_NONE, 0);
6803
6804 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(b1));
6805 b2 = gtk_radio_button_new_with_label(group, _("Wald test, based on covariance matrix"));
6806 pack_switch(b2, sr, FALSE, FALSE, OPT_W, 0);
6807
6808 if (sr->ci != VAROMIT) {
6809 MODEL *pmod = (MODEL *) vwin->data;
6810
6811 if (pmod != NULL) {
6812 auto_ok = (pmod->ci != PANEL);
6813 }
6814 }
6815
6816 if (auto_ok) {
6817 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(b2));
6818 b3 = gtk_radio_button_new_with_label(group, _("Sequential elimination of variables\n"
6819 "using two-sided p-value:"));
6820 g_signal_connect(G_OBJECT(b3), "toggled",
6821 G_CALLBACK(auto_omit_callback), sr);
6822
6823 sr->extra[0] = alpha_spinner(0.10, 0.01);
6824 pack_switch_with_extra(b3, sr, FALSE, OPT_A, 0, sr->extra[0], NULL);
6825 gtk_widget_set_sensitive(sr->extra[0], FALSE);
6826
6827 sr->extra[1] = gtk_check_button_new_with_label(_("Test only selected variables"));
6828 pack_switch(sr->extra[1], sr, FALSE, FALSE, OPT_NONE, 1);
6829 gtk_widget_set_sensitive(sr->extra[1], FALSE);
6830 g_signal_connect(G_OBJECT(sr->extra[1]), "toggled",
6831 G_CALLBACK(auto_omit_restrict_callback), sr);
6832 }
6833 }
6834
select_re_method(GtkComboBox * box,selector * sr)6835 static void select_re_method (GtkComboBox *box, selector *sr)
6836 {
6837 int a = gtk_combo_box_get_active(box);
6838
6839 if (a == 2) {
6840 sr->opts |= OPT_N;
6841 sr->opts &= ~OPT_X;
6842 } else {
6843 sr->opts &= ~OPT_N;
6844 if (a == 1) {
6845 sr->opts |= OPT_X;
6846 } else {
6847 sr->opts &= ~OPT_X;
6848 }
6849 }
6850 }
6851
build_panel_radios(selector * sr)6852 static void build_panel_radios (selector *sr)
6853 {
6854 GtkWidget *b1, *b2, *hbox, *w;
6855 GSList *group;
6856 gboolean fe = TRUE;
6857
6858 if (sr->opts & OPT_H) {
6859 /* panel weighted least squares */
6860 return;
6861 }
6862
6863 if (model_opt & OPT_U) {
6864 fe = FALSE;
6865 }
6866
6867 b1 = gtk_radio_button_new_with_label(NULL, _("Fixed effects"));
6868 pack_switch(b1, sr, fe, FALSE, OPT_NONE, 0);
6869
6870 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(b1));
6871 b2 = gtk_radio_button_new_with_label(group, _("Random effects"));
6872 hbox = pack_switch(b2, sr, !fe, FALSE, OPT_U, 0);
6873
6874 /* random effects transformation selector */
6875 w = gtk_combo_box_text_new();
6876 combo_box_append_text(w, _("Swamy-Arora"));
6877 combo_box_append_text(w, _("Swamy-Arora / Baltagi-Chang"));
6878 combo_box_append_text(w, _("Nerlove"));
6879 gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 0);
6880 gtk_combo_box_set_active(GTK_COMBO_BOX(w), 0);
6881 gtk_widget_set_sensitive(w, !fe);
6882 g_signal_connect(G_OBJECT(w), "changed",
6883 G_CALLBACK(select_re_method), sr);
6884 sensitize_conditional_on(w, b2);
6885 }
6886
build_dpanel_radios(selector * sr)6887 static void build_dpanel_radios (selector *sr)
6888 {
6889 GtkWidget *b1, *b2;
6890 GSList *group;
6891 gboolean twostep = FALSE;
6892
6893 if (dpd_2step || (model_opt & OPT_T)) {
6894 twostep = TRUE;
6895 }
6896
6897 b1 = gtk_radio_button_new_with_label(NULL, _("One-step estimation"));
6898 pack_switch(b1, sr, !twostep, FALSE, OPT_NONE, 0);
6899
6900 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(b1));
6901 b2 = gtk_radio_button_new_with_label(group, _("Two-step estimation"));
6902 pack_switch(b2, sr, twostep, FALSE, OPT_T, 0);
6903 }
6904
build_heckit_radios(selector * sr)6905 static void build_heckit_radios (selector *sr)
6906 {
6907 GtkWidget *b1, *b2;
6908 GSList *group;
6909 gboolean ml = TRUE;
6910
6911 if (model_opt & OPT_T) {
6912 ml = FALSE;
6913 }
6914
6915 b1 = gtk_radio_button_new_with_label(NULL, _("Maximum likelihood estimation"));
6916 pack_switch(b1, sr, ml, FALSE, OPT_NONE, 0);
6917
6918 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(b1));
6919 b2 = gtk_radio_button_new_with_label(group, _("2-step estimation"));
6920 pack_switch(b2, sr, !ml, FALSE, OPT_T, 0);
6921 }
6922
build_xtab_radios(selector * sr)6923 static void build_xtab_radios (selector *sr)
6924 {
6925 GtkWidget *b1, *b2, *b3;
6926 GSList *group;
6927
6928 b1 = gtk_radio_button_new_with_label(NULL, _("Plain numerical values"));
6929 pack_switch(b1, sr, TRUE, FALSE, OPT_NONE, 0);
6930
6931 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(b1));
6932 b2 = gtk_radio_button_new_with_label(group, _("Show row percentages"));
6933 pack_switch(b2, sr, FALSE, FALSE, OPT_R, 0);
6934
6935 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(b2));
6936 b3 = gtk_radio_button_new_with_label(group, _("Show column percentages"));
6937 pack_switch(b3, sr, FALSE, FALSE, OPT_C, 0);
6938 }
6939
build_ar1_radios(selector * sr)6940 static void build_ar1_radios (selector *sr)
6941 {
6942 GtkWidget *b1, *b2, *b3, *b4, *hbox;
6943 GSList *group;
6944
6945 b1 = gtk_radio_button_new_with_label(NULL, _("Cochrane-Orcutt"));
6946 pack_switch(b1, sr, TRUE, FALSE, OPT_NONE, 0);
6947
6948 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(b1));
6949 b2 = gtk_radio_button_new_with_label(group, _("Prais-Winsten"));
6950 pack_switch(b2, sr, FALSE, FALSE, OPT_P, 0);
6951
6952 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(b2));
6953 b3 = gtk_radio_button_new_with_label(group, _("Hildreth-Lu"));
6954 hbox = pack_switch(b3, sr, FALSE, FALSE, OPT_H, 0);
6955
6956 b4 = gtk_check_button_new_with_label(_("Fine-tune using Cochrane-Orcutt"));
6957 pack_switch_in(hbox, b4, sr, TRUE, TRUE, OPT_B, 0);
6958 gtk_widget_set_sensitive(b4, FALSE);
6959 sensitize_conditional_on(b4, b3);
6960
6961 if (model_opt & OPT_P) {
6962 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b2), TRUE);
6963 } else if (model_opt & OPT_H) {
6964 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b3), TRUE);
6965 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b4),
6966 !(model_opt & OPT_B));
6967 } else {
6968 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b1), TRUE);
6969 }
6970 }
6971
arma_estimator_switch(GtkComboBox * box,selector * sr)6972 static gboolean arma_estimator_switch (GtkComboBox *box, selector *sr)
6973 {
6974 if (sr->hess_button != NULL) {
6975 GtkWidget *xb = sr->x12a_button;
6976
6977 if (xb == NULL || !button_is_active(xb)) {
6978 gchar *s = combo_box_get_active_text(box);
6979
6980 gtk_widget_set_sensitive(sr->hess_button,
6981 !strcmp(s, _("Exact Maximum Likelihood")));
6982 g_free(s);
6983 }
6984 }
6985
6986 return FALSE;
6987 }
6988
build_arma_combo(selector * sr)6989 static void build_arma_combo (selector *sr)
6990 {
6991 GtkWidget *hbox, *combo, *button;
6992 static const char *opt_strs[] = {
6993 N_("Exact Maximum Likelihood"),
6994 N_("Conditional Maximum Likelihood"),
6995 NULL
6996 };
6997 static gretlopt opts[] = {
6998 OPT_NONE,
6999 OPT_C,
7000 };
7001 static combo_opts arma_opts;
7002 int deflt = 0;
7003
7004 arma_opts.strs = opt_strs;
7005 arma_opts.vals = opts;
7006 arma_opts.optp = &sr->opts;
7007
7008 if (model_opt & OPT_C) {
7009 deflt = 1;
7010 }
7011
7012 combo = gretl_opts_combo_full(&arma_opts, deflt, NULL,
7013 G_CALLBACK(arma_estimator_switch),
7014 sr);
7015 g_object_set_data(G_OBJECT(combo), "selector", sr);
7016
7017 hbox = gtk_hbox_new(FALSE, 5);
7018 gtk_box_pack_start(GTK_BOX(hbox), combo, FALSE, FALSE, 0);
7019
7020 button = gtk_button_new_from_stock(GTK_STOCK_PREFERENCES);
7021 g_signal_connect(G_OBJECT(button), "clicked",
7022 G_CALLBACK(call_iters_dialog), combo);
7023 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5);
7024
7025 gtk_box_pack_start(GTK_BOX(sr->vbox), hbox, FALSE, FALSE, 5);
7026 }
7027
build_coint_combo(selector * sr)7028 static void build_coint_combo (selector *sr)
7029 {
7030 GtkWidget *hbox, *combo;
7031 static const char *opt_strs[] = {
7032 N_("test without constant"),
7033 N_("test with constant"),
7034 N_("with constant and trend"),
7035 N_("with constant and quadratic trend"),
7036 NULL
7037 };
7038 static gretlopt opts[] = {
7039 OPT_N,
7040 OPT_NONE,
7041 OPT_T,
7042 OPT_R,
7043 };
7044 static combo_opts coint_opts;
7045 int deflt = 1;
7046
7047 coint_opts.strs = opt_strs;
7048 coint_opts.vals = opts;
7049 coint_opts.optp = &sr->opts;
7050
7051 combo = gretl_opts_combo(&coint_opts, deflt);
7052
7053 hbox = gtk_hbox_new(FALSE, 5);
7054 gtk_box_pack_start(GTK_BOX(hbox), combo, FALSE, FALSE, 0);
7055 gtk_box_pack_start(GTK_BOX(sr->vbox), hbox, FALSE, FALSE, 5);
7056 }
7057
build_vecm_combo(selector * sr)7058 static void build_vecm_combo (selector *sr)
7059 {
7060 GtkWidget *hbox, *combo;
7061 static const char *opt_strs[] = {
7062 N_("No constant"),
7063 N_("Restricted constant"),
7064 N_("Unrestricted constant"),
7065 N_("Restricted trend"),
7066 N_("Unrestricted trend"),
7067 NULL
7068 };
7069 static gretlopt opts[] = {
7070 OPT_N,
7071 OPT_R,
7072 OPT_NONE,
7073 OPT_A,
7074 OPT_T
7075 };
7076 static combo_opts vecm_opts;
7077
7078 vecm_opts.strs = opt_strs;
7079 vecm_opts.vals = opts;
7080 vecm_opts.optp = &sr->opts;
7081
7082 combo = gretl_opts_combo(&vecm_opts, jcase);
7083
7084 hbox = gtk_hbox_new(FALSE, 5);
7085 gtk_box_pack_start(GTK_BOX(hbox), combo, FALSE, FALSE, 0);
7086
7087 gtk_box_pack_start(GTK_BOX(sr->vbox), hbox, FALSE, FALSE, 5);
7088 }
7089
7090 #define DSET_DB_OK(d) (d->pd == 1 || (d->structure == TIME_SERIES && \
7091 (d->pd == 4 || d->pd == 12)))
7092
build_data_export_combo(selector * sr)7093 static void build_data_export_combo (selector *sr)
7094 {
7095 GtkWidget *hbox, *label, *combo;
7096 static const char *opt_strs[] = {
7097 N_("CSV"),
7098 N_("GeoJSON"),
7099 N_("gretl datafile (.gdt)"),
7100 N_("gretl binary datafile (.gdtb)"),
7101 N_("gretl database (.bin)"),
7102 N_("space separated (R-friendly)"),
7103 N_("Octave"),
7104 N_("Stata"),
7105 N_("JMulTi"),
7106 N_("PcGive"),
7107 NULL
7108 };
7109 static gretlopt opts[] = {
7110 OPT_C,
7111 OPT_P,
7112 OPT_Z,
7113 OPT_B,
7114 OPT_D,
7115 OPT_R,
7116 OPT_M,
7117 OPT_S,
7118 OPT_J,
7119 OPT_G
7120 };
7121 static combo_opts export_opts;
7122 int deflt = 0;
7123
7124 export_opts.strs = opt_strs;
7125 export_opts.vals = opts;
7126 export_opts.optp = &sr->opts;
7127
7128 hbox = gtk_hbox_new(FALSE, 5);
7129
7130 label = gtk_label_new(_("Select format"));
7131 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
7132
7133 if (dataset->mapfile != NULL) {
7134 int masked[4] = {3, 4, 8, 9};
7135
7136 deflt = 1;
7137 combo = gretl_opts_combo_masked(&export_opts, deflt, masked);
7138 } else if (DSET_DB_OK(dataset)) {
7139 int masked[2] = {1, 1};
7140
7141 combo = gretl_opts_combo_masked(&export_opts, deflt, masked);
7142 } else {
7143 int masked[3] = {2, 1, 4};
7144
7145 combo = gretl_opts_combo_masked(&export_opts, deflt, masked);
7146 }
7147
7148 gtk_box_pack_start(GTK_BOX(hbox), combo, FALSE, FALSE, 0);
7149 gtk_box_pack_start(GTK_BOX(sr->vbox), hbox, FALSE, FALSE, 5);
7150 }
7151
build_selector_radios(selector * sr)7152 static void build_selector_radios (selector *sr)
7153 {
7154 if (sr->ci == PANEL) {
7155 build_panel_radios(sr);
7156 } else if (sr->ci == DPANEL) {
7157 build_dpanel_radios(sr);
7158 } else if (sr->ci == SCATTERS) {
7159 build_scatters_radios(sr);
7160 } else if (sr->ci == ADD) {
7161 build_add_test_radios(sr);
7162 } else if (sr->ci == OMIT || sr->ci == VAROMIT) {
7163 build_omit_test_radios(sr);
7164 } else if (sr->ci == LOGIT || sr->ci == PROBIT) {
7165 build_pvalues_radios(sr);
7166 } else if (sr->ci == HECKIT) {
7167 build_heckit_radios(sr);
7168 } else if (sr->ci == XTAB) {
7169 build_xtab_radios(sr);
7170 } else if (sr->ci == PCA) {
7171 build_pca_radios(sr);
7172 } else if (sr->ci == QUANTREG) {
7173 build_quantreg_radios(sr);
7174 } else if (sr->ci == LOGISTIC || sr->ci == FE_LOGISTIC) {
7175 build_logistic_radios(sr);
7176 } else if (sr->ci == AR1) {
7177 build_ar1_radios(sr);
7178 } else if (sr->ci == REGLS) {
7179 build_regls_controls(sr);
7180 }
7181 }
7182
build_selector_combo(selector * sr)7183 static void build_selector_combo (selector *sr)
7184 {
7185 if (sr->ci == ARMA) {
7186 build_arma_combo(sr);
7187 } else if (sr->ci == COINT) {
7188 build_coint_combo(sr);
7189 } else if (sr->ci == VECM || sr->ci == COINT2) {
7190 build_vecm_combo(sr);
7191 } else if (sr->ci == IV_GMM) {
7192 build_gmm_popdown(sr);
7193 } else if (sr->ci == COUNTMOD) {
7194 build_count_data_popdown(sr);
7195 } else if (sr->ci == DURATION) {
7196 build_duration_popdown(sr);
7197 } else if (sr->ci == EXPORT) {
7198 build_data_export_combo(sr);
7199 }
7200 }
7201
lag_selector_button(selector * sr)7202 static void lag_selector_button (selector *sr)
7203 {
7204 GtkWidget *hbox = gtk_hbox_new(FALSE, 5);
7205
7206 sr->lags_button = gtk_button_new_with_label(_("lags..."));
7207
7208 g_signal_connect(G_OBJECT(sr->lags_button), "clicked",
7209 G_CALLBACK(lags_dialog_driver), sr);
7210 if (varlist_row_count(sr, SR_RVARS1, NULL) < 2) {
7211 gtk_widget_set_sensitive(sr->lags_button, FALSE);
7212 }
7213
7214 gtk_box_pack_start(GTK_BOX(hbox), sr->lags_button, FALSE, FALSE, 0);
7215 gtk_box_pack_start(GTK_BOX(sr->vbox), hbox, FALSE, FALSE, 0);
7216 }
7217
selector_doit(GtkWidget * w,selector * sr)7218 static void selector_doit (GtkWidget *w, selector *sr)
7219 {
7220 if (!FNPKG_CODE(sr->ci)) {
7221 /* we don't need this when gathering function names */
7222 compose_cmdlist(sr);
7223 }
7224
7225 if (sr->error == 0) {
7226 int err = 0;
7227
7228 #ifdef OS_OSX
7229 /* Hiding the selector window prevents the "next" window
7230 (i.e. the one opened by sr->callback) from being hidden
7231 behind gretl's main window, on Apple's X11
7232 */
7233 if (open_selector != NULL) {
7234 gtk_widget_hide(sr->dlg);
7235 }
7236 #endif
7237
7238 err = sr->callback(sr);
7239
7240 if (!err && open_selector != NULL) {
7241 gtk_widget_destroy(sr->dlg);
7242 }
7243
7244 #ifdef OS_OSX
7245 if (err && open_selector != NULL) {
7246 gtk_widget_show(sr->dlg);
7247 }
7248 #endif
7249 }
7250 }
7251
build_selector_buttons(selector * sr)7252 static void build_selector_buttons (selector *sr)
7253 {
7254 GtkWidget *tmp;
7255
7256 if (sr->ci != PRINT && sr->ci != SUMMARY && !FNPKG_CODE(sr->ci) &&
7257 sr->ci != DEFINE_LIST && sr->ci != DEFINE_MATRIX &&
7258 sr->ci != ELLIPSE && sr->ci != CHOW &&
7259 !SAVE_DATA_ACTION(sr->ci)) {
7260 /* add a Help button if appropriate */
7261 int ci = sr->ci;
7262
7263 if (sr->ci == OLOGIT || sr->ci == MLOGIT) {
7264 ci = LOGIT;
7265 } else if (sr->ci == OPROBIT) {
7266 ci = PROBIT;
7267 } else if (sr->ci == FE_LOGISTIC) {
7268 ci = LOGISTIC;
7269 } else if (IV_MODEL(sr->ci)) {
7270 ci = IVREG;
7271 }
7272
7273 context_help_button(sr->action_area, ci);
7274 }
7275
7276 if (sr->ci != EDIT_FUNCTIONS) {
7277 tmp = gtk_button_new_from_stock(GTK_STOCK_CLEAR);
7278 gtk_widget_set_can_default(tmp, TRUE);
7279 gtk_container_add(GTK_CONTAINER(sr->action_area), tmp);
7280 g_signal_connect(G_OBJECT(tmp), "clicked",
7281 G_CALLBACK(clear_vars), sr);
7282 }
7283
7284 tmp = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
7285 gtk_widget_set_can_default(tmp, TRUE);
7286 gtk_container_add(GTK_CONTAINER(sr->action_area), tmp);
7287 g_signal_connect(G_OBJECT(tmp), "clicked",
7288 G_CALLBACK(cancel_selector), sr);
7289
7290 tmp = gtk_button_new_from_stock(GTK_STOCK_OK);
7291 gtk_widget_set_can_default(tmp, TRUE);
7292 gtk_container_add(GTK_CONTAINER(sr->action_area), tmp);
7293 g_signal_connect(G_OBJECT(tmp), "clicked",
7294 G_CALLBACK(selector_doit), sr);
7295 gtk_widget_grab_default(tmp);
7296 }
7297
list_show_var(int v,int ci,int show_lags)7298 static int list_show_var (int v, int ci, int show_lags)
7299 {
7300 int ret = 1;
7301
7302 if (ci == LOESS || ci == NADARWAT) {
7303 /* special: for nonparam models we should show
7304 lagged vars, since we don't display the full
7305 lag-selection mechanism */
7306 show_lags = 1;
7307 }
7308
7309 lags_hidden = 0;
7310
7311 if (v == 0 && (ci == DEFINE_LIST || ci == DEFINE_MATRIX)) {
7312 ;
7313 } else if (v == 0 && (!MODEL_CODE(ci) || ci == ARMA || ci == GARCH)) {
7314 ret = 0;
7315 } else if (v == 0 && (ci == LOESS || ci == NADARWAT)) {
7316 ret = 0;
7317 } else if (series_is_hidden(dataset, v)) {
7318 ret = 0;
7319 } else if (is_panel_group_names_series(dataset, v)) {
7320 ret = 0;
7321 } else if (!show_lags && series_get_lag(dataset, v)) {
7322 lags_hidden = 1;
7323 ret = 0;
7324 } else if (ci == XTAB) {
7325 ret = accept_as_discrete(dataset, v, 0);
7326 } else if (ci == MIDASREG && series_get_midas_period(dataset, v)) {
7327 ret = 0;
7328 }
7329
7330 return ret;
7331 }
7332
7333 /* callback from successful generation of a new variable or
7334 variables via click on the selector's "Add variable button"
7335 */
7336
selector_register_genr(int newvars,gpointer p)7337 void selector_register_genr (int newvars, gpointer p)
7338 {
7339 selector *sr = p;
7340 GtkListStore *store;
7341 GtkTreeIter iter;
7342 int i, v;
7343
7344 store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(sr->lvars)));
7345 tree_model_get_iter_last(GTK_TREE_MODEL(store), &iter);
7346
7347 for (i=0; i<newvars; i++) {
7348 v = dataset->v - newvars + i;
7349 if (list_show_var(v, sr->ci, 0)) {
7350 list_append_var_simple(store, &iter, v);
7351 }
7352 }
7353 }
7354
new_var_callback(GtkWidget * w,selector * sr)7355 static void new_var_callback (GtkWidget *w, selector *sr)
7356 {
7357 edit_dialog(GENR, _("gretl: add var"),
7358 _("Enter formula for new variable"),
7359 NULL, do_selector_genr, sr,
7360 VARCLICK_INSERT_NAME, sr->dlg);
7361 }
7362
add_var_button(selector * sr)7363 static GtkWidget *add_var_button (selector *sr)
7364 {
7365 GtkWidget *img = gtk_image_new_from_stock(GTK_STOCK_ADD,
7366 GTK_ICON_SIZE_MENU);
7367 GtkWidget *button = gtk_button_new();
7368
7369 gtk_container_add(GTK_CONTAINER(button), img);
7370 gretl_tooltips_add(GTK_WIDGET(button), _("New variable"));
7371 g_signal_connect(button, "clicked", G_CALLBACK(new_var_callback), sr);
7372
7373 return button;
7374 }
7375
selection_dialog_add_top_label(selector * sr)7376 static void selection_dialog_add_top_label (selector *sr)
7377 {
7378 GtkWidget *label;
7379 gchar *s = NULL;
7380 int ci = sr->ci;
7381
7382 if (MODEL_CODE(ci) || VEC_CODE(ci) || NONPARAM_CODE(ci)) {
7383 GtkWidget *hbox, *button;
7384
7385 hbox = gtk_hbox_new(FALSE, 0);
7386 button = add_var_button(sr);
7387 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
7388 s = estimator_label(ci);
7389 if (s != NULL) {
7390 label = gtk_label_new(_(s));
7391 gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, FALSE, 0);
7392 label = gtk_label_new("");
7393 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 16);
7394 }
7395 gtk_box_pack_start(GTK_BOX(sr->vbox), hbox, FALSE, FALSE, 0);
7396 } else if (ci == SAVE_FUNCTIONS) {
7397 GtkWidget *hbox, *entry;
7398
7399 hbox = gtk_hbox_new(FALSE, 5);
7400 label = gtk_label_new(_("Name for package:"));
7401 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
7402 entry = gtk_entry_new();
7403 gtk_entry_set_max_length(GTK_ENTRY(entry), 31);
7404 gtk_entry_set_width_chars(GTK_ENTRY(entry), 24);
7405 gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, FALSE, 0);
7406 gtk_box_pack_start(GTK_BOX(sr->vbox), hbox, FALSE, FALSE, 5);
7407 gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
7408 sr->extra[0] = entry;
7409 } else {
7410 if (ci == GR_XY)
7411 s = N_("XY scatterplot");
7412 else if (ci == GR_IMP)
7413 s = N_("plot with impulses");
7414 else if (ci == GR_3D)
7415 s = N_("3D plot");
7416 else if (ci == SCATTERS)
7417 s = N_("multiple scatterplots");
7418 else if (ci == GR_DUMMY)
7419 s = N_("factorized plot");
7420 else if (ci == GR_FBOX)
7421 s = N_("factorized boxplot");
7422 else if (ci == GR_XYZ)
7423 s = N_("scatterplot with control");
7424 else if (ci == ANOVA)
7425 s = N_("ANOVA");
7426
7427 if (s != NULL) {
7428 label = gtk_label_new(_(s));
7429 gtk_box_pack_start(GTK_BOX(sr->vbox), label, FALSE, FALSE, 5);
7430 }
7431 }
7432 }
7433
has_0(const int * list)7434 static int has_0 (const int *list)
7435 {
7436 int i;
7437
7438 for (i=1; i<=list[0]; i++) {
7439 if (list[i] == 0) {
7440 return 1;
7441 }
7442 }
7443
7444 return 0;
7445 }
7446
primary_rhs_varlist(selector * sr)7447 static void primary_rhs_varlist (selector *sr)
7448 {
7449 GtkTreeModel *mod;
7450 GtkListStore *store;
7451 GtkTreeIter iter;
7452 GtkWidget *hbox;
7453 GtkWidget *tmp = NULL;
7454 GtkWidget **lptr = NULL;
7455 int i;
7456
7457 if (COINT_CODE(sr->ci)) {
7458 tmp = gtk_label_new(_("Variables to test"));
7459 } else if (VEC_CODE(sr->ci)) {
7460 tmp = gtk_label_new(_("Endogenous variables"));
7461 } else if (sr->ci == BIPROBIT) {
7462 tmp = gtk_label_new(_("Equation 1 regressors"));
7463 } else if (MODEL_CODE(sr->ci)) {
7464 tmp = gtk_label_new(_("Regressors"));
7465 } else if (sr->ci == GR_XY || sr->ci == GR_IMP) {
7466 tmp = gtk_label_new(_("Y-axis variables"));
7467 } else if (sr->ci == SCATTERS) {
7468 multiplot_label = tmp = gtk_label_new(_("X-axis variables"));
7469 } else if (FNPKG_CODE(sr->ci)) {
7470 tmp = gtk_label_new(_("Public functions"));
7471 }
7472
7473 if (tmp != NULL) {
7474 table_add_right(sr, tmp, 1);
7475 }
7476
7477 hbox = gtk_hbox_new(FALSE, 5);
7478
7479 /* add the actual primary RHS listbox */
7480 sr->rvars1 = var_list_box_new(GTK_BOX(hbox), sr, SR_RVARS1);
7481 mod = gtk_tree_view_get_model(GTK_TREE_VIEW(sr->rvars1));
7482
7483 if (sr->ci == ARMA) {
7484 lptr = &sr->lags_button;
7485 } else if (sr->ci == VAR) { /* FIXME VECM? */
7486 lptr = &sr->extra[EXTRA_LAGS];
7487 }
7488
7489 /* add push/pull buttons */
7490 push_pull_buttons(sr, add_to_rvars1_callback,
7491 remove_from_rvars1_callback,
7492 lptr, OPT_NONE);
7493
7494 store = GTK_LIST_STORE(mod);
7495 gtk_list_store_clear(store);
7496 gtk_tree_model_get_iter_first(mod, &iter);
7497
7498 if (MODEL_CODE(sr->ci)) {
7499 if (sr->ci == ARMA || sr->ci == GARCH || NONPARAM_CODE(sr->ci)) {
7500 ; /* skip */
7501 } else if (xlist == NULL || has_0(xlist)) {
7502 /* stick the constant in by default */
7503 list_append_var(mod, &iter, 0, sr, SR_RVARS1);
7504 }
7505 if (xlist != NULL) {
7506 /* we have a saved list of regressors */
7507 int nx = 0;
7508
7509 for (i=1; i<=xlist[0]; i++) {
7510 if (xlist[i] != 0) {
7511 list_append_var(mod, &iter, xlist[i], sr, SR_RVARS1);
7512 nx++;
7513 }
7514 }
7515 if (nx > 0 && sr->lags_button != NULL && sr->ci == ARMA) {
7516 gtk_widget_set_sensitive(sr->lags_button, TRUE);
7517 }
7518 }
7519 } else if (VEC_CODE(sr->ci) && veclist != NULL && veclist[0] > 0) {
7520 for (i=1; i<=veclist[0]; i++) {
7521 list_append_var(mod, &iter, veclist[i], sr, SR_RVARS1);
7522 }
7523 if (sr->extra[EXTRA_LAGS] != NULL) {
7524 gtk_widget_set_sensitive(sr->extra[EXTRA_LAGS], TRUE);
7525 }
7526 }
7527
7528 table_add_right(sr, hbox, 0);
7529 }
7530
7531 /* On opening the selector dialog, select (if possible) the
7532 first relevant item in the listbox on the left.
7533 */
7534
selector_set_focus(selector * sr)7535 static void selector_set_focus (selector *sr)
7536 {
7537 if (sr->lvars != NULL) {
7538 GtkTreeModel *mod = gtk_tree_view_get_model(GTK_TREE_VIEW(sr->lvars));
7539 GtkTreeSelection *sel;
7540 GtkTreeIter iter;
7541 gboolean do_sel;
7542 int v;
7543
7544 gtk_widget_grab_focus(sr->lvars);
7545 do_sel = gtk_tree_model_get_iter_first(mod, &iter);
7546 if (do_sel) {
7547 if (!FNPKG_CODE(sr->ci) && list_show_var(0, sr->ci, 0)) {
7548 /* don't select the constant: skip a row */
7549 do_sel = gtk_tree_model_iter_next(mod, &iter);
7550 }
7551 while (do_sel && MODEL_CODE(sr->ci)) {
7552 /* skip named lists? */
7553 gtk_tree_model_get(mod, &iter, COL_ID, &v, -1);
7554 if (v > 0) {
7555 break;
7556 }
7557 do_sel = gtk_tree_model_iter_next(mod, &iter);
7558 }
7559 }
7560 if (do_sel) {
7561 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(sr->lvars));
7562 gtk_tree_selection_select_iter(sel, &iter);
7563 }
7564 }
7565 }
7566
list_append_named_lists(GtkListStore * store,GtkTreeIter * iterp)7567 static void list_append_named_lists (GtkListStore *store,
7568 GtkTreeIter *iterp)
7569 {
7570 GList *llist = user_var_names_for_type(GRETL_TYPE_LIST);
7571 GList *tail = llist;
7572 const int *list;
7573
7574 while (tail != NULL) {
7575 list = get_list_by_name(tail->data);
7576 if (list != NULL && list[0] > 0 &&
7577 series_get_midas_period(dataset, list[1]) == 0) {
7578 gtk_list_store_append(store, iterp);
7579 gtk_list_store_set(store, iterp, COL_ID, -1, COL_LAG, 0,
7580 COL_NAME, tail->data, -1);
7581 }
7582 tail = tail->next;
7583 }
7584
7585 g_list_free(llist);
7586 }
7587
midas_special_left_panel(selector * sr,GtkWidget * left_box,int saverow)7588 static int midas_special_left_panel (selector *sr,
7589 GtkWidget *left_box,
7590 int saverow)
7591 {
7592 GtkListStore *store;
7593 GtkTreeIter iter;
7594 GtkWidget *l2box, *lbl;
7595 int i, m, nmidas = 0;
7596 int err = 0;
7597
7598 lbl = gtk_label_new("MIDAS vars");
7599 l2box = gtk_hbox_new(FALSE, 0);
7600 sr->lvars2 = var_list_box_new(GTK_BOX(l2box), sr, SR_LVARS2);
7601 store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(sr->lvars2)));
7602 gtk_list_store_clear(store);
7603 gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter);
7604 alt_table_add_left(sr, left_box, 0, saverow);
7605 alt_table_add_left(sr, lbl, saverow, saverow + 1);
7606 alt_table_add_left(sr, l2box, saverow + 1, sr->n_rows);
7607
7608 for (i=1; i<dataset->v; i++) {
7609 m = series_is_midas_anchor(dataset, i);
7610 if (m > 0 && i + m <= dataset->v) {
7611 int is_midas = 1;
7612 int j, p, p0 = m;
7613
7614 for (j=i+1; j<i+m; j++) {
7615 p = series_get_midas_period(dataset, j);
7616 if (p != p0 - 1) {
7617 is_midas = 0;
7618 break;
7619 } else {
7620 p0 = p;
7621 }
7622 }
7623 if (is_midas) {
7624 nmidas++;
7625 list_append_midas_var(store, &iter, i, m);
7626 }
7627 }
7628 }
7629
7630 if (nmidas == 0) {
7631 /* "can't happen" */
7632 err = 1;
7633 }
7634
7635 return err;
7636 }
7637
selection_dialog(int ci,const char * title,void * data,int (* callback)())7638 selector *selection_dialog (int ci, const char *title,
7639 void *data, int (*callback)())
7640 {
7641 GtkListStore *store;
7642 GtkTreeIter iter;
7643 GtkWidget *left_box;
7644 selector *sr;
7645 int preselect;
7646 int saverow;
7647 int i, yvar = 0;
7648
7649 preselect = presel;
7650 presel = 0;
7651
7652 if (open_selector != NULL) {
7653 gtk_window_present(GTK_WINDOW(open_selector->dlg));
7654 return open_selector;
7655 }
7656
7657 sr = mymalloc(sizeof *sr);
7658
7659 if (sr == NULL) {
7660 return NULL;
7661 }
7662
7663 selector_init(sr, ci, title, callback, NULL, data, SELECTOR_FULL);
7664 selection_dialog_add_top_label(sr);
7665
7666 /* the following encloses LHS lvars, depvar and indepvar stuff */
7667 sr->table = gtk_table_new(sr->n_rows, 3, FALSE);
7668
7669 /* LHS: list of elements to choose from */
7670 left_box = gtk_hbox_new(FALSE, 0);
7671 sr->lvars = var_list_box_new(GTK_BOX(left_box), sr, SR_LVARS);
7672 store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(sr->lvars)));
7673 gtk_list_store_clear(store);
7674 gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter);
7675
7676 if (FNPKG_CODE(ci)) {
7677 available_functions_list(sr);
7678 } else {
7679 for (i=0; i<dataset->v; i++) {
7680 if (i == 1 && (MODEL_CODE(ci) || VEC_CODE(ci))) {
7681 list_append_named_lists(store, &iter);
7682 }
7683 if (list_show_var(i, ci, 0)) {
7684 list_append_var_simple(store, &iter, i);
7685 }
7686 }
7687 }
7688
7689 if (MODEL_CODE(ci) || NONPARAM_CODE(ci) || ci == ANOVA) {
7690 /* models: top right -> dependent variable */
7691 yvar = build_depvar_section(sr, preselect);
7692 } else if (ci == GR_XY || ci == GR_IMP || ci == GR_DUMMY ||
7693 ci == SCATTERS || ci == GR_3D || ci == GR_XYZ ||
7694 ci == GR_FBOX) {
7695 /* graphs: top right -> x-axis variable or equivalent */
7696 build_x_axis_section(sr, preselect);
7697 } else if (FNPKG_CODE(ci)) {
7698 primary_rhs_varlist(sr);
7699 }
7700
7701 /* middle right: used for some estimators and factored plot */
7702 if (ci == WLS || ci == AR || ci == ARCH || USE_ZLIST(ci) ||
7703 VEC_CODE(ci) || ci == COUNTMOD || ci == DURATION ||
7704 ci == QUANTREG || ci == INTREG || ci == TOBIT ||
7705 ci == DPANEL || ci == MIDASREG || THREE_VARS_CODE(ci) ||
7706 NONPARAM_CODE(ci)) {
7707 build_mid_section(sr);
7708 }
7709
7710 saverow = sr->row;
7711
7712 if (ci == GR_FBOX || THREE_VARS_CODE(ci)) {
7713 /* choose extra var for plot */
7714 extra_plotvar_box(sr);
7715 } else if (AUX_LAST(ci)) {
7716 secondary_rhs_varlist(sr);
7717 } else if (!NONPARAM_CODE(ci)) {
7718 /* all other uses: list of vars */
7719 primary_rhs_varlist(sr);
7720 }
7721
7722 if (ci == MIDASREG) {
7723 /* we need two left-hand list boxes, the second to
7724 hold high-frequency vars */
7725 midas_special_left_panel(sr, left_box, saverow);
7726 } else {
7727 /* add left-hand column now we know how many rows it should span */
7728 table_add_left(sr, left_box, 0, sr->n_rows);
7729 }
7730
7731 /* pack the whole central section into the dialog's vbox */
7732 gtk_box_pack_start(GTK_BOX(sr->vbox), sr->table, TRUE, TRUE, 0);
7733
7734 if (ci == ARMA) {
7735 /* AR, D, MA for ARIMA */
7736 build_arma_spinners(sr);
7737 } else if (ci == GARCH) {
7738 /* P and Q for GARCH */
7739 build_garch_spinners(sr);
7740 }
7741
7742 /* toggle switches for some cases */
7743 if (WANT_TOGGLES(ci)) {
7744 build_selector_switches(sr);
7745 }
7746
7747 #ifdef GNUPLOT3D
7748 if (ci == GR_3D) {
7749 build_selector_switches(sr);
7750 }
7751 #endif
7752
7753 /* radio buttons for some */
7754 if (want_radios(sr)) {
7755 build_selector_radios(sr);
7756 }
7757
7758 /* drop-down selector for some */
7759 if (want_combo(sr)) {
7760 build_selector_combo(sr);
7761 }
7762
7763 /* plus lag selection stuff, if relevant */
7764 if (dataset_lags_ok(dataset)) {
7765 if (ci == GR_XY || ci == GR_IMP || ci == GR_DUMMY || \
7766 ci == SCATTERS || ci == GR_XYZ) {
7767 unhide_lags_switch(sr);
7768 }
7769 if (MODEL_CODE(ci) && ci != ARMA) {
7770 lag_selector_button(sr);
7771 }
7772 if (select_lags_depvar(ci) && yvar > 0) {
7773 maybe_activate_depvar_lags(sr->depvar, sr);
7774 maybe_insert_depvar_lags(sr, yvar, 0);
7775 }
7776 }
7777
7778 /* buttons: Help, Clear, Cancel, OK */
7779 build_selector_buttons(sr);
7780
7781 gtk_widget_show_all(sr->dlg);
7782 selector_set_focus(sr);
7783
7784 return sr;
7785 }
7786
simple_sel_label(int ci)7787 static char *simple_sel_label (int ci)
7788 {
7789 switch (ci) {
7790 case LOGS:
7791 return N_("Select variables for logging");
7792 case LAGS:
7793 return N_("Select variables for lagging");
7794 case SQUARE:
7795 return N_("Select variables to square");
7796 case DIFF:
7797 return N_("Select variables to difference");
7798 case LDIFF:
7799 return N_("Select variables to log-difference");
7800 case ADD:
7801 return N_("Select variables to add");
7802 case OMIT:
7803 case VAROMIT:
7804 return N_("Select variables to omit");
7805 case COEFFSUM:
7806 return N_("Select coefficients to sum");
7807 case QQPLOT:
7808 return N_("Q-Q plot: select one or two variables");
7809 case ELLIPSE:
7810 return N_("Confidence region: select two variables");
7811 case PRINT:
7812 return N_("Select variables to display");
7813 case GR_BOX:
7814 return N_("Select variables for boxplot");
7815 case GR_PLOT:
7816 case TSPLOTS:
7817 return N_("Select variables to plot");
7818 case SAVE_DATA:
7819 case SAVE_DATA_AS:
7820 case EXPORT_CSV:
7821 case EXPORT_R:
7822 case EXPORT_OCTAVE:
7823 case EXPORT_JM:
7824 case EXPORT_DAT:
7825 case EXPORT:
7826 return N_("Select variables to save");
7827 case COPY_CSV:
7828 return N_("Select variables to copy");
7829 case CHOW:
7830 return N_("Select variables to test");
7831 case DEFINE_LIST:
7832 return N_("Define named list");
7833 default:
7834 return NULL;
7835 }
7836 }
7837
add_omit_list(gpointer p,selector * sr)7838 static int add_omit_list (gpointer p, selector *sr)
7839 {
7840 windata_t *vwin = (windata_t *) p;
7841 GRETL_VAR *var = NULL;
7842 MODEL *pmod = NULL;
7843 GtkListStore *store;
7844 GtkTreeIter iter;
7845 int i, nvars = 0;
7846
7847 if (sr->ci == VAROMIT) {
7848 var = (GRETL_VAR *) vwin->data;
7849 } else {
7850 pmod = (MODEL *) vwin->data;
7851 }
7852
7853 store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(sr->lvars)));
7854 gtk_list_store_clear(store);
7855 gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter);
7856
7857 if (sr->ci == ELLIPSE) {
7858 char pname[VNAMELEN];
7859 int nc = gretl_model_get_int(pmod, "base-coeffs"); /* FIXME? */
7860
7861 if (nc == 0) {
7862 nc = pmod->ncoeff;
7863 }
7864
7865 for (i=0; i<nc; i++) {
7866 /* note: special case, not using varnames as such */
7867 gretl_model_get_param_name(pmod, dataset, i, pname);
7868 gtk_list_store_append(store, &iter);
7869 gtk_list_store_set(store, &iter,
7870 COL_ID, i, COL_LAG, 0,
7871 COL_NAME, pname,
7872 -1);
7873 nvars++;
7874 }
7875 g_object_set_data(G_OBJECT(sr->lvars), "keep-names",
7876 GINT_TO_POINTER(1));
7877 } else if (sr->ci == OMIT || sr->ci == ADD || sr->ci == CHOW ||
7878 sr->ci == COEFFSUM) {
7879 int *xlist = gretl_model_get_x_list(pmod);
7880
7881 if (xlist == NULL) {
7882 return 0;
7883 }
7884
7885 if (sr->ci == ADD) {
7886 int dv = gretl_model_get_depvar(pmod);
7887
7888 for (i=0; i<dataset->v; i++) {
7889 if (!in_gretl_list(xlist, i) && i != dv &&
7890 !series_is_hidden(dataset, i)) {
7891 gtk_list_store_append(store, &iter);
7892 gtk_list_store_set(store, &iter,
7893 COL_ID, i, COL_LAG, 0,
7894 COL_NAME, dataset->varname[i],
7895 -1);
7896 nvars++;
7897 }
7898 }
7899 } else {
7900 for (i=1; i<=xlist[0]; i++) {
7901 if (sr->ci == CHOW && xlist[i] == 0) {
7902 continue;
7903 }
7904 gtk_list_store_append(store, &iter);
7905 gtk_list_store_set(store, &iter,
7906 COL_ID, xlist[i], COL_LAG, 0,
7907 COL_NAME, dataset->varname[xlist[i]],
7908 -1);
7909 nvars++;
7910 }
7911 }
7912 free(xlist);
7913 } else if (sr->ci == VAROMIT) {
7914 const int *xlist;
7915
7916 xlist = gretl_VAR_get_exo_list(var);
7917 if (xlist != NULL) {
7918 for (i=1; i<=xlist[0]; i++) {
7919 gtk_list_store_append(store, &iter);
7920 gtk_list_store_set(store, &iter,
7921 COL_ID, xlist[i], COL_LAG, 0,
7922 COL_NAME, dataset->varname[xlist[i]],
7923 -1);
7924 nvars++;
7925 }
7926 }
7927 }
7928
7929 return nvars;
7930 }
7931
available_functions_list(selector * sr)7932 static void available_functions_list (selector *sr)
7933 {
7934 GtkListStore *store;
7935 GtkTreeIter iter;
7936 const char *fnname;
7937 int idx;
7938
7939 store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(sr->lvars)));
7940 gtk_list_store_clear(store);
7941 gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter);
7942
7943 function_names_init();
7944
7945 while ((fnname = next_available_function_name(sr->data, &idx)) != NULL) {
7946 gtk_list_store_append(store, &iter);
7947 gtk_list_store_set(store, &iter,
7948 COL_ID, idx, COL_LAG, 0,
7949 COL_NAME, fnname, -1);
7950 }
7951
7952 g_object_set_data(G_OBJECT(sr->lvars), "keep-names",
7953 GINT_TO_POINTER(1));
7954 }
7955
simple_selection_top_label(int ci,const char * title)7956 static GtkWidget *simple_selection_top_label (int ci, const char *title)
7957 {
7958 const char *s = simple_sel_label(ci);
7959 GtkWidget *label = NULL;
7960 GtkWidget *hbox = NULL;
7961
7962 if (s != NULL && *s != '\0') {
7963 label = gtk_label_new(_(s));
7964 } else if (title != NULL) {
7965 if (!strncmp(title, "gretl: ", 7)) {
7966 title += 7;
7967 }
7968 label = gtk_label_new(title);
7969 }
7970
7971 if (label != NULL) {
7972 hbox = gtk_hbox_new(FALSE, 5);
7973 gtk_container_add(GTK_CONTAINER(hbox), label);
7974 }
7975
7976 return hbox;
7977 }
7978
7979 static void
add_to_rvars1_from_named_list(selector * sr,const int * list,int clear)7980 add_to_rvars1_from_named_list (selector *sr, const int *list,
7981 int clear)
7982 {
7983 GtkTreeModel *mod;
7984 GtkTreeIter iter;
7985 int i, v;
7986
7987 mod = gtk_tree_view_get_model(GTK_TREE_VIEW(sr->rvars1));
7988 if (mod == NULL) {
7989 return;
7990 }
7991
7992 gtk_tree_model_get_iter_first(mod, &iter);
7993
7994 if (clear) {
7995 gtk_list_store_clear(GTK_LIST_STORE(mod));
7996 }
7997
7998 for (i=1; i<=list[0]; i++) {
7999 v = list[i];
8000 gtk_list_store_append(GTK_LIST_STORE(mod), &iter);
8001 gtk_list_store_set(GTK_LIST_STORE(mod), &iter,
8002 COL_ID, v, COL_LAG, 0,
8003 COL_NAME, dataset->varname[v], -1);
8004 }
8005 }
8006
maybe_set_plot_vars(selector * sr)8007 static void maybe_set_plot_vars (selector *sr)
8008 {
8009 int mc = mdata_selection_count();
8010
8011 if (mc > 1 && mc < 7) {
8012 set_vars_from_main(sr);
8013 }
8014 }
8015
8016 /* the following is called on start-up when defining a list */
8017
maybe_set_listdef_vars(selector * sr)8018 static void maybe_set_listdef_vars (selector *sr)
8019 {
8020 const char *lname = selector_entry_text(sr);
8021
8022 if (lname != NULL && *lname != 0) {
8023 int *list = get_list_by_name(lname);
8024
8025 if (list != NULL) {
8026 add_to_rvars1_from_named_list(sr, list, 0);
8027 }
8028 } else if (sr->data == NULL) {
8029 /* called from main window */
8030 int mc = mdata_selection_count();
8031
8032 if (mc > 1) {
8033 set_vars_from_main(sr);
8034 }
8035 }
8036 }
8037
8038 /* callback from change in combo selector, when defining or editing
8039 a list */
8040
listdef_vars_callback(GtkComboBox * b,selector * sr)8041 static void listdef_vars_callback (GtkComboBox *b, selector *sr)
8042 {
8043 const char *lname = selector_entry_text(sr);
8044
8045 if (lname != NULL && *lname != '\0') {
8046 int *list = get_list_by_name(lname);
8047
8048 if (list != NULL) {
8049 add_to_rvars1_from_named_list(sr, list, 1);
8050 }
8051 }
8052 }
8053
set_name_from_fn_param(GtkWidget * w,selector * sr,GtkWidget * entry)8054 static void set_name_from_fn_param (GtkWidget *w, selector *sr,
8055 GtkWidget *entry)
8056 {
8057 gchar *tmp = NULL;
8058
8059 get_fncall_param_info(sr->parent, NULL, &tmp);
8060
8061 if (tmp == NULL) {
8062 int argnum = widget_get_int(w, "argnum");
8063
8064 tmp = g_strdup_printf("arg%d", argnum + 1);
8065 }
8066
8067 gtk_entry_set_text(GTK_ENTRY(entry), tmp);
8068 g_free(tmp);
8069 }
8070
selector_add_list_name_entry(selector * sr)8071 static void selector_add_list_name_entry (selector *sr)
8072 {
8073 const char *lname = NULL;
8074 GtkWidget *src = NULL;
8075 GList *lnames = NULL;
8076 GtkWidget *combo = NULL;
8077 GtkWidget *label;
8078 GtkWidget *entry;
8079
8080 if (sr->data != NULL) {
8081 /* called from function call dialog */
8082 src = GTK_WIDGET(sr->data);
8083 lname = gtk_entry_get_text(GTK_ENTRY(src));
8084 } else {
8085 lnames = user_var_names_for_type(GRETL_TYPE_LIST);
8086 }
8087
8088 label = gtk_label_new(_("Name of list"));
8089 table_add_right(sr, label, 1);
8090
8091 if (lnames != NULL) {
8092 combo = combo_box_text_new_with_entry();
8093 set_combo_box_strings_from_list(combo, lnames);
8094 entry = gtk_bin_get_child(GTK_BIN(combo));
8095 g_signal_connect(G_OBJECT(combo), "changed",
8096 G_CALLBACK(listdef_vars_callback), sr);
8097 } else {
8098 entry = gtk_entry_new();
8099 }
8100
8101 sr->extra[0] = entry;
8102
8103 gtk_entry_set_max_length(GTK_ENTRY(entry), VNAMELEN);
8104 gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
8105
8106 if (src != NULL) {
8107 if (lname != NULL && *lname != '\0' && strcmp(lname, "null")) {
8108 gtk_entry_set_text(GTK_ENTRY(entry), lname);
8109 } else {
8110 set_name_from_fn_param(src, sr, entry);
8111 }
8112 gtk_editable_select_region(GTK_EDITABLE(entry), 0, -1);
8113 }
8114
8115 if (combo != NULL) {
8116 table_add_right(sr, combo, 1);
8117 } else {
8118 table_add_right(sr, entry, 1);
8119 }
8120
8121 table_add_vwedge(sr);
8122 }
8123
8124 #if 0 /* not ready */
8125 static int ols_omit_select (windata_t *vwin)
8126 {
8127 if (vwin->role == VIEW_MODEL) {
8128 MODEL *pmod = vwin->data;
8129
8130 return bootstrap_ok(pmod->ci);
8131 } else {
8132 return 0;
8133 }
8134 }
8135 #endif
8136
maybe_prefill_RHS(selector * sr)8137 static void maybe_prefill_RHS (selector *sr)
8138 {
8139 int *list = main_window_selection_as_list();
8140
8141 if (list != NULL && list[0] >= 2) {
8142 GtkListStore *store;
8143 GtkTreeIter iter;
8144 int i;
8145
8146 store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(sr->rvars1)));
8147 gtk_list_store_clear(store);
8148 gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter);
8149
8150 for (i=1; i<=list[0]; i++) {
8151 list_append_var_simple(store, &iter, list[i]);
8152 }
8153
8154 if (sr->ci == CORR) {
8155 set_n_rvars1(sr, list[0]);
8156 }
8157 }
8158
8159 free(list);
8160 }
8161
8162 selector *
simple_selection_with_data(int ci,const char * title,int (* callback)(),GtkWidget * parent,gpointer data)8163 simple_selection_with_data (int ci, const char *title, int (*callback)(),
8164 GtkWidget *parent, gpointer data)
8165 {
8166 GtkListStore *store;
8167 GtkTreeIter iter;
8168 GtkWidget *left_box, *right_box;
8169 GtkWidget *tmp;
8170 selector *sr;
8171 int nleft = 0;
8172 int i, err = 0;
8173
8174 if (open_selector != NULL) {
8175 gtk_window_present(GTK_WINDOW(open_selector->dlg));
8176 return open_selector;
8177 }
8178
8179 sr = mymalloc(sizeof *sr);
8180 if (sr == NULL) {
8181 return NULL;
8182 }
8183
8184 selector_init(sr, ci, title, callback, parent, data, SELECTOR_SIMPLE);
8185
8186 tmp = simple_selection_top_label(ci, title);
8187 if (tmp != NULL) {
8188 gtk_box_pack_start(GTK_BOX(sr->vbox), tmp, FALSE, FALSE, 0);
8189 }
8190
8191 /* tables to hold vboxes and buttons */
8192 sr->table = gtk_table_new(1, 3, FALSE);
8193
8194 /* holds list of elements available for selection */
8195 left_box = gtk_vbox_new(FALSE, 5);
8196
8197 sr->lvars = var_list_box_new(GTK_BOX(left_box), sr, SR_LVARS);
8198 store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(sr->lvars)));
8199 gtk_list_store_clear(store);
8200 gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter);
8201
8202 if (ci == OMIT || ci == ADD || ci == COEFFSUM ||
8203 ci == ELLIPSE || ci == VAROMIT || ci == CHOW) {
8204 nleft = add_omit_list(data, sr);
8205 } else {
8206 int start = (ci == DEFINE_LIST || ci == DEFINE_MATRIX)? 0 : 1;
8207
8208 for (i=start; i<dataset->v; i++) {
8209 if (i == 1 && SHOW_LISTS_CODE(ci)) {
8210 list_append_named_lists(store, &iter);
8211 }
8212 if (list_show_var(i, ci, 0)) {
8213 list_append_var_simple(store, &iter, i);
8214 nleft++;
8215 }
8216 }
8217 }
8218
8219 sr->n_left = nleft;
8220
8221 right_box = gtk_vbox_new(FALSE, 5);
8222 sr->rvars1 = var_list_box_new(GTK_BOX(right_box), sr, SR_RVARS1);
8223
8224 if (sr->ci == CORR) {
8225 /* ensure that RHS var count is set to zero */
8226 set_n_rvars1(sr, 0);
8227 }
8228
8229 /* pre-fill RHS box? Only if we have 2 or more vars selected in the
8230 main window and if the command is "suitable"
8231 */
8232 if (RHS_PREFILL(ci)) {
8233 maybe_prefill_RHS(sr);
8234 }
8235
8236 /* entry field for some uses */
8237 if (ci == DEFINE_LIST) {
8238 selector_add_list_name_entry(sr);
8239 }
8240
8241 /* put buttons into mid-section */
8242 push_pull_buttons(sr, add_to_rvars1_callback,
8243 remove_from_rvars1_callback,
8244 NULL, OPT_A | OPT_R);
8245
8246 /* pack RHS */
8247 table_add_right(sr, right_box, 0);
8248
8249 /* pack left-hand stuff */
8250 table_add_left(sr, left_box, 0, sr->n_rows);
8251
8252 /* pack the whole central section into the dialog's vbox */
8253 gtk_box_pack_start(GTK_BOX(sr->vbox), sr->table, TRUE, TRUE, 0);
8254
8255 /* unhide lags check box? */
8256 if ((sr->ci == DEFINE_LIST || sr->ci == EXPORT || SAVE_DATA_ACTION(sr->ci))
8257 && lags_hidden) {
8258 unhide_lags_switch(sr);
8259 }
8260
8261 /* radio buttons? */
8262 if (want_radios(sr)) {
8263 build_selector_radios(sr);
8264 }
8265
8266 /* toggle switches for some cases */
8267 if (WANT_TOGGLES(ci)) {
8268 build_selector_switches(sr);
8269 }
8270
8271 /* combo/dropdown list? */
8272 if (want_combo(sr)) {
8273 build_selector_combo(sr);
8274 }
8275
8276 if (ci == ELLIPSE) {
8277 build_ellipse_spinner(sr);
8278 }
8279
8280 #if 0 /* not ready */
8281 /* bootstrap check box? */
8282 if (ci == OMIT && ols_omit_select(p)) {
8283 test_boot_switch(sr);
8284 }
8285 #endif
8286
8287 /* buttons: Help, Clear, Cancel, OK */
8288 build_selector_buttons(sr);
8289
8290 if (TWO_VARS_CODE(sr->ci) && sr->ci != ELLIPSE &&
8291 mdata_selection_count() == 2) {
8292 set_vars_from_main(sr);
8293 } else if (nleft == 1) {
8294 select_singleton(sr);
8295 } else if (sr->ci == DEFINE_LIST) {
8296 maybe_set_listdef_vars(sr);
8297 } else if (sr->ci == TSPLOTS || sr->ci == GR_BOX) {
8298 maybe_set_plot_vars(sr);
8299 }
8300
8301 if (nleft == 0) {
8302 err = E_DATA;
8303 } else if ((ci == COEFFSUM || ci == ELLIPSE) && nleft < 2) {
8304 err = E_DATA;
8305 } else {
8306 gtk_widget_show_all(sr->dlg);
8307 }
8308
8309 if (err) {
8310 warnbox(_("No suitable data are available"));
8311 gtk_widget_destroy(sr->dlg);
8312 sr = NULL;
8313 } else if (sr->ci == DEFINE_MATRIX) {
8314 selector_set_blocking(sr, 1);
8315 }
8316
8317 return sr;
8318 }
8319
simple_selection(int ci,const char * title,int (* callback)(),GtkWidget * parent)8320 selector *simple_selection (int ci, const char *title, int (*callback)(),
8321 GtkWidget *parent)
8322 {
8323 return simple_selection_with_data(ci, title, callback, parent, NULL);
8324 }
8325
8326
restore_vwin_menu(GtkWidget * w,windata_t * vwin)8327 static void restore_vwin_menu (GtkWidget *w, windata_t *vwin)
8328 {
8329 if (vwin != NULL && vwin->mbar != NULL) {
8330 gtk_widget_set_sensitive(vwin->mbar, TRUE);
8331 }
8332 }
8333
8334 selector *
simple_selection_for_viewer(int ci,const char * title,int (* callback)(),windata_t * vwin)8335 simple_selection_for_viewer (int ci, const char *title, int (*callback)(),
8336 windata_t *vwin)
8337 {
8338 selector *sr;
8339
8340 sr = simple_selection_with_data(ci, title, callback,
8341 vwin_toplevel(vwin),
8342 vwin);
8343
8344 if (sr != NULL && vwin->mbar != NULL) {
8345 if (window_is_tab(vwin)) {
8346 tabwin_register_dialog(sr->dlg, vwin_toplevel(vwin));
8347 } else {
8348 gtk_widget_set_sensitive(vwin->mbar, FALSE);
8349 g_signal_connect(sr->dlg, "destroy",
8350 G_CALLBACK(restore_vwin_menu),
8351 vwin);
8352 }
8353 }
8354
8355 return sr;
8356 }
8357
get_or_set_storelist(const char * s,int reset)8358 static gchar *get_or_set_storelist (const char *s, int reset)
8359 {
8360 static gchar *storelist;
8361
8362 if (s != NULL) {
8363 /* set storelist */
8364 g_free(storelist);
8365 if (*s == '\0') {
8366 storelist = NULL;
8367 } else {
8368 storelist = g_strdup(s);
8369 }
8370 return NULL;
8371 } else if (reset) {
8372 g_free(storelist);
8373 storelist = NULL;
8374 return NULL;
8375 } else {
8376 /* retrieve storelist (and NULL-ify it) */
8377 gchar *ret = storelist;
8378
8379 storelist = NULL;
8380 return ret;
8381 }
8382 }
8383
get_selector_storelist(void)8384 gchar *get_selector_storelist (void)
8385 {
8386 return get_or_set_storelist(NULL, 0);
8387 }
8388
set_selector_storelist(const char * s)8389 void set_selector_storelist (const char *s)
8390 {
8391 if (s == NULL) {
8392 /* forces a reset */
8393 get_or_set_storelist(NULL, 1);
8394 } else {
8395 get_or_set_storelist(s, 0);
8396 }
8397 }
8398
get_selected_function_names(selector * sr,char *** S1,int * n1,char *** S2,int * n2)8399 static int get_selected_function_names (selector *sr,
8400 char ***S1, int *n1,
8401 char ***S2, int *n2)
8402 {
8403 GtkTreeModel *src;
8404 GtkTreeIter iter;
8405 gchar *fname;
8406
8407 /* public function names are in top right list */
8408 src = gtk_tree_view_get_model(GTK_TREE_VIEW(sr->rvars1));
8409 if (gtk_tree_model_get_iter_first(src, &iter)) {
8410 do {
8411 gtk_tree_model_get(src, &iter, COL_NAME, &fname, -1);
8412 strings_array_add(S1, n1, gretl_strdup(fname));
8413 g_free(fname);
8414 } while (gtk_tree_model_iter_next(src, &iter));
8415 }
8416
8417 if (*n1 == 0) {
8418 warnbox(_("You must specify a public interface"));
8419 return 1;
8420 }
8421
8422 /* private function names are in lower right list */
8423 src = gtk_tree_view_get_model(GTK_TREE_VIEW(sr->rvars2));
8424 gtk_tree_model_get_iter_first(src, &iter);
8425 if (gtk_tree_model_get_iter_first(src, &iter)) {
8426 do {
8427 gtk_tree_model_get(src, &iter, COL_NAME, &fname, -1);
8428 strings_array_add(S2, n2, gretl_strdup(fname));
8429 g_free(fname);
8430 } while (gtk_tree_model_iter_next(src, &iter));
8431 }
8432
8433 return 0;
8434 }
8435
pkg_add_remove_callback(selector * sr)8436 static int pkg_add_remove_callback (selector *sr)
8437 {
8438 void *p = sr->data;
8439 char **pubnames = NULL;
8440 char **privnames = NULL;
8441 int npub = 0;
8442 int npriv = 0;
8443 int err;
8444
8445 err = get_selected_function_names(sr, &pubnames, &npub,
8446 &privnames, &npriv);
8447 if (!err) {
8448 revise_function_package(p, pubnames, npub, privnames, npriv);
8449 }
8450
8451 return err;
8452 }
8453
check_pkgname(const char * name,GtkWidget * parent)8454 static int check_pkgname (const char *name,
8455 GtkWidget *parent)
8456 {
8457 int n = strlen(name);
8458 int err = 0;
8459
8460 if (has_suffix(name, ".gfn")) {
8461 n -= 4;
8462 }
8463
8464 if (n >= FN_NAMELEN) {
8465 /* too long */
8466 err = 1;
8467 } else if (gretl_namechar_spn(name) != n) {
8468 /* contains funny stuff */
8469 err = 1;
8470 }
8471
8472 if (err) {
8473 msgbox(_("Invalid package name: the name must start with a letter,\n"
8474 "must be less than 32 characters in length, and must include\n"
8475 "only ASCII letters, numbers and '_'."),
8476 GTK_MESSAGE_ERROR, parent);
8477 }
8478
8479 return err;
8480 }
8481
functions_selected_callback(selector * sr)8482 static int functions_selected_callback (selector *sr)
8483 {
8484 GtkWidget *entry = sr->extra[0];
8485 char **pubnames = NULL;
8486 char **privnames = NULL;
8487 int npub = 0;
8488 int npriv = 0;
8489 const char *s;
8490 int err = 0;
8491
8492 s = gtk_entry_get_text(GTK_ENTRY(entry));
8493
8494 if (s == NULL || *s == '\0' || check_pkgname(s, sr->dlg)) {
8495 gtk_widget_grab_focus(entry);
8496 err = 1;
8497 } else {
8498 err = get_selected_function_names(sr, &pubnames, &npub,
8499 &privnames, &npriv);
8500 }
8501
8502 if (!err) {
8503 gchar *pkgname = g_strdup(s);
8504
8505 if (has_suffix(pkgname, ".gfn")) {
8506 char *p = strrchr(pkgname, '.');
8507
8508 *p = '\0';
8509 }
8510 edit_new_function_package(pkgname, pubnames, npub,
8511 privnames, npriv);
8512 }
8513
8514 return err;
8515 }
8516
data_export_selection_callback(selector * sr)8517 static int data_export_selection_callback (selector *sr)
8518 {
8519 int ci = sr->ci;
8520
8521 if ((sr->cmdlist == NULL || *sr->cmdlist == '\0') && sr->n_left == 0) {
8522 warnbox(_("No variables are selected"));
8523 /* return non-zero to block closing of dialog */
8524 return 1;
8525 }
8526
8527 if (ci == EXPORT) {
8528 /* set the specific export format based on the
8529 option from the series selector
8530 */
8531 if (sr->opts & OPT_C) {
8532 ci = EXPORT_CSV;
8533 } else if (sr->opts & OPT_R) {
8534 ci = EXPORT_R;
8535 } else if (sr->opts & OPT_M) {
8536 ci = EXPORT_OCTAVE;
8537 } else if (sr->opts & OPT_J) {
8538 ci = EXPORT_JM;
8539 } else if (sr->opts & OPT_G) {
8540 ci = EXPORT_DAT;
8541 } else if (sr->opts & OPT_S) {
8542 ci = EXPORT_DTA;
8543 } else if (sr->opts & OPT_D) {
8544 ci = EXPORT_DB;
8545 } else if (sr->opts & OPT_P) {
8546 ci = SAVE_MAP;
8547 } else if (sr->opts & OPT_B) {
8548 ci = EXPORT_GDTB;
8549 } else {
8550 ci = EXPORT_GDT;
8551 }
8552 }
8553
8554 if (sr->cmdlist != NULL) {
8555 set_selector_storelist(sr->cmdlist);
8556 }
8557
8558 gtk_widget_destroy(sr->dlg);
8559
8560 if (ci == EXPORT_CSV) {
8561 int resp = csv_options_dialog(EXPORT_CSV, GRETL_OBJ_DSET,
8562 NULL);
8563
8564 if (canceled(resp)) {
8565 set_selector_storelist(NULL);
8566 return 0;
8567 }
8568 }
8569
8570 if (ci != COPY_CSV) {
8571 file_selector(ci, FSEL_DATA_NONE, NULL);
8572 }
8573
8574 return 0;
8575 }
8576
data_export_selection_wrapper(int file_ci)8577 void data_export_selection_wrapper (int file_ci)
8578 {
8579 selector *sr;
8580
8581 set_selector_storelist(NULL);
8582
8583 sr = simple_selection(file_ci, (file_ci == COPY_CSV)?
8584 _("Copy data") : _("Export data"),
8585 data_export_selection_callback,
8586 NULL);
8587 if (sr != NULL) {
8588 selector_set_blocking(sr, 0);
8589 }
8590 }
8591
functions_selection_wrapper(GtkWidget * parent)8592 void functions_selection_wrapper (GtkWidget *parent)
8593 {
8594 int err;
8595
8596 set_selector_storelist(NULL);
8597 err = no_user_functions_check(parent);
8598
8599 if (!err) {
8600 selector *sr;
8601
8602 sr = selection_dialog(SAVE_FUNCTIONS, _("Select functions"),
8603 NULL, functions_selected_callback);
8604 if (sr != NULL) {
8605 selector_set_blocking(sr, 1);
8606 }
8607 }
8608 }
8609
add_remove_functions_dialog(char ** pubnames,int npub,char ** privnames,int npriv,void * p1,void * p2)8610 void add_remove_functions_dialog (char **pubnames, int npub,
8611 char **privnames, int npriv,
8612 void *p1, void *p2)
8613 {
8614 fnpkg *pkg = p1;
8615 void *finfo = p2;
8616 const char *title = NULL;
8617 selector *sr = NULL;
8618
8619 if (pkg != NULL) {
8620 title = function_package_get_name(pkg);
8621 }
8622
8623 if (title == NULL || *title == '\0') {
8624 title = _("Edit package list");
8625 }
8626
8627 /* to start with, set @pkg as sr->data to enable the correct
8628 LHS listing of functions for the package */
8629
8630 sr = selection_dialog(EDIT_FUNCTIONS, title,
8631 pkg, pkg_add_remove_callback);
8632
8633 if (sr != NULL) {
8634 GtkTreeModel *model;
8635 GtkListStore *store;
8636 GtkTreeIter iter;
8637 int i, idx;
8638
8639 /* switch sr->data to point to the current 'editor' */
8640 sr->data = finfo;
8641
8642 /* put current @pubnames into top right list box */
8643 if (npub > 0) {
8644 model = gtk_tree_view_get_model(GTK_TREE_VIEW(sr->rvars1));
8645 store = GTK_LIST_STORE(model);
8646 gtk_list_store_clear(store);
8647 gtk_tree_model_get_iter_first(model, &iter);
8648 for (i=0; i<npub; i++) {
8649 idx = user_function_index_by_name(pubnames[i], pkg);
8650 if (idx >= 0) {
8651 gtk_list_store_append(store, &iter);
8652 gtk_list_store_set(store, &iter,
8653 COL_ID, idx, COL_LAG, 0,
8654 COL_NAME, pubnames[i], -1);
8655 }
8656 }
8657 }
8658
8659 /* put current @privnames into lower right box */
8660 if (npriv > 0) {
8661 model = gtk_tree_view_get_model(GTK_TREE_VIEW(sr->rvars2));
8662 store = GTK_LIST_STORE(model);
8663 gtk_list_store_clear(store);
8664 gtk_tree_model_get_iter_first(model, &iter);
8665 for (i=0; i<npriv; i++) {
8666 idx = user_function_index_by_name(privnames[i], pkg);
8667 if (idx >= 0) {
8668 gtk_list_store_append(store, &iter);
8669 gtk_list_store_set(store, &iter,
8670 COL_ID, idx, COL_LAG, 0,
8671 COL_NAME, privnames[i], -1);
8672 }
8673 }
8674 }
8675
8676 selector_set_blocking(sr, 1);
8677 }
8678 }
8679
8680 /* accessor functions */
8681
selector_code(const selector * sr)8682 int selector_code (const selector *sr)
8683 {
8684 return (sr->ci == PANEL_WLS || sr->ci == PANEL_B)?
8685 PANEL : sr->ci;
8686 }
8687
selector_list(const selector * sr)8688 const char *selector_list (const selector *sr)
8689 {
8690 const char *ret = NULL;
8691
8692 if (sr->cmdlist != NULL && *sr->cmdlist != '\0') {
8693 ret = sr->cmdlist;
8694 }
8695
8696 return ret;
8697 }
8698
selector_list_hasconst(const selector * sr)8699 int selector_list_hasconst (const selector *sr)
8700 {
8701 int hc = sr->cmdlist != NULL &&
8702 strstr(sr->cmdlist, " 0") != NULL;
8703
8704 return hc;
8705 }
8706
selector_get_data(const selector * sr)8707 gpointer selector_get_data (const selector *sr)
8708 {
8709 return sr->data;
8710 }
8711
selector_get_extra_data(const selector * sr)8712 gpointer selector_get_extra_data (const selector *sr)
8713 {
8714 return sr->extra_data;
8715 }
8716
selector_get_opts(const selector * sr)8717 gretlopt selector_get_opts (const selector *sr)
8718 {
8719 gretlopt ret;
8720
8721 if (sr->ci == PANEL_B) {
8722 ret = sr->opts | OPT_B;
8723 } else if (sr->ci == FE_LOGISTIC) {
8724 ret = sr->opts | OPT_F;
8725 } else {
8726 ret = sr->opts;
8727 }
8728
8729 if (sr->ci == VECM || sr->ci == COINT2) {
8730 /* record Johansen case */
8731 if (ret & OPT_A) {
8732 /* --crt */
8733 jcase = J_REST_TREND;
8734 } else if (ret & OPT_N) {
8735 /* --nc */
8736 jcase = J_NO_CONST;
8737 } else if (ret & OPT_R) {
8738 /* --rc */
8739 jcase = J_REST_CONST;
8740 } else if (ret & OPT_T) {
8741 /* --ct */
8742 jcase = J_UNREST_TREND;
8743 } else {
8744 /* unrestricted constant */
8745 jcase = J_UNREST_CONST;
8746 }
8747 }
8748
8749 return ret;
8750 }
8751
selector_entry_text(const selector * sr)8752 const char *selector_entry_text (const selector *sr)
8753 {
8754 g_return_val_if_fail(GTK_IS_ENTRY(sr->extra[0]), NULL);
8755
8756 return gtk_entry_get_text(GTK_ENTRY(sr->extra[0]));
8757 }
8758
selector_error(const selector * sr)8759 int selector_error (const selector *sr)
8760 {
8761 return sr->error;
8762 }
8763
maybe_clear_selector(const int * dlist)8764 void maybe_clear_selector (const int *dlist)
8765 {
8766 int i, j;
8767
8768 if (xlist != NULL) {
8769 for (i=1; i<=xlist[0]; i++) {
8770 for (j=1; j<=dlist[0]; j++) {
8771 if (xlist[i] >= dlist[j]) {
8772 clear_selector();
8773 return;
8774 }
8775 }
8776 }
8777 }
8778 }
8779
selector_cleanup(void)8780 void selector_cleanup (void)
8781 {
8782 clear_selector();
8783
8784 if (open_selector != NULL) {
8785 gtk_widget_destroy(open_selector->dlg);
8786 }
8787 }
8788
8789 /* ------------- lag selection apparatus -------------- */
8790
8791 #define NOT_LAG 66666
8792
8793 typedef struct var_lag_info_ var_lag_info;
8794
8795 struct var_lag_info_ {
8796 int v; /* variable ID number or VDEFLT for default */
8797 int pos; /* starting position in overall array of lag setters */
8798 int nvl; /* number of siblings in array */
8799 int lmin; /* minimum lag */
8800 int lmax; /* maximum lag */
8801 char context; /* LAG_X, LAG_W, ... */
8802 char *lspec; /* string specification of particular lags */
8803 GtkWidget *spin1; /* spinner for minimum lag */
8804 GtkWidget *spin2; /* spinner for maximum lag */
8805 GtkWidget *entry; /* text entry for specific lags */
8806 GtkWidget *toggle; /* button to switch between spinners and entry */
8807 var_lag_info *vlp; /* parent array */
8808 };
8809
8810 #define depvar_row(c) (c == LAG_Y_X || c == LAG_Y_W)
8811
8812 /* handle action in the "specific lags" entry box */
8813
lag_entry_callback(GtkWidget * w,gpointer p)8814 static void lag_entry_callback (GtkWidget *w, gpointer p)
8815 {
8816 const gchar *s = gtk_entry_get_text(GTK_ENTRY(w));
8817 var_lag_info *vlinfo = (var_lag_info *) p;
8818
8819 free(vlinfo->lspec);
8820 vlinfo->lspec = g_strdup(s);
8821
8822 if (vlinfo->v == VDEFLT) {
8823 /* set the default for this context */
8824 var_lag_info *vlset = vlinfo->vlp;
8825 int i;
8826
8827 for (i=vlinfo->pos+1; i<vlinfo->nvl; i++) {
8828 if (vlset[i].context == vlinfo->context && vlset[i].entry != NULL) {
8829 gtk_entry_set_text(GTK_ENTRY(vlset[i].entry), s);
8830 }
8831 }
8832 }
8833 }
8834
8835 /* retrieve the min or max lag from a spinner and process
8836 the result */
8837
lag_set_callback(GtkWidget * w,gpointer p)8838 static void lag_set_callback (GtkWidget *w, gpointer p)
8839 {
8840 var_lag_info *vlinfo;
8841 int lag, *plag;
8842
8843 vlinfo = (var_lag_info *) g_object_get_data(G_OBJECT(w), "vlinfo");
8844
8845 plag = (w == vlinfo->spin1)? &vlinfo->lmin : &vlinfo->lmax;
8846 lag = *plag = spinner_get_int(w);
8847
8848 /* force consistency if need be */
8849
8850 if (w == vlinfo->spin1 && vlinfo->spin2 != NULL) {
8851 if (spinner_get_int(vlinfo->spin2) < lag) {
8852 gtk_spin_button_set_value(GTK_SPIN_BUTTON(vlinfo->spin2), lag);
8853 }
8854 } else if (w == vlinfo->spin2 && vlinfo->spin1 != NULL) {
8855 if (spinner_get_int(vlinfo->spin1) > lag) {
8856 gtk_spin_button_set_value(GTK_SPIN_BUTTON(vlinfo->spin1), lag);
8857 }
8858 }
8859
8860 if (vlinfo->v == VDEFLT) {
8861 /* set the default value for this context */
8862 var_lag_info *vlset = vlinfo->vlp;
8863 GtkWidget *s;
8864 int i;
8865
8866 for (i=vlinfo->pos; i<vlinfo->nvl; i++) {
8867 if (vlset[i].context == vlinfo->context) {
8868 s = (w == vlinfo->spin1)? vlset[i].spin1 : vlset[i].spin2;
8869 if (s != NULL) {
8870 gtk_spin_button_set_value(GTK_SPIN_BUTTON(s), lag);
8871 }
8872 }
8873 }
8874 }
8875 }
8876
8877 /* switch from using min/max spinners to using the "specific lags"
8878 text entry, or vice versa */
8879
activate_specific_lags(GtkWidget * w,var_lag_info * vlinfo)8880 static void activate_specific_lags (GtkWidget *w, var_lag_info *vlinfo)
8881 {
8882 gboolean active = button_is_active(w);
8883
8884 if (active) {
8885 gtk_widget_set_sensitive(vlinfo->entry, TRUE);
8886 gtk_widget_set_sensitive(vlinfo->spin1, FALSE);
8887 gtk_widget_set_sensitive(vlinfo->spin2, FALSE);
8888 gtk_widget_grab_focus(vlinfo->entry);
8889 } else {
8890 gtk_widget_set_sensitive(vlinfo->entry, FALSE);
8891 gtk_widget_set_sensitive(vlinfo->spin1, TRUE);
8892 gtk_widget_set_sensitive(vlinfo->spin2, TRUE);
8893 gtk_widget_grab_focus(vlinfo->spin1);
8894 }
8895
8896 if (vlinfo->v == VDEFLT) {
8897 /* set the default per context */
8898 var_lag_info *vlset = vlinfo->vlp;
8899 int i;
8900
8901 for (i=vlinfo->pos+1; i<vlinfo->nvl; i++) {
8902 if (vlset[i].context == vlinfo->context) {
8903 if (vlset[i].toggle != NULL) {
8904 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(vlset[i].toggle),
8905 active);
8906 }
8907 }
8908 }
8909 }
8910 }
8911
lag_toggle_register(GtkWidget * w,var_lag_info * vlinfo)8912 static void lag_toggle_register (GtkWidget *w, var_lag_info *vlinfo)
8913 {
8914 var_lag_info *vlset = vlinfo->vlp;
8915 gboolean active;
8916 int i;
8917
8918 if (vlset == NULL) return;
8919
8920 for (i=0; i<vlinfo->nvl; i++) {
8921 if (depvar_row(vlset[i].context)) {
8922 if (!gtk_widget_is_sensitive(vlset[i].spin1) &&
8923 !gtk_widget_is_sensitive(vlset[i].entry)) {
8924 /* dependent var lags are disabled */
8925 vlset[i].lmin = vlset[i].lmax = NOT_LAG; /* ?? */
8926 free(vlset[i].lspec);
8927 vlset[i].lspec = NULL;
8928 continue;
8929 }
8930 }
8931 active = button_is_active(vlset[i].toggle);
8932 if (active) {
8933 vlset[i].lmin = vlset[i].lmax = NOT_LAG;
8934 } else {
8935 free(vlset[i].lspec);
8936 vlset[i].lspec = NULL;
8937 }
8938 }
8939 }
8940
activate_y_lags(GtkWidget * w,var_lag_info * vlinfo)8941 static void activate_y_lags (GtkWidget *w, var_lag_info *vlinfo)
8942 {
8943 gboolean active = button_is_active(w);
8944
8945 gtk_widget_set_sensitive(vlinfo->spin1, active);
8946 gtk_widget_set_sensitive(vlinfo->spin2, active);
8947 gtk_widget_set_sensitive(vlinfo->toggle, active);
8948
8949 if (active) {
8950 vlinfo->lmin = spinner_get_int(vlinfo->spin1);
8951 vlinfo->lmax = spinner_get_int(vlinfo->spin2);
8952 }
8953
8954 if (vlinfo->context == LAG_Y_X) {
8955 y_x_lags_enabled = active;
8956 } else {
8957 y_w_lags_enabled = active;
8958 }
8959 }
8960
lagsel_spin_connect(GtkWidget * button)8961 static void lagsel_spin_connect (GtkWidget *button)
8962 {
8963 g_signal_connect(G_OBJECT(button), "value-changed",
8964 G_CALLBACK(lag_set_callback), NULL);
8965 gtk_entry_set_activates_default(GTK_ENTRY(button), TRUE);
8966 }
8967
resensitize_selector(GtkWidget * w,gpointer p)8968 static void resensitize_selector (GtkWidget *w, gpointer p)
8969 {
8970 if (open_selector != NULL) {
8971 gtk_widget_set_sensitive(open_selector->dlg, TRUE);
8972 }
8973 }
8974
8975 /* The actual lag selection dialog: we provide spinners for a lag
8976 range and also a free-form entry field for non-contiguous lags. In
8977 some circumstances we allow specification of lags for the dependent
8978 variable as well as the independent vars.
8979 */
8980
8981 static int
lags_dialog(const int * list,var_lag_info * vlinfo,selector * sr)8982 lags_dialog (const int *list, var_lag_info *vlinfo, selector *sr)
8983 {
8984 GtkWidget *lbl, *dialog, *myvbox;
8985 GtkWidget *tbl, *tmp, *vbox, *hbox;
8986 GtkWidget *y_check = NULL;
8987 gint tbl_len;
8988 double lmax;
8989 int VAR_special, insts;
8990 int i, j;
8991 int ret = GRETL_CANCEL;
8992
8993 dialog = gretl_dialog_new(_("lag order"), sr->dlg,
8994 GRETL_DLG_BLOCK | GRETL_DLG_RESIZE);
8995
8996 g_signal_connect(G_OBJECT(dialog), "destroy",
8997 G_CALLBACK(resensitize_selector), NULL);
8998
8999 myvbox = gtk_vbox_new(FALSE, 5);
9000
9001 VAR_special = (vlinfo[0].v == VDEFLT && vlinfo[0].context == LAG_Y_V);
9002 insts = in_gretl_list(list, LAG_W);
9003
9004 lmax = (dataset->t2 - dataset->t1) / list[0];
9005
9006 if (VAR_special) {
9007 /* allow for gaps in VAR lag order */
9008 lbl = gtk_label_new(_("Lags of endogenous variables"));
9009 gtk_box_pack_start(GTK_BOX(myvbox), lbl, FALSE, FALSE, 0);
9010 }
9011
9012 /* allow for additional label row */
9013 tbl_len = list[0] + 1;
9014
9015 tbl = gtk_table_new(tbl_len, 7, FALSE);
9016 gtk_table_set_row_spacings(GTK_TABLE(tbl), 5);
9017 gtk_table_set_col_spacings(GTK_TABLE(tbl), 5);
9018 gtk_box_pack_start(GTK_BOX(myvbox), tbl, FALSE, FALSE, 0);
9019
9020 /* row 0 of table: heading(s) */
9021
9022 if (insts) {
9023 /* there's an instruments section to follow */
9024 lbl = gtk_label_new(_("Regressors"));
9025 gtk_table_attach(GTK_TABLE(tbl), lbl, 0, 7, 0, 1, 0, 0, 0, 5);
9026 } else {
9027 if (!VAR_special) {
9028 lbl = gtk_label_new(_("Variable"));
9029 gtk_table_attach_defaults(GTK_TABLE(tbl), lbl, 0, 1, 0, 1);
9030 lbl = gtk_label_new(_("lags"));
9031 gtk_table_attach_defaults(GTK_TABLE(tbl), lbl, 1, 4, 0, 1);
9032 lbl = gtk_label_new(" ");
9033 gtk_table_attach_defaults(GTK_TABLE(tbl), lbl, 4, 5, 0, 1);
9034 }
9035
9036 lbl = gtk_label_new(_("or"));
9037 gtk_table_attach_defaults(GTK_TABLE(tbl), lbl, 5, 6, 0, 1);
9038 lbl = gtk_label_new(_("specific lags"));
9039 gtk_table_attach_defaults(GTK_TABLE(tbl), lbl, 6, 7, 0, 1);
9040 }
9041
9042 j = 0;
9043 for (i=1; i<=list[0]; i++) {
9044 var_lag_info *vlj;
9045 int li = list[i];
9046 int lmin = 0;
9047
9048 if (list_lag_special(li)) {
9049 if (li == LAG_W) {
9050 tmp = gtk_label_new(_("Instruments"));
9051 gtk_table_attach_defaults(GTK_TABLE(tbl), tmp, 0, 7, i, i+1);
9052 } else if (depvar_row(li)) {
9053 y_check = gtk_check_button_new_with_label(_("Lags of dependent variable"));
9054 gtk_table_attach_defaults(GTK_TABLE(tbl), y_check, 0, 7, i, i+1);
9055 } else {
9056 tmp = gtk_hseparator_new();
9057 gtk_table_attach_defaults(GTK_TABLE(tbl), tmp, 0, 7, i, i+1);
9058 }
9059 continue;
9060 }
9061
9062 if (!VAR_special) {
9063 if (li == VDEFLT) {
9064 lbl = gtk_label_new(_("default"));
9065 } else {
9066 lbl = gtk_label_new(dataset->varname[li]);
9067 }
9068 gtk_table_attach_defaults(GTK_TABLE(tbl), lbl, 0, 1, i, i+1);
9069 }
9070
9071 vlj = &vlinfo[j++];
9072
9073 if (depvar_row(vlj->context) || vlj->context == LAG_Y_V) {
9074 lmin = 1;
9075 }
9076
9077 /* min. lag spinner */
9078 vlj->spin1 = gtk_spin_button_new_with_range(lmin, lmax, 1);
9079 gtk_table_attach_defaults(GTK_TABLE(tbl), vlj->spin1, 1, 2, i, i+1);
9080 g_object_set_data(G_OBJECT(vlj->spin1), "vlinfo", vlj);
9081 lagsel_spin_connect(vlj->spin1);
9082 gtk_spin_button_set_value(GTK_SPIN_BUTTON(vlj->spin1), vlj->lmin);
9083
9084 lbl = gtk_label_new(_("to"));
9085 gtk_table_attach_defaults(GTK_TABLE(tbl), lbl, 2, 3, i, i+1);
9086
9087 /* max. lag spinner */
9088 vlj->spin2 = gtk_spin_button_new_with_range(lmin, lmax, 1);
9089 gtk_table_attach_defaults(GTK_TABLE(tbl), vlj->spin2, 3, 4, i, i+1);
9090 g_object_set_data(G_OBJECT(vlj->spin2), "vlinfo", vlj);
9091 lagsel_spin_connect(vlj->spin2);
9092 gtk_spin_button_set_value(GTK_SPIN_BUTTON(vlj->spin2), vlj->lmax);
9093
9094 /* spacer column */
9095 lbl = gtk_label_new(" ");
9096 gtk_table_attach_defaults(GTK_TABLE(tbl), lbl, 4, 5, i, i+1);
9097
9098 /* toggle button for activating entry of specific lags */
9099 vlj->toggle = gtk_check_button_new();
9100 gtk_table_attach_defaults(GTK_TABLE(tbl), vlj->toggle, 5, 6, i, i+1);
9101 g_signal_connect(G_OBJECT(vlj->toggle), "toggled",
9102 G_CALLBACK(activate_specific_lags), vlj);
9103
9104 /* text entry widget for specific lags */
9105 vlj->entry = gtk_entry_new();
9106 gtk_entry_set_width_chars(GTK_ENTRY(vlj->entry), 16);
9107 gtk_table_attach_defaults(GTK_TABLE(tbl), vlj->entry, 6, 7, i, i+1);
9108 g_signal_connect(G_OBJECT(vlj->entry), "changed",
9109 G_CALLBACK(lag_entry_callback), vlj);
9110 gtk_entry_set_activates_default(GTK_ENTRY(vlj->entry), TRUE);
9111 if (vlj->lspec != NULL && *vlj->lspec != '\0') {
9112 /* got a saved non-contiguous lag spec string: apply it */
9113 gtk_entry_set_text(GTK_ENTRY(vlj->entry), vlj->lspec);
9114 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(vlj->toggle),
9115 TRUE);
9116 } else {
9117 /* disable this by default */
9118 gtk_widget_set_sensitive(vlj->entry, FALSE);
9119 }
9120
9121 /* set sensitivity of dependent variable lags apparatus */
9122 if (y_check != NULL && depvar_row(vlj->context)) {
9123 g_signal_connect(G_OBJECT(y_check), "toggled",
9124 G_CALLBACK(activate_y_lags), vlj);
9125 if ((vlj->context == LAG_Y_X && y_x_lags_enabled) ||
9126 (vlj->context == LAG_Y_W && y_w_lags_enabled)) {
9127 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(y_check),
9128 TRUE);
9129 } else {
9130 gtk_widget_set_sensitive(vlj->spin1, FALSE);
9131 gtk_widget_set_sensitive(vlj->spin2, FALSE);
9132 gtk_widget_set_sensitive(vlj->toggle, FALSE);
9133 gtk_widget_set_sensitive(vlj->entry, FALSE);
9134 }
9135 }
9136 }
9137
9138 hbox = gtk_hbox_new(FALSE, 5);
9139 gtk_box_pack_start(GTK_BOX(hbox), myvbox, TRUE, TRUE, 5);
9140
9141 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
9142
9143 if (list[0] > 10) {
9144 GtkWidget *scroller = gtk_scrolled_window_new(NULL, NULL);
9145
9146 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroller),
9147 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
9148 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroller),
9149 hbox);
9150 gtk_box_pack_start(GTK_BOX(vbox), scroller, TRUE, TRUE, 5);
9151 gtk_widget_set_size_request(scroller, -1, 360);
9152 } else {
9153 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
9154 }
9155
9156 hbox = gtk_dialog_get_action_area(GTK_DIALOG(dialog));
9157
9158 /* "Cancel" button */
9159 tmp = cancel_delete_button(hbox, dialog);
9160 g_signal_connect(G_OBJECT(tmp), "clicked",
9161 G_CALLBACK(delete_widget), dialog);
9162
9163 /* "OK" button */
9164 tmp = ok_validate_button(hbox, &ret, NULL);
9165 g_signal_connect(G_OBJECT(tmp), "clicked",
9166 G_CALLBACK(lag_toggle_register), &vlinfo[0]);
9167 g_signal_connect(G_OBJECT(tmp), "clicked",
9168 G_CALLBACK(delete_widget), dialog);
9169 gtk_widget_grab_default(tmp);
9170
9171 /* "Help" button */
9172 context_help_button(hbox, LAGS_DIALOG);
9173
9174 gtk_widget_set_sensitive(sr->dlg, FALSE);
9175 gtk_widget_show_all(dialog);
9176
9177 return ret;
9178 }
9179
9180 /* based on the lags dialog, revise the representation of a given
9181 variable within the selection boxes in the model specification
9182 dialog, using varlist_insert_var_full().
9183 */
9184
9185 static void
revise_var_string(var_lag_info * vlinfo,selector * sr,int locus)9186 revise_var_string (var_lag_info *vlinfo, selector *sr, int locus)
9187 {
9188 GtkWidget *w;
9189 GtkTreeModel *mod;
9190 GtkTreeIter iter;
9191 int modv;
9192
9193 w = (locus == SR_RVARS2)? sr->rvars2 : sr->rvars1;
9194 mod = gtk_tree_view_get_model(GTK_TREE_VIEW(w));
9195 gtk_tree_model_get_iter_first(mod, &iter);
9196
9197 do {
9198 gtk_tree_model_get(mod, &iter, COL_ID, &modv, -1);
9199 if (modv == vlinfo->v) {
9200 #if VLDEBUG
9201 fprintf(stderr, "revise_var_string: calling varlist_insert_var_full\n");
9202 #endif
9203 varlist_insert_var_full(vlinfo->v, mod, &iter, sr, locus);
9204 break;
9205 }
9206 } while (gtk_tree_model_iter_next(mod, &iter));
9207 }
9208
9209 /* go through a list box and find the vars that are candidates for
9210 lag selection: this excludes constant and trend, and also
9211 list entries that are themselves just dummy placeholders
9212 for already selected lags of a variable */
9213
get_laggable_vars(GtkWidget * w,int context,int * list,int * i)9214 static int get_laggable_vars (GtkWidget *w, int context, int *list, int *i)
9215 {
9216 GtkTreeModel *model;
9217 GtkTreeIter iter;
9218 gint v, lag;
9219 int n = 0;
9220
9221 if (!GTK_IS_TREE_VIEW(w)) {
9222 return 0;
9223 }
9224
9225 model = gtk_tree_view_get_model(GTK_TREE_VIEW(w));
9226 if (model == NULL) {
9227 return 0;
9228 }
9229
9230 if (gtk_tree_model_get_iter_first(model, &iter)) {
9231 do {
9232 int laggable = 1;
9233
9234 gtk_tree_model_get(model, &iter, COL_ID, &v, COL_LAG, &lag, -1);
9235
9236 if (v == 0 || !strcmp(dataset->varname[v], "time") ||
9237 !strcmp(dataset->varname[v], "timesq")) {
9238 laggable = 0;
9239 } else if (is_lag_dummy(v, lag, context)) {
9240 laggable = 0;
9241 }
9242
9243 if (laggable) {
9244 if (list != NULL) {
9245 list[*i] = v;
9246 *i += 1;
9247 }
9248 n++;
9249 }
9250 } while (gtk_tree_model_iter_next(model, &iter));
9251 }
9252
9253 return n;
9254 }
9255
9256 /* Construct a special list which encodes the information needed
9257 for building the lag selection dialog
9258 */
9259
sr_get_stoch_list(selector * sr,int * pnset,int * pcontext)9260 static int *sr_get_stoch_list (selector *sr, int *pnset, int *pcontext)
9261 {
9262 GtkWidget *listw[2] = { NULL, NULL };
9263 gint ynum = 0;
9264 int nv[2] = {0};
9265 int nset, nsep;
9266 int context;
9267 int i, j;
9268 int *slist = NULL;
9269
9270 if (sr->ci != ARMA && sr->ci != VAR &&
9271 sr->ci != VECM && sr->ci != VLAGSEL &&
9272 sr->ci != DPANEL && sr->ci != MIDASREG) {
9273 ynum = selector_get_depvar_number(sr);
9274 }
9275
9276 listw[0] = (select_lags_primary(sr->ci))? sr->rvars1 : sr->rvars2;
9277
9278 if (USE_ZLIST(sr->ci)) {
9279 listw[1] = sr->rvars2;
9280 }
9281
9282 if (listw[0] != NULL) {
9283 /* number of laggable regressors */
9284 nv[0] = get_laggable_vars(listw[0], LAG_X, NULL, NULL);
9285 if (nv[0] == 0) {
9286 listw[0] = NULL;
9287 }
9288 }
9289
9290 if (listw[1] != NULL) {
9291 /* number of laggable instrumentsm if applicable */
9292 nv[1] = get_laggable_vars(listw[1], LAG_W, NULL, NULL);
9293 if (nv[1] == 0) {
9294 listw[1] = NULL;
9295 }
9296 }
9297
9298 #if LDEBUG
9299 fprintf(stderr, "sr_get_stoch_list: ynum = %d, nv[0] = %d, nv[1] = %d\n",
9300 ynum, nv[0], nv[1]);
9301 #endif
9302
9303 if (ynum < 0 && nv[0] == 0 && nv[1] == 0) {
9304 /* nothing relevant was found */
9305 errbox("Please add some variables to the model first");
9306 return NULL;
9307 }
9308
9309 /* initialize number of setters and separators */
9310 nset = nsep = 0;
9311
9312 /* first pass: figure out how many elements the list should have */
9313
9314 if (nv[0] > 0) {
9315 /* regressors */
9316 *pcontext = LAG_X;
9317 nset += nv[0] + (nv[0] > 1); /* the Xs plus their defaults */
9318 if (ynum > 0) {
9319 nsep++; /* depvar heading */
9320 nset++; /* depvar row */
9321 }
9322 }
9323
9324 if (nv[1] > 0) {
9325 /* instruments */
9326 if (nv[0] > 0) {
9327 nsep++; /* separator from Xs */
9328 } else {
9329 *pcontext = LAG_W;
9330 }
9331 nsep++; /* "instruments" heading */
9332 nset += nv[1] + (nv[1] > 1); /* instruments plus their defaults */
9333 if (ynum > 0) {
9334 nsep++; /* depvar (as instrument) heading */
9335 nset++; /* depvar row */
9336 }
9337 }
9338
9339 if (nv[0] == 0 && nv[1] == 0) {
9340 /* only the dependent variable is present */
9341 *pcontext = LAG_Y_X;
9342 nsep++; /* depvar heading */
9343 nset++; /* depvar row */
9344 if (USE_ZLIST(sr->ci)) {
9345 nsep++; /* list separator for insts */
9346 nsep++; /* "instruments" heading */
9347 nsep++; /* depvar heading */
9348 nset++; /* depvar row */
9349 }
9350 }
9351
9352 /* allocate the list */
9353
9354 fprintf(stderr, "nset=%d, nsep=%d\n", nset, nsep);
9355
9356 slist = gretl_list_new(nset + nsep);
9357 if (slist == NULL) {
9358 return NULL;
9359 }
9360
9361 /* second pass: actually build the list, inserting special
9362 list separators if needed
9363 */
9364
9365 i = 1;
9366 for (j=0; j<2; j++) {
9367 if (listw[j] == NULL) {
9368 continue;
9369 }
9370 context = (j == 1)? LAG_W : LAG_X;
9371 if (j == 1) {
9372 if (nv[0] > 0) {
9373 slist[i++] = LISTSEP;
9374 }
9375 slist[i++] = LAG_W;
9376 }
9377 if (nv[j] > 1) {
9378 /* insert default only if we have more than one entry */
9379 slist[i++] = VDEFLT;
9380 }
9381 get_laggable_vars(listw[j], context, slist, &i);
9382 if (ynum > 0) {
9383 slist[i++] = (j > 0)? LAG_Y_W : LAG_Y_X;
9384 slist[i++] = ynum;
9385 }
9386 }
9387
9388 /* special case where the dependent variable is the only laggable
9389 variable selected so far */
9390
9391 if (nv[0] == 0 && nv[1] == 0) {
9392 slist[i++] = LAG_Y_X;
9393 slist[i++] = ynum;
9394 if (USE_ZLIST(sr->ci)) {
9395 slist[i++] = LISTSEP;
9396 slist[i++] = LAG_W;
9397 slist[i++] = LAG_Y_W;
9398 slist[i++] = ynum;
9399 }
9400 }
9401
9402 *pnset = nset;
9403
9404 return slist;
9405 }
9406
maybe_revise_var_string(var_lag_info * vlinfo,selector * sr)9407 static void maybe_revise_var_string (var_lag_info *vlinfo, selector *sr)
9408 {
9409 int locus = 0;
9410
9411 #if VLDEBUG
9412 fprintf(stderr, "maybe_revise_var_string: v = %d, context = %d\n",
9413 vlinfo->v, vlinfo->context);
9414 #endif
9415
9416 if (vlinfo->context == LAG_X) {
9417 locus = (sr->ci == VAR ||
9418 sr->ci == VECM ||
9419 sr->ci == VLAGSEL)? SR_RVARS2 : SR_RVARS1;
9420 } else if (vlinfo->context == LAG_W) {
9421 locus = SR_RVARS2;
9422 } else if (depvar_row(vlinfo->context)) {
9423 #if VLDEBUG
9424 fprintf(stderr, " calling maybe_revise_depvar_lags, context = %d\n",
9425 vlinfo->context);
9426 #endif
9427 maybe_revise_depvar_lags(sr, vlinfo->v, vlinfo->context);
9428 }
9429
9430 if (locus > 0) {
9431 #if VLDEBUG
9432 fprintf(stderr, " calling revise_var_string, locus = %d\n", locus);
9433 #endif
9434 revise_var_string(vlinfo, sr, locus);
9435 }
9436 }
9437
9438 /* return 1 if lags changed, else 0 */
9439
set_lags_for_var(var_lag_info * vlinfo,int yxlags,int ywlags)9440 static int set_lags_for_var (var_lag_info *vlinfo, int yxlags, int ywlags)
9441 {
9442 int *llist = NULL;
9443 int changed = 0;
9444 int err = 0;
9445
9446 #if LDEBUG
9447 fprintf(stderr, "set_lags_for_var: v=%d, lmin=%d, lmax=%d, lspec=%p\n",
9448 vlinfo->v, vlinfo->lmin, vlinfo->lmax, (void *) vlinfo->lspec);
9449 #endif
9450
9451 if (vlinfo->lspec != NULL && *vlinfo->lspec != 0) {
9452 gretl_charsub(vlinfo->lspec, ',', ' ');
9453 llist = gretl_list_from_string(vlinfo->lspec, &err);
9454 if (!err) {
9455 err = set_lag_prefs_from_list(vlinfo->v, llist, vlinfo->context,
9456 &changed);
9457 if (err) {
9458 free(llist);
9459 }
9460 }
9461 } else if (vlinfo->lmin != NOT_LAG && vlinfo->lmax != NOT_LAG) {
9462 set_lag_prefs_from_minmax(vlinfo->v, vlinfo->lmin, vlinfo->lmax,
9463 vlinfo->context, &changed);
9464 } else {
9465 set_null_lagpref(vlinfo->v, vlinfo->context, &changed);
9466 }
9467
9468 if (vlinfo->context == LAG_Y_X && yxlags != y_x_lags_enabled) {
9469 changed = 1;
9470 } else if (vlinfo->context == LAG_Y_W && ywlags != y_w_lags_enabled) {
9471 changed = 1;
9472 }
9473
9474 return changed;
9475 }
9476
9477 /* Keep the global "lag order" spinner in sync with lag specifications
9478 entered via the the (more complex) lags dialog. We set the value
9479 shown in the spinner to the maximum lag; in addition we desensitize
9480 the global spinner if the user has specified gaps in the lag
9481 structure.
9482 */
9483
sync_lag_order_spinner(var_lag_info * vlinfo,selector * sr)9484 static void sync_lag_order_spinner (var_lag_info *vlinfo,
9485 selector *sr)
9486 {
9487 const int *list = NULL;
9488 int lmin = 0, lmax = 0;
9489
9490 get_lag_preference(vlinfo->v, &lmin, &lmax, &list,
9491 vlinfo->context, sr);
9492
9493 if (list != NULL) {
9494 lmin = list[1];
9495 lmax = list[list[0]];
9496 }
9497
9498 if (lmax != 0 && lmax != spinner_get_int(sr->extra[0])) {
9499 /* update max lag as shown by spinner */
9500 gtk_spin_button_set_value(GTK_SPIN_BUTTON(sr->extra[0]),
9501 lmax);
9502 }
9503
9504 if (lmin > 1 || list != NULL) {
9505 /* not 1-based consecutive lags: so disable spinner */
9506 gtk_widget_set_sensitive(sr->extra[0], FALSE);
9507 } else {
9508 gtk_widget_set_sensitive(sr->extra[0], TRUE);
9509 }
9510 }
9511
9512 #if LDEBUG > 2
print_vlinfo(var_lag_info * vlj)9513 static void print_vlinfo (var_lag_info *vlj)
9514 {
9515 fprintf(stderr, "\nCreated vlinfostruct:\n");
9516 fprintf(stderr, " v = %d\n", vlj->v);
9517 fprintf(stderr, " pos = %d\n", vlj->pos);
9518 fprintf(stderr, " nvl = %d\n", vlj->nvl);
9519 fprintf(stderr, " context = %d\n", (int) vlj->context);
9520 fprintf(stderr, " vlp = %p\n", (void *) vlj->vlp);
9521
9522 fprintf(stderr, " lmin = %d\n", vlj->lmin);
9523 fprintf(stderr, " lmax = %d\n", vlj->lmax);
9524
9525 if (vlj->lspec != NULL) {
9526 fprintf(stderr, " lspec = '%s'\n", vlj->lspec);
9527 } else {
9528 fprintf(stderr, " lspec = NULL\n");
9529 }
9530 }
9531 #endif
9532
9533 /* Respond to the user clicking the "Lags..." button: here we build
9534 the information needed to make the lag selection dialog, run
9535 the dialog, then implement any changes made via the GUI.
9536 */
9537
lags_dialog_driver(GtkWidget * w,selector * sr)9538 static gboolean lags_dialog_driver (GtkWidget *w, selector *sr)
9539 {
9540 var_lag_info *vlinfo;
9541 int yxlags = y_x_lags_enabled;
9542 int ywlags = y_w_lags_enabled;
9543 int context = 0;
9544 int i, j, resp, nvl;
9545 int *list;
9546
9547 if (w == sr->extra[EXTRA_LAGS]) {
9548 /* VAR: use a dummy entry for all endogenous vars */
9549 list = gretl_list_new(1);
9550 if (list == NULL) {
9551 return FALSE;
9552 }
9553 list[1] = VDEFLT;
9554 nvl = 1;
9555 context = LAG_Y_V;
9556 } else {
9557 /* get the list of stochastic (laggable) variables */
9558 list = sr_get_stoch_list(sr, &nvl, &context);
9559 if (list == NULL) {
9560 return FALSE;
9561 }
9562 }
9563
9564 #if LDEBUG
9565 printlist(list, "stochastic vars list");
9566 fprintf(stderr, "number of setters = %d\n", nvl);
9567 #endif
9568
9569 /* allocate array of vlinfo, one per laggable var */
9570 vlinfo = mymalloc(nvl * sizeof *vlinfo);
9571 if (vlinfo == NULL) {
9572 free(list);
9573 return FALSE;
9574 }
9575
9576 j = 0;
9577 for (i=1; i<=list[0]; i++) {
9578 const int *laglist = NULL;
9579 var_lag_info *vlj;
9580 int vi = list[i];
9581
9582 if (list_lag_special(vi)) {
9583 /* LISTSEP is used to switch "lag context" */
9584 context = (vi == LISTSEP)? 0 : vi;
9585 #if LDEBUG
9586 fprintf(stderr, "list[%d] = %d: set context = %d\n",
9587 i, vi, context);
9588 #endif
9589 continue;
9590 }
9591
9592 vlj = &vlinfo[j++];
9593
9594 /* pick up any saved preferences (including saved defaults) */
9595 get_lag_preference(vi, &vlj->lmin, &vlj->lmax,
9596 &laglist, context, sr);
9597
9598 if (laglist != NULL) {
9599 /* we got a list of specific lags for variable vi: convert
9600 to a string for putting into a text entry box */
9601 vlj->lspec = gretl_list_to_numeric_string(laglist);
9602 vlj->lmin = laglist[1];
9603 vlj->lmax = laglist[laglist[0]];
9604 } else {
9605 vlj->lspec = NULL;
9606 }
9607
9608 vlj->v = vi;
9609 vlj->pos = j;
9610 vlj->nvl = nvl;
9611 vlj->context = context;
9612 vlj->spin1 = NULL;
9613 vlj->spin2 = NULL;
9614 vlj->entry = NULL;
9615 vlj->toggle = NULL;
9616 vlj->vlp = vlinfo;
9617 #if LDEBUG > 2
9618 print_vlinfo(vlj);
9619 #endif
9620 }
9621
9622 /* show the user the lags dialog box */
9623 resp = lags_dialog(list, vlinfo, sr);
9624
9625 if (canceled(resp)) {
9626 y_x_lags_enabled = yxlags;
9627 y_w_lags_enabled = ywlags;
9628 } else {
9629 /* register any changes made by the user */
9630 for (j=0; j<nvl; j++) {
9631 int changed = set_lags_for_var(&vlinfo[j], yxlags, ywlags);
9632
9633 if (vlinfo[j].v != VDEFLT && changed) {
9634 maybe_revise_var_string(&vlinfo[j], sr);
9635 }
9636 }
9637 if (context == LAG_Y_V) {
9638 sync_lag_order_spinner(&vlinfo[0], sr);
9639 }
9640 }
9641
9642 /* clean up any allocated lag spec strings */
9643 for (j=0; j<nvl; j++) {
9644 if (vlinfo[j].lspec != NULL) {
9645 free(vlinfo[j].lspec);
9646 }
9647 }
9648
9649 free(list);
9650 free(vlinfo);
9651
9652 return FALSE;
9653 }
9654