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 /* toolbar.c: main-window toolbar, viewer window toolbars, etc. */
21
22 #include "gretl.h"
23 #include "console.h"
24 #include "session.h"
25 #include "datafiles.h"
26 #include "selector.h"
27 #include "textbuf.h"
28 #include "textutil.h"
29 #include "series_view.h"
30 #include "model_table.h"
31 #include "cmdstack.h"
32 #include "dlgutils.h"
33 #include "fileselect.h"
34 #include "winstack.h"
35 #include "tabwin.h"
36 #include "fncall.h"
37 #include "fnsave.h"
38 #include "database.h"
39 #include "toolbar.h"
40
41 #include "uservar.h"
42 #include "forecast.h"
43 #include "gretl_www.h"
44
45 #ifdef G_OS_WIN32
46 # include "gretlwin32.h"
47 #endif
48
49 #include <gio/gio.h>
50
51 /* for viewer window toolbars */
52 #include "../pixmaps/mini.en.xpm"
53
54 /* for pop-up search entry */
55 #include "../pixmaps/close_16.xpm"
56
57 /* for window-finder menu */
58 #include "../pixmaps/mini.gretl.xpm"
59 #include "../pixmaps/mini.table.xpm"
60 #include "../pixmaps/mini.page.xpm"
61
62 enum {
63 SAVE_ITEM = 1,
64 SAVE_AS_ITEM,
65 EDIT_ITEM,
66 PLOT_ITEM,
67 EXEC_ITEM,
68 COPY_ITEM,
69 PRINT_ITEM,
70 TEX_ITEM,
71 ADD_DATA_ITEM,
72 ADD_MATRIX_ITEM,
73 MAIL_ITEM,
74 HELP_ITEM,
75 CMD_HELP_ITEM,
76 GP_HELP_ITEM,
77 X12A_HELP_ITEM,
78 SORT_ITEM,
79 SORT_BY_ITEM,
80 FORMAT_ITEM,
81 INDEX_ITEM,
82 EDIT_HANSL_ITEM,
83 STICKIFY_ITEM,
84 ALPHA_ITEM,
85 REFRESH_ITEM,
86 OPEN_ITEM,
87 SPLIT_H_ITEM,
88 SPLIT_V_ITEM,
89 EDITOR_ITEM,
90 NOTES_ITEM,
91 NEW_ITEM,
92 BUNDLE_ITEM,
93 FIND_ITEM,
94 COPY_SCRIPT_ITEM,
95 BUILD_ITEM,
96 HMAP_ITEM,
97 DIGITS_ITEM,
98 DBN_ITEM,
99 FCAST_ITEM,
100 CLOSE_ITEM
101 } viewbar_flags;
102
103 int toolbar_icon_size = GTK_ICON_SIZE_MENU;
104
105 struct png_stock_maker {
106 char *fname;
107 const char *id;
108 gint8 in_menu;
109 };
110
111 struct png_stock_maker png_stocks[] = {
112 { "calc.png", GRETL_STOCK_CALC, 0 },
113 { "database.png", GRETL_STOCK_DB, 0 },
114 { "fx.png", GRETL_STOCK_FUNC, 0 },
115 { "betahat.png", GRETL_STOCK_MODEL, 0 },
116 { "iconview.png", GRETL_STOCK_ICONS, 0 },
117 { "console.png", GRETL_STOCK_CONSOLE, 0 },
118 { "plot.png", GRETL_STOCK_SCATTER, 0 },
119 { "winlist.png", GRETL_STOCK_WINLIST },
120 { "bundle.png", GRETL_STOCK_BUNDLE, 1 },
121 { "alpha.png", GRETL_STOCK_ALPHA, 0 },
122 { "tex.png", GRETL_STOCK_TEX, 0 },
123 { "bigger.png", GRETL_STOCK_BIGGER, 0 },
124 { "smaller.png", GRETL_STOCK_SMALLER, 0 },
125 { "menu.png", GRETL_STOCK_MENU, 0 },
126 { "tools.png", GRETL_STOCK_TOOLS, 0 },
127 { "dbnomics.png", GRETL_STOCK_DBN, 1 },
128 { "fcast.png", GRETL_STOCK_FCAST, 0 },
129 { "heatmap.png", GRETL_STOCK_HMAP, 0 },
130 { "pushpin.png", GRETL_STOCK_PIN, 0 },
131 { "mail.png", GRETL_STOCK_MAIL, 1 },
132 { "pdf.png", GRETL_STOCK_PDF, 1 },
133 { "split_h.png", GRETL_STOCK_SPLIT_H, 0 },
134 { "join_h.png", GRETL_STOCK_JOIN_H, 0 },
135 { "split_v.png", GRETL_STOCK_SPLIT_V, 0 },
136 { "join_v.png", GRETL_STOCK_JOIN_V, 0 },
137 { "boxplot.png", GRETL_STOCK_BOX, 0 },
138 { "tsplot.png", GRETL_STOCK_TS, 0 },
139 { "book.png", GRETL_STOCK_BOOK, 0 },
140 { "query.png", GRETL_STOCK_QUERY, 0 },
141 };
142
143 struct xpm_stock_maker {
144 char **xpm;
145 const char *id;
146 };
147
148 #if GTK_MAJOR_VERSION == 3
149
try_auto_icon_sizing(int * bigger)150 static void try_auto_icon_sizing (int *bigger)
151 {
152 GdkDisplay *display = gdk_display_get_default();
153 GdkMonitor *monitor = gdk_display_get_primary_monitor(display);
154 GdkScreen *screen = gdk_screen_get_default();
155
156 if (monitor != NULL) {
157 int mmw = gdk_monitor_get_width_mm(monitor);
158 int pxw = gdk_screen_get_width(screen);
159 double mm16 = 16 * mmw / (double) pxw;
160
161 if (mm16 < 2.8) {
162 /* size of 16 pixels in millimeters */
163 fprintf(stderr, " auto-setting larger icons\n");
164 *bigger = 1;
165 }
166 }
167 }
168
169 #endif /* GTK3 */
170
gretl_stock_icons_init(void)171 void gretl_stock_icons_init (void)
172 {
173 struct xpm_stock_maker xpm_stocks[] = {
174 { mini_en_xpm, GRETL_STOCK_EN },
175 { mini_gretl_xpm, GRETL_STOCK_GRETL},
176 { mini_table_xpm, GRETL_STOCK_TABLE},
177 { mini_page_xpm, GRETL_STOCK_PAGE},
178 { close_16_xpm, GRETL_STOCK_CLOSE}
179 };
180 static GtkIconFactory *gretl_factory;
181 int n1 = G_N_ELEMENTS(png_stocks);
182 int n2 = G_N_ELEMENTS(xpm_stocks);
183
184 if (gretl_factory == NULL) {
185 int bigger = (get_icon_sizing() == ICON_SIZE_MEDIUM);
186 char icon_path[48], menu_path[48];
187 gchar *p, *pm, *respath;
188 GResource *icons;
189 GtkIconSource *isrc;
190 GtkIconSet *iset;
191 GdkPixbuf *pbuf;
192 int i;
193
194 #if GTK_MAJOR_VERSION == 3
195 if (get_icon_sizing() == ICON_SIZE_AUTO) {
196 try_auto_icon_sizing(&bigger);
197 }
198 #endif
199
200 if (bigger) {
201 #if GTK_MAJOR_VERSION == 3
202 toolbar_icon_size = GTK_ICON_SIZE_LARGE_TOOLBAR;
203 #else
204 toolbar_icon_size = GTK_ICON_SIZE_SMALL_TOOLBAR;
205 #endif
206 }
207
208 gretl_factory = gtk_icon_factory_new();
209
210 respath = g_strdup_printf("%sgretl-icons.gresource", gretl_home());
211 icons = g_resource_load(respath, NULL);
212 if (icons == NULL) {
213 fprintf(stderr, "g_resource_load: failed to load icons\n");
214 g_free(respath);
215 goto do_pixmaps;
216 }
217
218 g_resources_register(icons);
219
220 if (bigger) {
221 strcpy(icon_path, "/gretl/icons/24x24/");
222 strcpy(menu_path, "/gretl/icons/16x16/");
223 pm = strrchr(menu_path, '/') + 1;
224 } else {
225 strcpy(icon_path, "/gretl/icons/16x16/");
226 }
227 p = strrchr(icon_path, '/') + 1;
228
229 for (i=0; i<n1; i++) {
230 strcat(icon_path, png_stocks[i].fname);
231 pbuf = gdk_pixbuf_new_from_resource(icon_path, NULL);
232 if (pbuf == NULL) {
233 fprintf(stderr, "Failed to load %s\n", icon_path);
234 *p = '\0';
235 continue;
236 }
237 if (bigger && png_stocks[i].in_menu) {
238 iset = gtk_icon_set_new();
239 /* for toolbar use */
240 isrc = gtk_icon_source_new();
241 gtk_icon_source_set_pixbuf(isrc, pbuf);
242 gtk_icon_source_set_size(isrc, toolbar_icon_size);
243 gtk_icon_source_set_size_wildcarded(isrc, FALSE);
244 gtk_icon_set_add_source(iset, isrc);
245 g_object_unref(pbuf);
246 /* for menu use */
247 strcat(menu_path, png_stocks[i].fname);
248 pbuf = gdk_pixbuf_new_from_resource(menu_path, NULL);
249 isrc = gtk_icon_source_new();
250 gtk_icon_source_set_pixbuf(isrc, pbuf);
251 gtk_icon_source_set_size(isrc, GTK_ICON_SIZE_MENU);
252 gtk_icon_source_set_size_wildcarded(isrc, FALSE);
253 gtk_icon_set_add_source(iset, isrc);
254 g_object_unref(pbuf);
255 *pm = '\0';
256 } else {
257 /* we just need a single icon */
258 iset = gtk_icon_set_new_from_pixbuf(pbuf);
259 }
260 gtk_icon_factory_add(gretl_factory, png_stocks[i].id, iset);
261 gtk_icon_set_unref(iset);
262 *p = '\0';
263 }
264
265 g_free(respath);
266 g_resources_unregister(icons);
267 g_resource_unref(icons);
268
269 do_pixmaps:
270
271 for (i=0; i<n2; i++) {
272 pbuf = gdk_pixbuf_new_from_xpm_data((const char **) xpm_stocks[i].xpm);
273 iset = gtk_icon_set_new_from_pixbuf(pbuf);
274 g_object_unref(pbuf);
275 gtk_icon_factory_add(gretl_factory, xpm_stocks[i].id, iset);
276 gtk_icon_set_unref(iset);
277 }
278
279 gtk_icon_factory_add_default(gretl_factory);
280 }
281 }
282
283 /* callbacks for viewer window toolbar */
284
copy_to_editor(GtkWidget * w,windata_t * vwin)285 static void copy_to_editor (GtkWidget *w, windata_t *vwin)
286 {
287 gchar *buf = textview_get_text(vwin->text);
288
289 if (vwin->role == VIEW_LOG) {
290 /* allow for the possibility that the buffer is empty */
291 gchar *s = buf;
292 int n = 0;
293
294 while (s != NULL && n < 3) {
295 s = strchr(s, '\n');
296 if (s != NULL) {
297 s++;
298 n++;
299 }
300 }
301
302 if (s != NULL) {
303 gchar *modbuf;
304
305 modbuf = g_strdup_printf("# logged commands\n%s", s);
306 do_new_script(EDIT_HANSL, modbuf);
307 g_free(modbuf);
308 } else {
309 do_new_script(EDIT_HANSL, buf);
310 }
311 } else {
312 do_new_script(EDIT_HANSL, buf);
313 }
314
315 g_free(buf);
316 }
317
save_as_callback(GtkWidget * w,windata_t * vwin)318 static void save_as_callback (GtkWidget *w, windata_t *vwin)
319 {
320 GtkWidget *vmain = vwin_toplevel(vwin);
321 guint u = 0;
322
323 if (g_object_get_data(G_OBJECT(vmain), "text_out")) {
324 const char *opts[] = {
325 N_("Save to file"),
326 N_("Save to session as icon")
327 };
328 int resp;
329
330 resp = radio_dialog(_("gretl: save text"), _("Save text"),
331 opts, 2, 0, 0, vmain);
332 if (resp < 0) {
333 return;
334 } else if (resp == 1) {
335 save_output_as_text_icon(vwin);
336 return;
337 } else {
338 u = SAVE_OUTPUT;
339 }
340 } else if (vwin->role == EDIT_HANSL) {
341 u = SAVE_SCRIPT;
342 } else if (vwin->role == EDIT_GP) {
343 u = SAVE_GP_CMDS;
344 } else if (vwin->role == EDIT_R) {
345 u = SAVE_R_CMDS;
346 } else if (vwin->role == EDIT_OX) {
347 u = SAVE_OX_CMDS;
348 } else if (vwin->role == EDIT_OCTAVE) {
349 u = SAVE_OCTAVE_CMDS;
350 } else if (vwin->role == EDIT_PYTHON) {
351 u = SAVE_PYTHON_CMDS;
352 } else if (vwin->role == EDIT_JULIA) {
353 u = SAVE_JULIA_CODE;
354 } else if (vwin->role == EDIT_DYNARE) {
355 u = SAVE_DYNARE_CODE;
356 } else if (vwin->role == EDIT_LPSOLVE) {
357 u = SAVE_LPSOLVE_CODE;
358 } else if (vwin->role == EDIT_STATA) {
359 u = SAVE_STATA_CMDS;
360 } else if (vwin->role == EDIT_SPEC) {
361 u = SAVE_SPEC_FILE;
362 } else if (vwin->role == VIEW_FILE) {
363 u = SAVE_TEXT;
364 } else if (vwin->role == EDIT_PKG_HELP ||
365 vwin->role == EDIT_PKG_GHLP) {
366 u = SAVE_HELP_TEXT;
367 } else {
368 dummy_call();
369 return;
370 }
371
372 file_save(vwin, u);
373 }
374
375 /* Adjust the number of significant figures used in printing
376 coefficients and standard errors in a model viewer window,
377 or descriptive statistics in a "summary" window. Also record
378 the number of digits for use via Copy.
379 */
380
display_digits_callback(GtkWidget * w,windata_t * vwin)381 static void display_digits_callback (GtkWidget *w, windata_t *vwin)
382 {
383 int wdigits = widget_get_int(vwin->text, "digits");
384 int save_digits = get_gretl_digits();
385 int digits, resp;
386
387 digits = wdigits > 0 ? wdigits : save_digits;
388
389 if (vwin->role == SUMMARY) {
390 /* desciptive statistics window */
391 Summary *s = vwin->data;
392 int dmax = (s->opt & OPT_S)? 4 : 5;
393
394 digits = (digits > dmax)? dmax : digits;
395 resp = spin_dialog(NULL, NULL, &digits,
396 _("Number of digits to show for statistics"),
397 3, dmax, 0, vwin_toplevel(vwin));
398 } else {
399 /* model window */
400 resp = spin_dialog(NULL, NULL, &digits,
401 _("Number of digits to show for coefficients"),
402 3, 6, 0, vwin_toplevel(vwin));
403 }
404
405 if (resp != GRETL_CANCEL && digits != wdigits) {
406 const char *buf;
407 int save_digits;
408 PRN *prn;
409
410 if (bufopen(&prn)) return;
411 save_digits = get_gretl_digits();
412 set_gretl_digits(digits);
413 if (vwin->role == SUMMARY) {
414 print_summary(vwin->data, dataset, prn);
415 } else {
416 printmodel(vwin->data, dataset, OPT_NONE, prn);
417 }
418 buf = gretl_print_get_trimmed_buffer(prn);
419 textview_set_text(vwin->text, buf);
420 gretl_print_destroy(prn);
421 set_gretl_digits(save_digits);
422 widget_set_int(vwin->text, "digits", digits);
423 }
424 }
425
mail_script_callback(GtkWidget * w,windata_t * vwin)426 static void mail_script_callback (GtkWidget *w, windata_t *vwin)
427 {
428 if (viewer_char_count(vwin) == 0) {
429 infobox(_("Nothing to send"));
430 return;
431 }
432
433 if (query_save_text(NULL, NULL, vwin)) {
434 return;
435 }
436
437 send_attachment(vwin->fname);
438 }
439
440 /* callback for the "Open" icon in a script editing window,
441 which enables the user to switch to a different script,
442 or to open another tab if the editor is tab-enabled
443 */
444
file_open_callback(GtkWidget * w,windata_t * vwin)445 static void file_open_callback (GtkWidget *w, windata_t *vwin)
446 {
447 file_selector(OPEN_SCRIPT, FSEL_DATA_VWIN, vwin);
448 }
449
open_pkg_sample(GtkWidget * w,windata_t * vwin)450 static void open_pkg_sample (GtkWidget *w, windata_t *vwin)
451 {
452 if (viewer_char_count(vwin) > 0) {
453 int resp;
454
455 resp = yes_no_dialog(NULL, _("Really replace content with\n"
456 "a selected file?"),
457 vwin->main);
458 if (resp != GRETL_YES) {
459 return;
460 }
461 }
462
463 file_selector(OPEN_SCRIPT, FSEL_DATA_VWIN, vwin);
464 }
465
toolbar_new_callback(GtkWidget * w,windata_t * vwin)466 static void toolbar_new_callback (GtkWidget *w, windata_t *vwin)
467 {
468 do_new_script(vwin->role, NULL);
469 }
470
window_print_callback(GtkWidget * w,windata_t * vwin)471 static void window_print_callback (GtkWidget *w, windata_t *vwin)
472 {
473 if (textview_use_highlighting(vwin->role)) {
474 int resp = yes_no_cancel_dialog(NULL,
475 _("Print with syntax highlighting?"),
476 vwin_toplevel(vwin));
477
478 if (resp == GRETL_YES) {
479 sourceview_print(vwin);
480 } else if (resp == GRETL_NO) {
481 window_print(NULL, vwin);
482 }
483 } else {
484 window_print(NULL, vwin);
485 }
486 }
487
window_help(GtkWidget * w,windata_t * vwin)488 static void window_help (GtkWidget *w, windata_t *vwin)
489 {
490 show_gui_help(vwin->role);
491 }
492
multi_save_as_callback(GtkWidget * w,windata_t * vwin)493 static void multi_save_as_callback (GtkWidget *w, windata_t *vwin)
494 {
495 copy_format_dialog(vwin, W_SAVE);
496 }
497
script_index(GtkWidget * w,windata_t * vwin)498 static void script_index (GtkWidget *w, windata_t *vwin)
499 {
500 display_files(PS_FILES, NULL);
501 }
502
toolbar_refresh(GtkWidget * w,windata_t * vwin)503 static void toolbar_refresh (GtkWidget *w, windata_t *vwin)
504 {
505 if (vwin->role == VIEW_SERIES) {
506 series_view_refresh(w, vwin);
507 }
508 }
509
set_matrix_name(GtkWidget * widget,dialog_t * dlg)510 static void set_matrix_name (GtkWidget *widget, dialog_t *dlg)
511 {
512 char *vname = (char *) edit_dialog_get_data(dlg);
513 GtkWidget *parent = edit_dialog_get_window(dlg);
514 const gchar *s = edit_dialog_get_text(dlg);
515
516 if (s == NULL || gui_validate_varname(s, GRETL_TYPE_MATRIX, parent)) {
517 edit_dialog_reset(dlg);
518 } else {
519 strcpy(vname, s);
520 edit_dialog_close(dlg);
521 }
522 }
523
add_matrix_callback(GtkWidget * w,windata_t * vwin)524 static void add_matrix_callback (GtkWidget *w, windata_t *vwin)
525 {
526 if (vwin->role == XTAB) {
527 char mname[VNAMELEN];
528 gretl_matrix *m;
529 int err, cancel = 0;
530
531 blocking_edit_dialog(0, _("gretl: save matrix"),
532 _("Enter a name"), NULL,
533 set_matrix_name, mname,
534 VARCLICK_NONE,
535 vwin_toplevel(vwin),
536 &cancel);
537 if (!cancel) {
538 m = xtab_to_matrix(vwin->data);
539 if (m == NULL) {
540 nomem();
541 } else {
542 err = user_var_add_or_replace(mname,
543 GRETL_TYPE_MATRIX,
544 m);
545 if (err) {
546 gretl_matrix_free(m);
547 gui_errmsg(err);
548 } else {
549 infobox_printf(_("Saved matrix as %s"), mname);
550 }
551 }
552 }
553 }
554 }
555
add_data_callback(GtkWidget * w,windata_t * vwin)556 static void add_data_callback (GtkWidget *w, windata_t *vwin)
557 {
558 int oldv = dataset->v;
559
560 if (vwin->role == PCA) {
561 add_pca_data(vwin);
562 } else if (vwin->role == LEVERAGE) {
563 add_leverage_data(vwin);
564 } else if (vwin->role == MAHAL) {
565 add_mahalanobis_data(vwin);
566 } else if (vwin->role == FCAST) {
567 add_fcast_data(vwin, M_FCAST);
568 } else if (vwin->role == LOESS || vwin->role == NADARWAT) {
569 add_nonparam_data(vwin);
570 } else if (vwin->role == VIEW_DBNOMICS) {
571 add_dbnomics_data(vwin);
572 }
573
574 if (dataset->v > oldv) {
575 populate_varlist();
576 mark_dataset_as_modified();
577 }
578 }
579
real_coeffint_set_alpha(GtkWidget * w,GtkWidget * dialog)580 static void real_coeffint_set_alpha (GtkWidget *w, GtkWidget *dialog)
581 {
582 windata_t *vwin = g_object_get_data(G_OBJECT(dialog), "vwin");
583 double *x = g_object_get_data(G_OBJECT(dialog), "xptr");
584 CoeffIntervals *cf = vwin->data;
585 GtkTextBuffer *buf;
586 const char *newtext;
587 PRN *prn;
588
589 if (bufopen(&prn)) {
590 return;
591 }
592
593 reset_coeff_intervals(cf, 1.0 - *x);
594 text_print_model_confints(cf, prn);
595 newtext = gretl_print_get_buffer(prn);
596 buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(vwin->text));
597 gtk_text_buffer_set_text(buf, "", -1);
598 textview_set_text(vwin->text, newtext);
599 gretl_print_destroy(prn);
600
601 gtk_widget_destroy(dialog);
602 }
603
alpha_button_callback(GtkToggleButton * b,double * x)604 static void alpha_button_callback (GtkToggleButton *b, double *x)
605 {
606 if (gtk_toggle_button_get_active(b)) {
607 int i = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(b), "i"));
608
609 if (i == 0) {
610 *x = 0.90;
611 } else if (i == 1) {
612 *x = 0.95;
613 } else if (i == 2) {
614 *x = 0.99;
615 }
616 }
617 }
618
reformat_callback(GtkWidget * w,windata_t * vwin)619 static void reformat_callback (GtkWidget *w, windata_t *vwin)
620 {
621 if (vwin->role == VIEW_MODELTABLE) {
622 format_model_table(vwin);
623 } else {
624 series_view_format_dialog(vwin);
625 }
626 }
627
split_pane_callback(GtkWidget * w,windata_t * vwin)628 static void split_pane_callback (GtkWidget *w, windata_t *vwin)
629 {
630 GtkWidget *hb = g_object_get_data(G_OBJECT(w), "hpane");
631 GtkWidget *vb = g_object_get_data(G_OBJECT(w), "vpane");
632 int vertical = 0;
633
634 if (hb != NULL) {
635 vb = w;
636 vertical = 1;
637 } else {
638 hb = w;
639 }
640
641 /* Note: by "vertical" here we mean that the split runs vertically,
642 dividing the pane into left- and right-hand sections; otherwise
643 the split runs horizontally. In a "gnuplot commands" window we
644 only offer a horizontal split, which means that @vb ("vertical
645 button") may be NULL.
646 */
647
648 if (g_object_get_data(G_OBJECT(vwin->vbox), "sw") != NULL) {
649 /* currently in single-view mode: so split */
650 viewer_split_pane(vwin, vertical);
651 if (vb != NULL) {
652 gtk_widget_set_sensitive(vb, vertical);
653 }
654 gtk_widget_set_sensitive(hb, !vertical);
655 if (vertical) {
656 gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(vb),
657 GRETL_STOCK_JOIN_V);
658 } else {
659 gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(hb),
660 GRETL_STOCK_JOIN_H);
661 }
662 } else {
663 GtkWidget *paned;
664
665 paned = g_object_get_data(G_OBJECT(vwin->vbox), "paned");
666
667 if (paned != NULL) {
668 /* currently in split-view mode: so rejoin */
669 vertical = GTK_IS_HPANED(paned);
670 viewer_close_pane(vwin);
671 gtk_widget_set_sensitive(hb, TRUE);
672 if (vb != NULL) {
673 gtk_widget_set_sensitive(vb, TRUE);
674 }
675 if (vertical) {
676 gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(vb),
677 GRETL_STOCK_SPLIT_V);
678 } else {
679 gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(hb),
680 GRETL_STOCK_SPLIT_H);
681 }
682 }
683 }
684 }
685
toggle_alpha_spin(GtkToggleButton * b,GtkWidget * w)686 static void toggle_alpha_spin (GtkToggleButton *b, GtkWidget *w)
687 {
688 gtk_widget_set_sensitive(w, gtk_toggle_button_get_active(b));
689 }
690
coeffint_set_alpha(GtkWidget * w,windata_t * vwin)691 static void coeffint_set_alpha (GtkWidget *w, windata_t *vwin)
692 {
693 CoeffIntervals *cf = vwin->data;
694 GtkWidget *dialog, *tmp, *hbox;
695 GtkWidget *vbox, *b, *hb2;
696 GSList *group = NULL;
697 GtkAdjustment *adj;
698 gchar txt[16];
699 double x = 1.0 - cf->alpha;
700 gboolean defset = FALSE;
701 int i;
702
703 if (maybe_raise_dialog()) {
704 return;
705 }
706
707 dialog = gretl_dialog_new(_("gretl: coefficient confidence intervals"),
708 vwin_toplevel(vwin), GRETL_DLG_BLOCK);
709
710 hbox = gtk_hbox_new(FALSE, 5);
711 hb2 = gtk_hbox_new(FALSE, 5);
712 tmp = gtk_label_new(_("Confidence level"));
713 gtk_box_pack_start(GTK_BOX(hb2), tmp, FALSE, FALSE, 0);
714
715 tmp = gtk_label_new("1 - α :");
716 gtk_box_pack_start(GTK_BOX(hb2), tmp, FALSE, FALSE, 0);
717 gtk_box_pack_start(GTK_BOX(hbox), hb2, TRUE, TRUE, 10);
718 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
719 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
720
721 hbox = gtk_hbox_new(FALSE, 5);
722 vbox = gtk_vbox_new(FALSE, 5);
723
724 /* radio button for 90%, 95%, 99% confidence */
725
726 for (i=0; i<3; i++) {
727 double a = (i == 0)? 0.90 : (i == 1)? 0.95 : 0.99;
728
729 sprintf(txt, "%.2f", a);
730 b = gtk_radio_button_new_with_label(group, txt);
731 gtk_box_pack_start(GTK_BOX(vbox), b, FALSE, FALSE, 0);
732 group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(b));
733 if (a == x) {
734 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b), TRUE);
735 defset = TRUE;
736 } else {
737 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b), FALSE);
738 }
739 g_object_set_data(G_OBJECT(b), "i", GINT_TO_POINTER(i));
740 g_signal_connect(G_OBJECT(b), "toggled",
741 G_CALLBACK(alpha_button_callback),
742 &x);
743 }
744
745 /* radio button for "other" confidence level, plus spinner */
746
747 hb2 = gtk_hbox_new(FALSE, 0);
748 b = gtk_radio_button_new_with_label(group, _("Other"));
749 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b), !defset);
750 gtk_box_pack_start(GTK_BOX(hb2), b, FALSE, FALSE, 0);
751 adj = (GtkAdjustment *) gtk_adjustment_new(x, 0.60, 0.99, 0.01, 0, 0);
752 tmp = gtk_spin_button_new(GTK_ADJUSTMENT(adj), 0.01, 2);
753 g_signal_connect(G_OBJECT(tmp), "value-changed",
754 G_CALLBACK(set_double_from_spinner), &x);
755 gtk_widget_set_sensitive(tmp, !defset);
756 g_signal_connect(G_OBJECT(b), "toggled",
757 G_CALLBACK(toggle_alpha_spin),
758 tmp);
759 gtk_entry_set_activates_default(GTK_ENTRY(tmp), TRUE);
760 gtk_box_pack_start(GTK_BOX(hb2), tmp, FALSE, FALSE, 5);
761 gtk_box_pack_start(GTK_BOX(vbox), hb2, FALSE, FALSE, 0);
762
763 gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 10);
764
765 vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
766 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
767
768 hbox = gtk_dialog_get_action_area(GTK_DIALOG(dialog));
769
770 /* Cancel button */
771 cancel_delete_button(hbox, dialog);
772
773 g_object_set_data(G_OBJECT(dialog), "vwin", vwin);
774 g_object_set_data(G_OBJECT(dialog), "xptr", &x);
775
776 /* "OK" button */
777 tmp = ok_button(hbox);
778 g_signal_connect(G_OBJECT(tmp), "clicked",
779 G_CALLBACK(real_coeffint_set_alpha), dialog);
780 gtk_widget_grab_default(tmp);
781
782 gtk_widget_show_all(dialog);
783 }
784
stickiness_callback(GtkWidget * w,windata_t * vwin)785 static void stickiness_callback (GtkWidget *w, windata_t *vwin)
786 {
787 output_policy_dialog(vwin, vwin, 1);
788 }
789
do_corr_plot(windata_t * vwin)790 static void do_corr_plot (windata_t *vwin)
791 {
792 VMatrix *corr = vwin->data;
793 int err;
794
795 err = plot_corrmat(corr, OPT_NONE);
796 gui_graph_handler(err);
797 }
798
toolbar_plot_callback(GtkWidget * w,windata_t * vwin)799 static void toolbar_plot_callback (GtkWidget *w, windata_t *vwin)
800 {
801 if (vwin->role == VIEW_SERIES) {
802 series_view_graph(w, vwin);
803 } else if (vwin->role == VIEW_BUNDLE) {
804 exec_bundle_special_function(vwin->data, BUNDLE_PLOT,
805 NULL, vwin->main);
806 } else if (vwin->role == CORR) {
807 do_corr_plot(vwin);
808 } else if (vwin->role == VIEW_DBNOMICS) {
809 show_dbnomics_data(vwin, 1);
810 } else {
811 do_nonparam_plot(vwin);
812 }
813 }
814
toolbar_fcast_callback(GtkWidget * w,windata_t * vwin)815 static void toolbar_fcast_callback (GtkWidget *w, windata_t *vwin)
816 {
817 if (vwin->role == VIEW_BUNDLE) {
818 exec_bundle_special_function(vwin->data, BUNDLE_FCAST,
819 NULL, vwin->main);
820 }
821 }
822
dbnomics_show_series(GtkWidget * w,windata_t * vwin)823 static void dbnomics_show_series (GtkWidget *w, windata_t *vwin)
824 {
825 show_dbnomics_data(vwin, 0);
826 }
827
editor_prefs_callback(GtkWidget * w,windata_t * vwin)828 static void editor_prefs_callback (GtkWidget *w, windata_t *vwin)
829 {
830 if (vwin->role == CONSOLE) {
831 console_prefs_dialog(vwin->main);
832 } else {
833 preferences_dialog(TAB_EDITOR, NULL, vwin_toplevel(vwin));
834 }
835 }
836
build_pkg_callback(GtkWidget * w,windata_t * vwin)837 static void build_pkg_callback (GtkWidget *w, windata_t *vwin)
838 {
839 if (vwin_content_changed(vwin)) {
840 int resp;
841
842 resp = yes_no_cancel_dialog("gretl", _("Save changes?"),
843 vwin->main);
844 if (resp == GRETL_CANCEL) {
845 return;
846 }
847 if (resp == GRETL_YES) {
848 vwin_save_callback(NULL, vwin);
849 }
850 }
851
852 build_package_from_spec_file(vwin);
853 }
854
bundle_plot_ok(windata_t * vwin)855 static int bundle_plot_ok (windata_t *vwin)
856 {
857 gretl_bundle *b = vwin->data;
858 gchar *pf = get_bundle_special_function(b, BUNDLE_PLOT);
859 int ret = 0;
860
861 if (pf != NULL) {
862 ret = 1;
863 g_free(pf);
864 }
865
866 return ret;
867 }
868
bundle_fcast_ok(windata_t * vwin)869 static int bundle_fcast_ok (windata_t *vwin)
870 {
871 gretl_bundle *b = vwin->data;
872 gchar *ff = get_bundle_special_function(b, BUNDLE_FCAST);
873 int ret = 0;
874
875 if (ff != NULL) {
876 ret = 1;
877 g_free(ff);
878 }
879
880 return ret;
881 }
882
suppress_hmap(VMatrix * corr)883 static int suppress_hmap (VMatrix *corr)
884 {
885 return corr->dim < 3;
886 }
887
activate_script_help(GtkWidget * widget,windata_t * vwin)888 static void activate_script_help (GtkWidget *widget, windata_t *vwin)
889 {
890 text_set_cursor(vwin->text, GDK_QUESTION_ARROW);
891 set_window_help_active(vwin);
892 }
893
edit_script_popup_item(GretlToolItem * item)894 static int edit_script_popup_item (GretlToolItem *item)
895 {
896 if (item->icon == NULL) return 0;
897
898 return !strcmp(item->icon, GTK_STOCK_COPY) ||
899 !strcmp(item->icon, GTK_STOCK_PASTE) ||
900 !strcmp(item->icon, GTK_STOCK_FIND) ||
901 !strcmp(item->icon, GTK_STOCK_UNDO) ||
902 !strcmp(item->icon, GTK_STOCK_FIND_AND_REPLACE);
903 }
904
set_plot_icon(GretlToolItem * item,int role)905 static void set_plot_icon (GretlToolItem *item, int role)
906 {
907 if (role == LOESS || role == NADARWAT || role == VIEW_BUNDLE) {
908 item->icon = GRETL_STOCK_SCATTER;
909 } else if (role == VIEW_SERIES && dataset_is_cross_section(dataset)) {
910 item->icon = GRETL_STOCK_BOX;
911 } /* else stay with the default, a time series plot icon */
912 }
913
vwin_cut_callback(GtkWidget * w,windata_t * vwin)914 static void vwin_cut_callback (GtkWidget *w, windata_t *vwin)
915 {
916 gtk_text_buffer_cut_clipboard(gtk_text_view_get_buffer(GTK_TEXT_VIEW(vwin->text)),
917 gtk_clipboard_get(GDK_NONE),
918 TRUE);
919 }
920
921 static GretlToolItem viewbar_items[] = {
922 { N_("New window"), GTK_STOCK_NEW, G_CALLBACK(toolbar_new_callback), NEW_ITEM },
923 { N_("Open..."), GTK_STOCK_OPEN, G_CALLBACK(file_open_callback), OPEN_ITEM },
924 { N_("Save"), GTK_STOCK_SAVE, G_CALLBACK(vwin_save_callback), SAVE_ITEM },
925 { N_("Save as..."), GTK_STOCK_SAVE_AS, G_CALLBACK(save_as_callback), SAVE_AS_ITEM },
926 { N_("Open in script editor"), GTK_STOCK_EDIT, G_CALLBACK(copy_to_editor), COPY_SCRIPT_ITEM },
927 { N_("Save bundle content..."), GRETL_STOCK_BUNDLE, NULL, BUNDLE_ITEM },
928 { N_("Print..."), GTK_STOCK_PRINT, G_CALLBACK(window_print_callback), PRINT_ITEM },
929 { N_("Show/hide"), GRETL_STOCK_PIN, G_CALLBACK(session_notes_callback), NOTES_ITEM },
930 { N_("Display values"), GTK_STOCK_MEDIA_PLAY, G_CALLBACK(dbnomics_show_series), DBN_ITEM },
931 { N_("Run"), GTK_STOCK_EXECUTE, G_CALLBACK(do_run_script), EXEC_ITEM },
932 { N_("Build package"), GRETL_STOCK_TOOLS, G_CALLBACK(build_pkg_callback), BUILD_ITEM },
933 { N_("Cut"), GTK_STOCK_CUT, G_CALLBACK(vwin_cut_callback), EDIT_ITEM },
934 { N_("Copy"), GTK_STOCK_COPY, G_CALLBACK(vwin_copy_callback), COPY_ITEM },
935 { N_("Paste"), GTK_STOCK_PASTE, G_CALLBACK(text_paste), EDIT_ITEM },
936 { N_("Find..."), GTK_STOCK_FIND, G_CALLBACK(text_find), FIND_ITEM },
937 { N_("Replace..."), GTK_STOCK_FIND_AND_REPLACE, G_CALLBACK(text_replace), EDIT_ITEM },
938 { N_("Undo"), GTK_STOCK_UNDO, G_CALLBACK(text_undo), EDIT_ITEM },
939 { N_("Redo"), GTK_STOCK_REDO, G_CALLBACK(text_redo), EDIT_ITEM },
940 { N_("Sort"), GTK_STOCK_SORT_ASCENDING, G_CALLBACK(series_view_toggle_sort), SORT_ITEM },
941 { N_("Sort by..."), GTK_STOCK_SORT_ASCENDING, G_CALLBACK(multi_series_view_sort_by), SORT_BY_ITEM },
942 { N_("Preferences..."), GTK_STOCK_PREFERENCES, G_CALLBACK(editor_prefs_callback), EDIT_HANSL_ITEM },
943 { N_("Auto-indent script"), GTK_STOCK_INDENT, G_CALLBACK(indent_hansl), EDIT_HANSL_ITEM },
944 { N_("Send To..."), GRETL_STOCK_MAIL, G_CALLBACK(mail_script_callback), MAIL_ITEM },
945 { N_("Scripts index"), GTK_STOCK_INDEX, G_CALLBACK(script_index), INDEX_ITEM },
946 { N_("Confidence level..."), GRETL_STOCK_ALPHA, G_CALLBACK(coeffint_set_alpha), ALPHA_ITEM },
947 { N_("LaTeX"), GRETL_STOCK_TEX, G_CALLBACK(window_tex_callback), TEX_ITEM },
948 { N_("Graph"), GRETL_STOCK_TS, G_CALLBACK(toolbar_plot_callback), PLOT_ITEM },
949 { N_("Forecast"), GRETL_STOCK_FCAST, G_CALLBACK(toolbar_fcast_callback), FCAST_ITEM },
950 { N_("Heatmap"), GRETL_STOCK_HMAP, G_CALLBACK(toolbar_plot_callback), HMAP_ITEM },
951 { N_("Reformat..."), GTK_STOCK_CONVERT, G_CALLBACK(reformat_callback), FORMAT_ITEM },
952 { N_("Edit values..."), GTK_STOCK_EDIT, G_CALLBACK(series_view_edit), EDITOR_ITEM },
953 { N_("Refresh"), GTK_STOCK_REFRESH, G_CALLBACK(toolbar_refresh), REFRESH_ITEM },
954 { N_("Add to dataset..."), GTK_STOCK_ADD, G_CALLBACK(add_data_callback), ADD_DATA_ITEM },
955 { N_("Add as matrix..."), GTK_STOCK_ADD, G_CALLBACK(add_matrix_callback), ADD_MATRIX_ITEM },
956 { N_("Stickiness..."), GRETL_STOCK_PIN, G_CALLBACK(stickiness_callback), STICKIFY_ITEM },
957 { N_("Toggle split pane"), GRETL_STOCK_SPLIT_H, G_CALLBACK(split_pane_callback), SPLIT_H_ITEM },
958 { N_("Toggle split pane"), GRETL_STOCK_SPLIT_V, G_CALLBACK(split_pane_callback), SPLIT_V_ITEM },
959 { N_("Help on command"), GRETL_STOCK_QUERY, G_CALLBACK(activate_script_help), CMD_HELP_ITEM },
960 { N_("Help"), GTK_STOCK_HELP, G_CALLBACK(window_help), HELP_ITEM },
961 { N_("Help"), GTK_STOCK_HELP, G_CALLBACK(display_gnuplot_help), GP_HELP_ITEM },
962 { N_("Help"), GTK_STOCK_HELP, G_CALLBACK(display_x12a_help), X12A_HELP_ITEM },
963 { N_("Digits..."), NULL, G_CALLBACK(NULL), DIGITS_ITEM }
964 };
965
966 static int n_viewbar_items = G_N_ELEMENTS(viewbar_items);
967
968 #define exec_ok(r) (vwin_editing_script(r) || \
969 r == VIEW_SCRIPT || \
970 r == VIEW_PKG_SAMPLE || \
971 r == EDIT_PKG_SAMPLE)
972
973 #define open_ok(r) (vwin_editing_script(r))
974
975 #define new_ok(r) (vwin_editing_script(r))
976
977 #define edit_ok(r) (vwin_editing_script(r) || \
978 vwin_editing_buffer(r) || \
979 r == EDIT_PKG_CODE || \
980 r == EDIT_PKG_SAMPLE || \
981 r == EDIT_PKG_HELP || \
982 r == EDIT_PKG_GHLP)
983
984 #define save_as_ok(r) (r != EDIT_HEADER && \
985 r != EDIT_NOTES && \
986 r != EDIT_PKG_CODE && \
987 r != EDIT_PKG_SAMPLE && \
988 r != CONSOLE && \
989 r != VIEW_BUNDLE && \
990 r != VIEW_DBNOMICS)
991
992 #define help_ok(r) (r == LEVERAGE || \
993 r == COINT2 || \
994 r == HURST || \
995 r == RMPLOT || \
996 r == MAHAL)
997
998 #define cmd_help_ok(r) (r == EDIT_HANSL || \
999 r == EDIT_PKG_CODE || \
1000 r == EDIT_PKG_SAMPLE || \
1001 r == VIEW_PKG_SAMPLE || \
1002 r == VIEW_PKG_CODE || \
1003 r == VIEW_SCRIPT || \
1004 r == VIEW_LOG || \
1005 r == CONSOLE)
1006
1007 /* for a non-editable script: can offer option to copy
1008 content into an editor window */
1009 #define copy_script_ok(r) (r == VIEW_PKG_SAMPLE || \
1010 r == VIEW_PKG_CODE || \
1011 r == VIEW_SCRIPT || \
1012 r == VIEW_LOG)
1013
1014 #define sort_ok(r) (r == VIEW_SERIES)
1015
1016 #define plot_ok(r) (r == VIEW_SERIES || \
1017 r == LOESS || \
1018 r == NADARWAT || \
1019 r == VIEW_DBNOMICS)
1020
1021 #define add_data_ok(r) (r == PCA || r == LEVERAGE || \
1022 r == MAHAL || r == FCAST || \
1023 r == LOESS || r == NADARWAT || \
1024 r == VIEW_DBNOMICS)
1025
1026 #define split_h_ok(r) (r == SCRIPT_OUT || r == FNCALL_OUT || \
1027 r == VIEW_LOG || r == VIEW_PKG_CODE || \
1028 r == VIEW_BUNDLE || vwin_editing_script(r))
1029
1030 #define split_v_ok(r) (r == SCRIPT_OUT || r == FNCALL_OUT)
1031
1032 /* Screen out unwanted menu items depending on the context; also
1033 adjust the callbacks associated with some items based on
1034 context.
1035 */
1036
tool_item_get_callback(GretlToolItem * item,windata_t * vwin,int latex_ok,int sortby_ok,int format_ok,int save_ok)1037 static GCallback tool_item_get_callback (GretlToolItem *item, windata_t *vwin,
1038 int latex_ok, int sortby_ok,
1039 int format_ok, int save_ok)
1040 {
1041 static int mail_ok = -1;
1042 GCallback func = item->func;
1043 int f = item->flag;
1044 int r = vwin->role;
1045
1046 if (mail_ok < 0) {
1047 mail_ok = curl_does_smtp();
1048 }
1049
1050 if (r == EDIT_SPEC) {
1051 /* This is a "special" that should maybe be regularized:
1052 a bit like editing a script, but different...
1053 */
1054 if (f == NEW_ITEM || f == OPEN_ITEM || f == EXEC_ITEM) {
1055 return NULL;
1056 }
1057 } else if (f == BUILD_ITEM) {
1058 return NULL;
1059 }
1060
1061 /* popup use only */
1062 if (f == DIGITS_ITEM) {
1063 return NULL;
1064 }
1065
1066 if (use_toolbar_search_box(r) && f == FIND_ITEM) {
1067 /* using an "inline" search box: skip the
1068 "Find" button */
1069 return NULL;
1070 }
1071
1072 if (r == VIEW_DBNOMICS) {
1073 if (f == PRINT_ITEM || f == FIND_ITEM) {
1074 return NULL;
1075 }
1076 } else if (f == DBN_ITEM) {
1077 return NULL;
1078 }
1079
1080 if (copy_script_ok(r)) {
1081 if (f == SAVE_AS_ITEM) {
1082 return NULL;
1083 }
1084 } else if (f == COPY_SCRIPT_ITEM) {
1085 return NULL;
1086 }
1087
1088 if (r == EDIT_PKG_SAMPLE && f == OPEN_ITEM) {
1089 return G_CALLBACK(open_pkg_sample);
1090 } else if (!edit_ok(r) && f == EDIT_ITEM) {
1091 return NULL;
1092 } else if (!open_ok(r) && f == OPEN_ITEM) {
1093 return NULL;
1094 } else if (!new_ok(r) && f == NEW_ITEM) {
1095 return NULL;
1096 } else if (!exec_ok(r) && f == EXEC_ITEM) {
1097 return NULL;
1098 } else if (!cmd_help_ok(r) && f == CMD_HELP_ITEM) {
1099 return NULL;
1100 } else if ((!mail_ok || r != EDIT_HANSL) && f == MAIL_ITEM) {
1101 return NULL;
1102 } else if (!help_ok(r) && f == HELP_ITEM) {
1103 return NULL;
1104 } else if ((!latex_ok || !multiple_formats_ok(vwin)) && f == TEX_ITEM) {
1105 return NULL;
1106 } else if (!add_data_ok(r) && f == ADD_DATA_ITEM) {
1107 return NULL;
1108 } else if (r != XTAB && f == ADD_MATRIX_ITEM) {
1109 return NULL;
1110 } else if (!sort_ok(r) && f == SORT_ITEM) {
1111 return NULL;
1112 } else if (!sortby_ok && f == SORT_BY_ITEM) {
1113 return NULL;
1114 } else if (!plot_ok(r) && f == PLOT_ITEM) {
1115 if (r == VIEW_BUNDLE && bundle_plot_ok(vwin)) {
1116 ; /* alright then */
1117 } else {
1118 return NULL;
1119 }
1120 } else if (f == FCAST_ITEM) {
1121 if (r == VIEW_BUNDLE && bundle_fcast_ok(vwin)) {
1122 ; /* alright then */
1123 } else {
1124 return NULL;
1125 }
1126 } else if (!split_h_ok(r) && f == SPLIT_H_ITEM) {
1127 return NULL;
1128 } else if (!split_v_ok(r) && f == SPLIT_V_ITEM) {
1129 return NULL;
1130 } else if (!format_ok && f == FORMAT_ITEM) {
1131 return NULL;
1132 } else if (r != VIEW_SERIES && f == EDITOR_ITEM) {
1133 return NULL;
1134 } else if (r == CONSOLE && func == G_CALLBACK(editor_prefs_callback)) {
1135 ; /* alright then */
1136 } else if (r != EDIT_HANSL && r != EDIT_PKG_CODE &&
1137 r != EDIT_PKG_SAMPLE && f == EDIT_HANSL_ITEM) {
1138 return NULL;
1139 } else if (r != VIEW_SCRIPT && f == INDEX_ITEM) {
1140 return NULL;
1141 } else if (r != SCRIPT_OUT && f == STICKIFY_ITEM) {
1142 return NULL;
1143 } else if (r != COEFFINT && f == ALPHA_ITEM) {
1144 return NULL;
1145 } else if (r != VIEW_SERIES && f == REFRESH_ITEM) {
1146 return NULL;
1147 } else if (r != EDIT_GP && f == GP_HELP_ITEM) {
1148 return NULL;
1149 } else if (r != EDIT_X12A && f == X12A_HELP_ITEM) {
1150 return NULL;
1151 } else if (f == SAVE_ITEM && !save_ok) {
1152 return NULL;
1153 } else if (r != EDIT_NOTES && f == NOTES_ITEM) {
1154 return NULL;
1155 } else if (r != VIEW_BUNDLE && r != VIEW_DBNOMICS && f == BUNDLE_ITEM) {
1156 return NULL;
1157 } else if (f == HMAP_ITEM) {
1158 if (r != CORR) {
1159 return NULL;
1160 } else if (suppress_hmap(vwin->data)) {
1161 return NULL;
1162 }
1163 } else if (f == SAVE_AS_ITEM) {
1164 if (!save_as_ok(r) || (vwin->flags & VWIN_NO_SAVE)) {
1165 return NULL;
1166 } else if (multiple_formats_ok(vwin) ||
1167 (vwin->flags & VWIN_MULTI_SERIES)) {
1168 func = G_CALLBACK(multi_save_as_callback);
1169 }
1170 }
1171
1172 return func;
1173 }
1174
fcast_save_call(GtkAction * action,gpointer p)1175 static void fcast_save_call (GtkAction *action, gpointer p)
1176 {
1177 const char *s = gtk_action_get_name(action);
1178 ModelDataIndex idx;
1179
1180 idx = (strcmp(s, "SaveSderr") == 0)? M_FCSE : M_FCAST;
1181
1182 add_fcast_data((windata_t *) p, idx);
1183 }
1184
make_fcast_save_menu(windata_t * vwin)1185 static GtkWidget *make_fcast_save_menu (windata_t *vwin)
1186 {
1187 GtkWidget *menu = gtk_menu_new();
1188 GtkAction *action;
1189 GtkWidget *item;
1190 int i;
1191
1192 for (i=0; i<2; i++) {
1193 action = gtk_action_new(i == 0 ? "SaveFcast" : "SaveSderr",
1194 i == 0 ? _("_Save forecast...") :
1195 _("Save standard errors..."),
1196 NULL, NULL);
1197 g_signal_connect(G_OBJECT(action), "activate",
1198 G_CALLBACK(fcast_save_call), vwin);
1199 item = gtk_action_create_menu_item(action);
1200 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1201 }
1202
1203 return menu;
1204 }
1205
tool_item_get_menu(GretlToolItem * item,windata_t * vwin)1206 static GtkWidget *tool_item_get_menu (GretlToolItem *item, windata_t *vwin)
1207 {
1208 GtkWidget *menu = NULL;
1209
1210 if (vwin->role == VIEW_BUNDLE) {
1211 if (item->flag == BUNDLE_ITEM) {
1212 menu = make_bundle_content_menu(vwin);
1213 } else if (item->flag == PLOT_ITEM) {
1214 menu = make_bundle_plot_menu(vwin);
1215 } else if (item->flag == SAVE_ITEM) {
1216 menu = make_bundle_save_menu(vwin);
1217 if (menu != NULL) {
1218 item->tip = N_("Save...");
1219 }
1220 }
1221 } else if (vwin->role == VIEW_DBNOMICS) {
1222 if (item->flag == BUNDLE_ITEM) {
1223 menu = make_bundle_content_menu(vwin);
1224 } else if (item->flag == SAVE_ITEM) {
1225 menu = make_bundle_save_menu(vwin);
1226 if (menu != NULL) {
1227 item->tip = N_("Save...");
1228 }
1229 }
1230 } else if (vwin->role == FCAST && item->flag == ADD_DATA_ITEM) {
1231 FITRESID *fr = vwin->data;
1232
1233 if (fr->sderr != NULL) {
1234 menu = make_fcast_save_menu(vwin);
1235 }
1236 }
1237
1238 if (menu != NULL) {
1239 /* don't leak: record pointer to menu so it can
1240 be destroyed when the window is closed */
1241 vwin_record_toolbar_popup(vwin, menu);
1242 }
1243
1244 return menu;
1245 }
1246
gretl_toolbar_flat(GtkWidget * w)1247 static void gretl_toolbar_flat (GtkWidget *w)
1248 {
1249 static int style_done;
1250
1251 gtk_widget_set_name(w, "gretl_toolbar");
1252
1253 if (!style_done) {
1254 gtk_rc_parse_string("style \"gretl-tb-style\"\n{\n"
1255 " GtkToolbar::shadow-type = GTK_SHADOW_NONE\n"
1256 "}\n"
1257 "widget \"*.gretl_toolbar\" style \"gretl-tb-style\"");
1258 style_done = 1;
1259 }
1260 }
1261
gretl_toolbar_new(GtkWidget * sibling)1262 GtkWidget *gretl_toolbar_new (GtkWidget *sibling)
1263 {
1264 GtkWidget *tb = gtk_toolbar_new();
1265
1266 gtk_toolbar_set_icon_size(GTK_TOOLBAR(tb), toolbar_icon_size);
1267 gtk_toolbar_set_style(GTK_TOOLBAR(tb), GTK_TOOLBAR_ICONS);
1268 gtk_toolbar_set_show_arrow(GTK_TOOLBAR(tb), FALSE);
1269
1270 if (sibling == NULL) {
1271 /* if we're not alongside a menu bar ("sibling"),
1272 show the toolbar without a shadow
1273 */
1274 gretl_toolbar_flat(tb);
1275 }
1276
1277 return tb;
1278 }
1279
gretl_tooltips_add(GtkWidget * w,const gchar * str)1280 void gretl_tooltips_add (GtkWidget *w, const gchar *str)
1281 {
1282 gtk_widget_set_tooltip_text(w, str);
1283 }
1284
gretl_menu_button(const char * icon,const char * tip,GtkWidget ** pw)1285 static GtkToolItem *gretl_menu_button (const char *icon,
1286 const char *tip,
1287 GtkWidget **pw)
1288 {
1289 GtkWidget *img, *button = gtk_button_new();
1290 GtkToolItem *item = gtk_tool_item_new();
1291
1292 gtk_widget_set_tooltip_text(GTK_WIDGET(item), _(tip));
1293 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
1294 img = gtk_image_new_from_stock(icon, toolbar_icon_size /* GTK_ICON_SIZE_MENU */);
1295 gtk_container_add(GTK_CONTAINER(button), img);
1296 gtk_container_add(GTK_CONTAINER(item), button);
1297 *pw = button;
1298
1299 return item;
1300 }
1301
gretl_tool_item_set_tip(GtkWidget * item,GretlToolItem * tool)1302 static void gretl_tool_item_set_tip (GtkWidget *item,
1303 GretlToolItem *tool)
1304 {
1305 const char *accel = NULL;
1306
1307 if (tool->flag == EXEC_ITEM) {
1308 accel = "Ctrl+R";
1309 } else if (tool->flag == COPY_ITEM) {
1310 accel = "Ctrl+C";
1311 } else if (tool->flag == SAVE_ITEM) {
1312 accel = "Ctrl+S";
1313 } else if (tool->flag == FIND_ITEM) {
1314 accel = "Ctrl+F";
1315 } else if (!strcmp(tool->icon, GTK_STOCK_FIND_AND_REPLACE)) {
1316 accel = "Ctrl+H";
1317 }
1318
1319 if (accel != NULL) {
1320 gchar *s = g_strdup_printf("%s (%s)", _(tool->tip), accel);
1321
1322 gtk_widget_set_tooltip_text(item, s);
1323 g_free(s);
1324 } else {
1325 gtk_widget_set_tooltip_text(item, _(tool->tip));
1326 }
1327 }
1328
gretl_toolbar_insert(GtkWidget * tbar,GretlToolItem * tool,GCallback func,gpointer data,gint pos)1329 GtkWidget *gretl_toolbar_insert (GtkWidget *tbar,
1330 GretlToolItem *tool,
1331 GCallback func,
1332 gpointer data,
1333 gint pos)
1334 {
1335 GtkToolItem *item;
1336
1337 item = gtk_tool_button_new_from_stock(tool->icon);
1338 gretl_tool_item_set_tip(GTK_WIDGET(item), tool);
1339 g_signal_connect(G_OBJECT(item), "clicked", func, data);
1340 gtk_widget_set_size_request(GTK_WIDGET(item), 30, -1);
1341 gtk_toolbar_insert(GTK_TOOLBAR(tbar), item, pos);
1342
1343 return GTK_WIDGET(item);
1344 }
1345
button_menu_pos(GtkMenu * menu,gint * x,gint * y,gboolean * push_in,gpointer data)1346 static void button_menu_pos (GtkMenu *menu,
1347 gint *x,
1348 gint *y,
1349 gboolean *push_in,
1350 gpointer data)
1351 {
1352 GtkWidget *button = data;
1353 gint wx, wy, tx, ty;
1354
1355 gdk_window_get_origin(gtk_widget_get_window(button), &wx, &wy);
1356 gtk_widget_translate_coordinates(button, gtk_widget_get_toplevel(button),
1357 0, 0, &tx, &ty);
1358 *x = wx + tx;
1359 *y = wy + ty + 26;
1360 *push_in = TRUE;
1361 }
1362
tool_item_popup(GtkWidget * button,GdkEvent * event,GtkWidget * menu)1363 static void tool_item_popup (GtkWidget *button, GdkEvent *event,
1364 GtkWidget *menu)
1365 {
1366 gtk_menu_popup(GTK_MENU(menu), NULL, NULL,
1367 button_menu_pos, button,
1368 event->button.button, event->button.time);
1369 }
1370
1371 /* right-click action for exec button */
1372
exec_press(GtkWidget * w,GdkEventButton * eb,windata_t * vwin)1373 static gint exec_press (GtkWidget *w, GdkEventButton *eb, windata_t *vwin)
1374 {
1375 if (eb->button == 3) {
1376 run_script_silent(NULL, vwin);
1377 return TRUE;
1378 } else {
1379 return FALSE;
1380 }
1381 }
1382
vwin_toolbar_insert(GretlToolItem * tool,GCallback func,GtkWidget * menu,windata_t * vwin,gint pos)1383 GtkWidget *vwin_toolbar_insert (GretlToolItem *tool,
1384 GCallback func,
1385 GtkWidget *menu,
1386 windata_t *vwin,
1387 gint pos)
1388 {
1389 GtkToolItem *item;
1390
1391 if (menu != NULL) {
1392 /* make and insert a button that pops down a menu */
1393 GtkWidget *button;
1394
1395 item = gretl_menu_button(tool->icon, tool->tip, &button);
1396 g_signal_connect(G_OBJECT(button), "button-press-event",
1397 G_CALLBACK(tool_item_popup), menu);
1398 } else {
1399 /* make and insert a regular callback button */
1400 item = gtk_tool_button_new_from_stock(tool->icon);
1401 g_signal_connect(G_OBJECT(item), "clicked", func, vwin);
1402 if (tool->flag == NEW_ITEM && window_is_tab(vwin)) {
1403 gtk_widget_set_tooltip_text(GTK_WIDGET(item), _("New tab"));
1404 } else {
1405 gretl_tool_item_set_tip(GTK_WIDGET(item), tool);
1406 if (tool->flag == EXEC_ITEM) {
1407 g_signal_connect(G_OBJECT(item), "button-press-event",
1408 G_CALLBACK(exec_press), vwin);
1409 }
1410 }
1411 }
1412
1413 gtk_toolbar_insert(GTK_TOOLBAR(vwin->mbar), item, pos);
1414
1415 return GTK_WIDGET(item);
1416 }
1417
viewbar_add_items(windata_t * vwin,ViewbarFlags flags)1418 static void viewbar_add_items (windata_t *vwin, ViewbarFlags flags)
1419 {
1420 int sortby_ok = has_sortable_data(vwin);
1421 int format_ok = can_format_data(vwin);
1422 int latex_ok = latex_is_ok();
1423 int save_ok = (flags & VIEWBAR_EDITABLE);
1424 GtkWidget *hpane = NULL, *vpane = NULL;
1425 GtkWidget *button;
1426 GtkWidget *menu;
1427 GretlToolItem *item;
1428 GCallback func;
1429 int i;
1430
1431 for (i=0; i<n_viewbar_items; i++) {
1432 func = NULL;
1433 menu = NULL;
1434 item = &viewbar_items[i];
1435
1436 /* Is there anything to hook up, in context? We
1437 try first for a menu to attach to the toolbar
1438 button; failing that we test for a "direct"
1439 callback function.
1440 */
1441 menu = tool_item_get_menu(item, vwin);
1442 if (menu == NULL && item->func != NULL) {
1443 func = tool_item_get_callback(item, vwin, latex_ok, sortby_ok,
1444 format_ok, save_ok);
1445 }
1446 if (func == NULL && menu == NULL) {
1447 /* nothing to hook up */
1448 continue;
1449 }
1450
1451 if (item->flag == PLOT_ITEM) {
1452 set_plot_icon(item, vwin->role);
1453 }
1454
1455 button = vwin_toolbar_insert(item, func, menu, vwin, -1);
1456
1457 if (func == (GCallback) split_pane_callback) {
1458 if (hpane == NULL) {
1459 hpane = button;
1460 } else {
1461 vpane = button;
1462 }
1463 }
1464
1465 if (item->flag == SAVE_ITEM) {
1466 if (vwin->role != CONSOLE &&
1467 vwin->role != VIEW_BUNDLE &&
1468 vwin->role != VIEW_DBNOMICS) {
1469 /* nothing to save just yet */
1470 g_object_set_data(G_OBJECT(vwin->mbar), "save_button", button);
1471 gtk_widget_set_sensitive(button, FALSE);
1472 }
1473 } else if (item->flag == SAVE_AS_ITEM) {
1474 g_object_set_data(G_OBJECT(vwin->mbar), "save_as_button", button);
1475 if (strstr(vwin->fname, "script_tmp")) {
1476 gtk_widget_set_sensitive(button, FALSE);
1477 }
1478 }
1479 }
1480
1481 if (hpane != NULL) {
1482 g_object_set_data(G_OBJECT(hpane), "vpane", vpane);
1483 }
1484
1485 if (vpane != NULL) {
1486 g_object_set_data(G_OBJECT(vpane), "hpane", hpane);
1487 }
1488 }
1489
vwin_add_viewbar(windata_t * vwin,ViewbarFlags flags)1490 void vwin_add_viewbar (windata_t *vwin, ViewbarFlags flags)
1491 {
1492 if ((flags & VIEWBAR_HAS_TEXT) || vwin->role == SCRIPT_OUT) {
1493 g_object_set_data(G_OBJECT(vwin->main), "text_out",
1494 GINT_TO_POINTER(1));
1495 }
1496
1497 vwin->mbar = gretl_toolbar_new(NULL);
1498 viewbar_add_items(vwin, flags);
1499 vwin_pack_toolbar(vwin);
1500 }
1501
build_text_popup(windata_t * vwin)1502 GtkWidget *build_text_popup (windata_t *vwin)
1503 {
1504 GtkWidget *pmenu = gtk_menu_new();
1505 GretlToolItem *item;
1506 GCallback func;
1507 GtkWidget *w;
1508 int i;
1509
1510 for (i=0; i<n_viewbar_items; i++) {
1511 item = &viewbar_items[i];
1512 func = G_CALLBACK(NULL);
1513 if (item->flag == SPLIT_H_ITEM || item->flag == SPLIT_V_ITEM) {
1514 continue;
1515 } else if (item->flag == DIGITS_ITEM &&
1516 (vwin->role == VIEW_MODEL || vwin->role == SUMMARY)) {
1517 func = G_CALLBACK(display_digits_callback);
1518 } else if (vwin->role == EDIT_HANSL) {
1519 /* the script editor popup may have some special stuff
1520 added: don't clutter it up */
1521 if (edit_script_popup_item(item)) {
1522 func = item->func;
1523 } else {
1524 func = NULL;
1525 }
1526 } else {
1527 func = tool_item_get_callback(item, vwin, 0, 0, 0, 0);
1528 }
1529 if (func != G_CALLBACK(NULL)) {
1530 if (func == G_CALLBACK(text_paste)) {
1531 GtkClipboard *cb = gtk_clipboard_get(GDK_NONE);
1532
1533 if (!gtk_clipboard_wait_is_text_available(cb)) {
1534 continue;
1535 }
1536 } else if (func == G_CALLBACK(text_undo) && !text_can_undo(vwin)) {
1537 continue;
1538 }
1539 w = gtk_menu_item_new_with_label(_(item->tip));
1540 g_signal_connect(G_OBJECT(w), "activate", func, vwin);
1541 gtk_widget_show(w);
1542 gtk_menu_shell_append(GTK_MENU_SHELL(pmenu), w);
1543 }
1544 }
1545
1546 if (vwin->role != EDIT_HANSL) {
1547 if (window_is_undockable(vwin)) {
1548 add_undock_popup_item(pmenu, vwin);
1549 } else if (window_is_dockable(vwin)) {
1550 add_dock_popup_item(pmenu, vwin);
1551 }
1552 }
1553
1554 return pmenu;
1555 }
1556
1557 /* callbacks for main-window toolbar icons */
1558
tbar_calc(void)1559 static void tbar_calc (void)
1560 {
1561 #ifdef G_OS_WIN32
1562 win32_run_async(calculator, NULL);
1563 #else
1564 gretl_fork("calculator", NULL, NULL);
1565 #endif
1566 }
1567
tbar_open_data(void)1568 static void tbar_open_data (void)
1569 {
1570 display_files(TEXTBOOK_DATA, NULL);
1571 }
1572
tbar_command_ref(void)1573 static void tbar_command_ref (void)
1574 {
1575 display_text_help(NULL);
1576 }
1577
tbar_xy_graph(void)1578 static void tbar_xy_graph (void)
1579 {
1580 if (data_status) {
1581 if (dataset->v == 2) {
1582 do_graph_var(mdata->active_var);
1583 } else if (mdata_selection_count() == 2) {
1584 plot_from_selection(GR_XY);
1585 } else {
1586 selection_dialog(GR_XY, _("gretl: define graph"),
1587 NULL, do_graph_from_selector);
1588 }
1589 } else {
1590 warnbox(_("Please open a data file first"));
1591 }
1592 }
1593
tbar_model(void)1594 static void tbar_model (void)
1595 {
1596 if (data_status) {
1597 selection_dialog(OLS, _("gretl: specify model"), NULL, do_model);
1598 } else {
1599 warnbox(_("Please open a data file first"));
1600 }
1601 }
1602
tbar_new_script(void)1603 static void tbar_new_script (void)
1604 {
1605 do_new_script(EDIT_HANSL, NULL);
1606 }
1607
tbar_show_funcs(GtkWidget * w,gpointer p)1608 static void tbar_show_funcs (GtkWidget *w, gpointer p)
1609 {
1610 display_files(FUNC_FILES, NULL);
1611 }
1612
1613 /* end toolbar icon callbacks */
1614
1615 static GretlToolItem mainbar_items[] = {
1616 { N_("launch calculator"), GRETL_STOCK_CALC, G_CALLBACK(tbar_calc), 0 },
1617 { N_("new script"), GTK_STOCK_EDIT, G_CALLBACK(tbar_new_script), 0 },
1618 { N_("open gretl console"), GRETL_STOCK_CONSOLE, G_CALLBACK(gretl_console), 1 },
1619 { N_("session icon view"), GRETL_STOCK_ICONS, G_CALLBACK(view_session), 0 },
1620 { N_("function packages"), GRETL_STOCK_FUNC, G_CALLBACK(tbar_show_funcs), 0 },
1621 { N_("command reference"), GTK_STOCK_HELP, G_CALLBACK(tbar_command_ref), 0 },
1622 { N_("find series"), GTK_STOCK_FIND, G_CALLBACK(listbox_find), 0 },
1623 { N_("X-Y graph"), GRETL_STOCK_SCATTER, G_CALLBACK(tbar_xy_graph), 0 },
1624 { N_("OLS model"), GRETL_STOCK_MODEL, G_CALLBACK(tbar_model), 0 },
1625 { N_("databases"), GRETL_STOCK_DB, G_CALLBACK(show_native_dbs), 0 },
1626 { N_("open dataset"), GTK_STOCK_OPEN, G_CALLBACK(tbar_open_data), 0 },
1627 };
1628
add_mainwin_toolbar(GtkWidget * vbox)1629 void add_mainwin_toolbar (GtkWidget *vbox)
1630 {
1631 GretlToolItem *item;
1632 GtkWidget *hbox;
1633 int i, n = G_N_ELEMENTS(mainbar_items);
1634
1635 mdata->mbar = gretl_toolbar_new(NULL);
1636
1637 for (i=0; i<n; i++) {
1638 item = &mainbar_items[i];
1639 if (swallow && item->flag) {
1640 continue;
1641 }
1642 gretl_toolbar_insert(mdata->mbar, item, item->func, mdata, -1);
1643 }
1644
1645 hbox = gtk_hbox_new(FALSE, 0);
1646 gtk_box_pack_start(GTK_BOX(hbox), mdata->mbar, FALSE, FALSE, 0);
1647 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
1648 }
1649
1650 /* Add a temporary menubar for use in a script output
1651 window, while we're waiting for the output. If the
1652 output window is being reused this is a bit more
1653 complicated; we have to "hide" the regular menubar
1654 before inserting the temporary one.
1655 */
1656
vwin_add_tmpbar(windata_t * vwin)1657 void vwin_add_tmpbar (windata_t *vwin)
1658 {
1659 GretlToolItem item = {
1660 N_("Stop"),
1661 GTK_STOCK_STOP,
1662 G_CALLBACK(do_stop_script),
1663 0
1664 };
1665 GtkWidget *hbox, *tmp;
1666
1667 hbox = g_object_get_data(G_OBJECT(vwin->main), "top-hbox");
1668
1669 if (hbox != NULL) {
1670 /* We're replacing a "real" menubar temporarily: ref. the
1671 widgets in @hbox before removing them so we can put
1672 them back later.
1673 */
1674 GtkWidget *winlist = g_object_get_data(G_OBJECT(hbox), "winlist");
1675
1676 g_object_ref(G_OBJECT(vwin->mbar));
1677 gtk_container_remove(GTK_CONTAINER(hbox), vwin->mbar);
1678 if (vwin->finder != NULL) {
1679 g_object_ref(G_OBJECT(vwin->finder));
1680 gtk_container_remove(GTK_CONTAINER(hbox), vwin->finder);
1681 }
1682 if (winlist != NULL) {
1683 g_object_ref(G_OBJECT(winlist));
1684 gtk_container_remove(GTK_CONTAINER(hbox), winlist);
1685 }
1686 } else {
1687 /* starting from scratch */
1688 hbox = gtk_hbox_new(FALSE, 0);
1689 g_object_set_data(G_OBJECT(vwin->main), "top-hbox", hbox);
1690 gtk_box_pack_start(GTK_BOX(vwin->vbox), hbox, FALSE, FALSE, 0);
1691 }
1692
1693 tmp = gretl_toolbar_new(NULL);
1694 gretl_toolbar_insert(tmp, &item, item.func, NULL, 0);
1695 gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 5);
1696
1697 start_wait_for_output(vwin, hbox);
1698 gtk_widget_show_all(hbox);
1699 }
1700