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