/* * Copyright (c) by Allin Cottrell * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* dlgutils.c for gretl: utilities for composing dialog boxes */ #include "gretl.h" #include "textbuf.h" #include "menustate.h" #include "dlgutils.h" #include "system.h" void vbox_add_hsep (GtkWidget *vbox) { GtkWidget *h = gtk_hseparator_new(); gtk_box_pack_start(GTK_BOX(vbox), h, FALSE, FALSE, 0); gtk_widget_show(h); } /* Various buttons, usable in several sorts of dialogs */ GtkWidget *context_help_button (GtkWidget *hbox, int cmdcode) { GtkWidget *w; w = gtk_button_new_from_stock(GTK_STOCK_HELP); GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT); gtk_container_add(GTK_CONTAINER(hbox), w); gtk_button_box_set_child_secondary(GTK_BUTTON_BOX(hbox), w, TRUE); if (cmdcode >= 0) { g_signal_connect(G_OBJECT(w), "clicked", G_CALLBACK(context_help), GINT_TO_POINTER(cmdcode)); } gtk_widget_show(w); return w; } static void set_canceled (GtkWidget *w, int *c) { if (c != NULL) *c = 1; } GtkWidget *cancel_delete_button (GtkWidget *hbox, GtkWidget *targ, int *canceled) { GtkWidget *w; w = gtk_button_new_from_stock(GTK_STOCK_CANCEL); GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT); gtk_box_pack_start(GTK_BOX(hbox), w, TRUE, TRUE, 0); if (canceled != NULL) { g_signal_connect(G_OBJECT(w), "clicked", G_CALLBACK(set_canceled), canceled); } g_signal_connect(G_OBJECT(w), "clicked", G_CALLBACK(delete_widget), targ); gtk_widget_show(w); return w; } static void opt_invalid (GtkWidget *w, int *opt) { *opt = -1; } static void maybe_opt_invalid (GtkDialog *d, int resp, int *opt) { if (resp == GTK_RESPONSE_NONE || resp == GTK_RESPONSE_DELETE_EVENT) { *opt = -1; } } GtkWidget *cancel_options_button (GtkWidget *hbox, GtkWidget *targ, int *opt) { GtkWidget *w = gtk_button_new_from_stock(GTK_STOCK_CANCEL); GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT); gtk_box_pack_start(GTK_BOX(hbox), w, TRUE, TRUE, 0); if (opt != NULL) { g_signal_connect(G_OBJECT(w), "clicked", G_CALLBACK(opt_invalid), opt); g_signal_connect(GTK_DIALOG(targ), "response", G_CALLBACK(maybe_opt_invalid), opt); } g_signal_connect(G_OBJECT(w), "clicked", G_CALLBACK(delete_widget), targ); gtk_widget_show(w); return w; } GtkWidget *ok_button (GtkWidget *hbox) { GtkWidget *w; w = gtk_button_new_from_stock(GTK_STOCK_OK); GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT); gtk_container_add(GTK_CONTAINER(hbox), w); return w; } GtkWidget *apply_button (GtkWidget *hbox) { GtkWidget *w; w = gtk_button_new_from_stock(GTK_STOCK_APPLY); GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT); gtk_container_add(GTK_CONTAINER(hbox), w); return w; } GtkWidget *cancel_button (GtkWidget *hbox) { GtkWidget *w; w = gtk_button_new_from_stock(GTK_STOCK_CANCEL); GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT); gtk_container_add(GTK_CONTAINER(hbox), w); return w; } GtkWidget *next_button (GtkWidget *hbox) { GtkWidget *w; w = gtk_button_new_from_stock(GTK_STOCK_GO_FORWARD); GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT); gtk_container_add(GTK_CONTAINER(hbox), w); return w; } GtkWidget *back_button (GtkWidget *hbox) { GtkWidget *w; w = gtk_button_new_from_stock(GTK_STOCK_GO_BACK); GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT); gtk_container_add(GTK_CONTAINER(hbox), w); return w; } static void set_dialog_border_widths (GtkWidget *dlg) { int w1 = 10, w2 = 5; gtk_container_set_border_width(GTK_CONTAINER (GTK_DIALOG(dlg)->vbox), w1); gtk_container_set_border_width(GTK_CONTAINER (GTK_DIALOG(dlg)->action_area), w2); gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dlg)->vbox), w2); } static void gretl_dialog_set_resizeable (GtkWidget *w, gboolean s) { gtk_window_set_resizable(GTK_WINDOW(w), s); } static GtkWidget *current_dialog; int maybe_raise_dialog (void) { int ret = 0; if (current_dialog != NULL) { gdk_window_raise(current_dialog->window); ret = 1; } return ret; } static gint dialog_unblock (GtkWidget *w, gpointer p) { gtk_main_quit(); current_dialog = NULL; return FALSE; } static gint dialog_set_destruction (GtkWidget *w, gpointer p) { gtk_window_set_transient_for(GTK_WINDOW(w), GTK_WINDOW(p)); gtk_window_set_destroy_with_parent(GTK_WINDOW(w), TRUE); return FALSE; } GtkWidget *gretl_dialog_new (const char *title, GtkWidget *parent, unsigned char flags) { GtkWidget *d = gtk_dialog_new(); if (title != NULL) { gtk_window_set_title(GTK_WINDOW(d), title); } gtk_button_box_set_layout(GTK_BUTTON_BOX(GTK_DIALOG(d)->action_area), GTK_BUTTONBOX_END); set_dialog_border_widths(d); gtk_window_set_position(GTK_WINDOW(d), GTK_WIN_POS_MOUSE); if (flags & GRETL_DLG_BLOCK) { current_dialog = d; } if (flags & GRETL_DLG_MODAL) { gretl_set_window_modal(d); } if (!(flags & GRETL_DLG_RESIZE)) { gretl_dialog_set_resizeable(d, FALSE); } if (flags & GRETL_DLG_BLOCK) { g_signal_connect(G_OBJECT(d), "destroy", G_CALLBACK(dialog_unblock), NULL); } if (parent != NULL) { g_signal_connect(G_OBJECT(d), "show", G_CALLBACK(dialog_set_destruction), parent); } if (flags & GRETL_DLG_BLOCK) { g_signal_connect(G_OBJECT(d), "show", G_CALLBACK(gtk_main), NULL); } return d; } /* "edit dialog" apparatus */ GtkWidget *active_edit_id; GtkWidget *active_edit_name; GtkWidget *active_edit_text; struct dialog_t_ { GtkWidget *dialog; GtkWidget *edit; GtkWidget *popup; gpointer data; gint code; gint blocking; gretlopt opt; }; static GtkWidget *open_edit_dialog; static void destroy_dialog_data (GtkWidget *w, gpointer data) { dialog_t *d = (dialog_t *) data; if (d->blocking) { gtk_main_quit(); } g_free(d); open_edit_dialog = NULL; if (active_edit_id) active_edit_id = NULL; if (active_edit_name) active_edit_name = NULL; if (active_edit_text) active_edit_text = NULL; } static void cancel_on_delete (GtkDialog *d, int resp, int *c) { if (resp == GTK_RESPONSE_NONE || resp == GTK_RESPONSE_DELETE_EVENT) { *c = 1; } } static dialog_t * dialog_data_new (gpointer p, gint code, const char *title, int *canceled) { dialog_t *d = mymalloc(sizeof *d); if (d == NULL) { return NULL; } d->data = p; d->code = code; d->opt = OPT_NONE; d->dialog = gtk_dialog_new(); d->popup = NULL; if (canceled != NULL) { g_signal_connect(G_OBJECT(d->dialog), "delete_event", G_CALLBACK(cancel_on_delete), canceled); d->blocking = 1; } else { d->blocking = 0; } gtk_window_set_title(GTK_WINDOW(d->dialog), title); gtk_box_set_homogeneous(GTK_BOX (GTK_DIALOG(d->dialog)->action_area), TRUE); gtk_window_set_position(GTK_WINDOW(d->dialog), GTK_WIN_POS_MOUSE); g_signal_connect(G_OBJECT(d->dialog), "destroy", G_CALLBACK(destroy_dialog_data), d); return d; } void close_dialog (dialog_t *dlg) { gtk_widget_destroy(dlg->dialog); } /* saved material from "complex" edit dialog */ static int edit_save_code; static char *edit_save_buf; static void edit_save_buf_clear (void) { g_free(edit_save_buf); edit_save_buf = NULL; edit_save_code = 0; } static void set_edit_save_buf (const char *buf, int code) { edit_save_buf_clear(); if (buf != NULL) { edit_save_buf = g_strdup(buf); edit_save_code = code; } } static int dlg_text_set_previous (dialog_t *d) { if (d->code == edit_save_code && edit_save_buf != NULL) { textview_set_text(d->edit, edit_save_buf); return 1; } else { return 0; } } static int dlg_text_set_gmm_skel (dialog_t *d) { const char *skel = "# initializations go here\n\n\n" "gmm\n\n" "orthog\n" "weights\n" "params\n" "end gmm\n"; if (d->code == GMM && edit_save_buf == NULL) { textview_set_text(d->edit, skel); textview_set_cursor_at_line(d->edit, 1); return 1; } else { return 0; } } /* end edit saver apparatus */ gchar *edit_dialog_special_get_text (dialog_t *dlg) { gchar *buf; if (dlg == NULL) { edit_save_buf_clear(); return NULL; } buf = textview_get_text(dlg->edit); if (buf != NULL && *buf == '\0') { /* nothing was entered */ g_free(buf); buf = NULL; } if (buf == NULL) { gtk_widget_destroy(dlg->dialog); } set_edit_save_buf(buf, dlg->code); return buf; } const gchar *edit_dialog_get_text (dialog_t *dlg) { const gchar *buf; buf = gtk_entry_get_text(GTK_ENTRY(dlg->edit)); if (buf == NULL || *buf == '\0') { if (dlg->code != CORRGM && dlg->code != CREATE_DATASET) { gtk_widget_destroy(dlg->dialog); } return NULL; } return buf; } int edit_dialog_get_action (const dialog_t *dlg) { return dlg->code; } gretlopt edit_dialog_get_opt (const dialog_t *dlg) { return dlg->opt; } gpointer edit_dialog_get_data (dialog_t *dlg) { return dlg->data; } static void dialog_table_setup (dialog_t *dlg, int hsize) { GtkWidget *sw; sw = gtk_scrolled_window_new (NULL, NULL); gtk_widget_set_size_request(sw, hsize, 200); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg->dialog)->vbox), sw, TRUE, TRUE, FALSE); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_IN); gtk_container_add(GTK_CONTAINER(sw), dlg->edit); gtk_widget_show(dlg->edit); gtk_widget_show(sw); } static GtkWidget *dlg_text_edit_new (int *hsize, gboolean s) { GtkTextBuffer *tbuf; GtkWidget *tview; tbuf = gtk_text_buffer_new(NULL); tview = gtk_text_view_new_with_buffer(tbuf); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(tview), GTK_WRAP_WORD); gtk_text_view_set_left_margin(GTK_TEXT_VIEW(tview), 4); gtk_text_view_set_right_margin(GTK_TEXT_VIEW(tview), 4); gtk_widget_modify_font(GTK_WIDGET(tview), fixed_font); *hsize *= get_char_width(tview); *hsize += 48; gtk_text_view_set_editable(GTK_TEXT_VIEW(tview), s); gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(tview), s); return tview; } static void dlg_text_set_from_sys (gretl_equation_system *sys, dialog_t *d) { const char *buf; PRN *prn; if (bufopen(&prn)) { return; } print_equation_system_info(sys, datainfo, OPT_NONE, prn); buf = gretl_print_get_buffer(prn); textview_set_text(d->edit, buf); gretl_print_destroy(prn); } enum { ADD_EQN, ADD_DERIV, ADD_IDENT, ADD_ENDO_LIST, ADD_INSTR_LIST }; static int edit_has_list (GtkWidget *w, int i) { gchar *buf; int ret = 0; buf = textview_get_text(w); if (buf != NULL) { if (i == ADD_ENDO_LIST) { if (strstr(buf, "endog ")) ret = 1; } else if (i == ADD_INSTR_LIST) { if (strstr(buf, "instr ")) ret = 1; } g_free(buf); } return ret; } static gint edit_popup_click (GtkWidget *w, dialog_t *d) { gint action = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w), "action")); const char *ins = NULL; if (action == ADD_EQN) { ins = "equation "; } else if (action == ADD_DERIV) { ins = "deriv "; } else if (action == ADD_IDENT) { ins = "identity "; } else if (action == ADD_ENDO_LIST) { ins = "endog "; } else if (action == ADD_INSTR_LIST) { ins = "instr "; } if (ins != NULL) { GtkTextBuffer *tbuf; GtkTextIter pos; tbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(d->edit)); gtk_text_buffer_get_end_iter(tbuf, &pos); gtk_text_buffer_insert(tbuf, &pos, ins, strlen(ins)); } gtk_widget_destroy(d->popup); return FALSE; } static GtkWidget *build_edit_popup (dialog_t *d) { const char *items[] = { N_("Add equation"), N_("Add derivative"), N_("Add identity"), N_("Add list of endogenous variables"), N_("Add list of instruments") }; GtkWidget *menu; GtkWidget *item; int i, n_items = sizeof items / sizeof items[0]; menu = gtk_menu_new(); for (i=0; icode == NLS && (i != ADD_DERIV)) { continue; } else if (d->code == MLE && (i != ADD_DERIV)) { continue; } else if (d->code == SYSTEM) { if (i == ADD_DERIV) continue; if ((i == ADD_ENDO_LIST || i == ADD_INSTR_LIST) && edit_has_list(d->edit, i)) { continue; } } item = gtk_menu_item_new_with_label(_(items[i])); g_object_set_data(G_OBJECT(item), "action", GINT_TO_POINTER(i)); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(edit_popup_click), d); gtk_widget_show(item); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); } return menu; } static gboolean edit_dialog_popup_handler (GtkWidget *w, GdkEventButton *event, dialog_t *d) { GdkModifierType mods; gdk_window_get_pointer(w->window, NULL, NULL, &mods); if (mods & GDK_BUTTON3_MASK) { if (d->popup != NULL) { gtk_widget_destroy(d->popup); d->popup = NULL; } d->popup = build_edit_popup(d); if (d->popup != NULL) { gtk_menu_popup(GTK_MENU(d->popup), NULL, NULL, NULL, NULL, event->button, event->time); gtk_signal_connect(GTK_OBJECT(d->popup), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &d->popup); } return TRUE; } return FALSE; } static void set_replace_restrictions (GtkWidget *w, gpointer p) { dialog_t *d = (dialog_t *) p; if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))) { d->opt = OPT_P; } else { d->opt = OPT_NONE; } } static void sample_replace_buttons (GtkWidget *box, gpointer data) { GtkWidget *tmp; GSList *group; /* add to current sample restriction */ tmp = gtk_radio_button_new_with_label(NULL, _("add to current restriction")); gtk_box_pack_start(GTK_BOX(box), tmp, TRUE, TRUE, 0); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tmp), TRUE); gtk_widget_show(tmp); /* replace current sample restriction */ group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(tmp)); tmp = gtk_radio_button_new_with_label(group, _("replace current restriction")); gtk_box_pack_start(GTK_BOX(box), tmp, TRUE, TRUE, 0); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tmp), FALSE); g_signal_connect(G_OBJECT(tmp), "clicked", G_CALLBACK(set_replace_restrictions), data); gtk_widget_show(tmp); } static void free_sys_strings (GtkWidget *w, char **strs) { free_strings_array(strs, SYS_MAX - 1); } static void set_sys_method (GtkEditable *entry, dialog_t *d) { const gchar *s = gtk_entry_get_text(GTK_ENTRY(entry)); if (*s != '\0') { char mstr[8] = {0}; s = strrchr(s, '('); if (s != NULL) { sscanf(s + 1, "%7[^)]", mstr); d->opt = gretl_system_method_from_string(mstr); } } } static gboolean opt_v_callback (GtkWidget *w, dialog_t *dlg) { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))) { dlg->opt |= OPT_V; } else { dlg->opt &= ~OPT_V; } return FALSE; } static gboolean opt_r_callback (GtkWidget *w, dialog_t *dlg) { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))) { dlg->opt |= OPT_R; } else { dlg->opt &= ~OPT_R; } return FALSE; } static gboolean opt_b_callback (GtkWidget *w, dialog_t *dlg) { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))) { dlg->opt |= OPT_B; } else { dlg->opt &= ~OPT_B; } return FALSE; } static void dialog_option_switch (GtkWidget *vbox, dialog_t *dlg, gretlopt opt) { GtkWidget *b, *hbox; if (opt == OPT_V) { b = gtk_check_button_new_with_label(_("Show details of iterations")); g_signal_connect(G_OBJECT(b), "toggled", G_CALLBACK(opt_v_callback), dlg); } else if (opt == OPT_R) { b = gtk_check_button_new_with_label(_("Robust standard errors")); g_signal_connect(G_OBJECT(b), "toggled", G_CALLBACK(opt_r_callback), dlg); } else if (opt == OPT_B) { b = gtk_check_button_new_with_label(_("Use bootstrap")); g_signal_connect(G_OBJECT(b), "toggled", G_CALLBACK(opt_b_callback), dlg); } else { return; } hbox = gtk_hbox_new(FALSE, 5); gtk_box_pack_start(GTK_BOX(hbox), b, TRUE, TRUE, 5); gtk_widget_show(b); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); gtk_widget_show(hbox); } static void gmm_option_callback (GtkWidget *w, dialog_t *d) { gint i = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w), "i")); if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))) { switch (i) { case 0: d->opt &= ~OPT_T; d->opt &= ~OPT_I; break; case 1: d->opt |= OPT_T; d->opt &= ~OPT_I; break; case 2: d->opt &= ~OPT_T; d->opt |= OPT_I; break; } } } static void build_gmm_radios (GtkWidget *vbox, dialog_t *d) { GtkWidget *b, *hbox; GSList *group = NULL; const char *strs[] = { N_("One-step estimation"), N_("Two-step estimation"), N_("Iterated estimation") }; int i; for (i=0; i<3; i++) { b = gtk_radio_button_new_with_label(group, _(strs[i])); g_object_set_data(G_OBJECT(b), "i", GINT_TO_POINTER(i)); g_signal_connect(G_OBJECT(b), "toggled", G_CALLBACK(gmm_option_callback), d); group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(b)); hbox = gtk_hbox_new(FALSE, 5); gtk_box_pack_start(GTK_BOX(hbox), b, TRUE, TRUE, 5); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); gtk_widget_show_all(hbox); if (i == 0) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b), TRUE); } } } static void system_estimator_list (GtkWidget *vbox, dialog_t *d) { gretl_equation_system *sys = NULL; GList *items = NULL; GtkWidget *w, *hbox; gchar **strs; int method = -1; int i; if (d->data != NULL) { sys = (gretl_equation_system *) d->data; } strs = strings_array_new(SYS_MAX); for (i=SYS_SUR; imethod == i) { method = i; } } hbox = gtk_hbox_new(FALSE, 5); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5); gtk_widget_show(hbox); w = gtk_label_new(_("Estimator")); gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 5); gtk_widget_show(w); w = gtk_combo_new(); gtk_combo_set_popdown_strings(GTK_COMBO(w), items); gtk_editable_set_editable(GTK_EDITABLE(GTK_COMBO(w)->entry), FALSE); g_signal_connect(G_OBJECT(w), "destroy", G_CALLBACK(free_sys_strings), strs); g_signal_connect(G_OBJECT(GTK_COMBO(w)->entry), "changed", G_CALLBACK(set_sys_method), d); if (method >= 0) { gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(w)->entry), strs[method]); } gtk_box_pack_start(GTK_BOX(hbox), w, TRUE, TRUE, 5); gtk_widget_show(w); } static void dlg_display_sys (dialog_t *d) { gretl_equation_system *sys = d->data; GtkWidget *w; int hsize = 62; w = gtk_label_new(sys->name); gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_CENTER); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(d->dialog)->vbox), w, TRUE, TRUE, 10); gtk_widget_show(w); d->edit = dlg_text_edit_new(&hsize, FALSE); dialog_table_setup(d, hsize); dlg_text_set_from_sys(sys, d); } static void raise_and_focus_dialog (GtkEditable *editable, gpointer p) { dialog_t *d = (dialog_t *) p; gdk_window_raise(d->dialog->window); if (!GTK_WIDGET_HAS_FOCUS(d->edit)) { gtk_widget_grab_focus(d->edit); } } static int edit_dialog_help_code (int ci, void *p) { int hc = ci; if (ci == SYSTEM && p != NULL) { hc = 0; } else if (ci == PRINT || ci == CREATE_USERDIR || ci == CREATE_DATASET || ci == MINIBUF) { hc = 0; } else if (ci == RESTRICT) { windata_t *vwin = (windata_t *) p; if (vwin->role == VIEW_MODEL) { hc = MODEL_RESTR; } else if (vwin->role == SYSTEM) { hc = SYS_RESTR; } else if (vwin->role == VECM) { hc = VECM_RESTR; } } return hc; } static void clear_dlg_previous (GtkWidget *w, dialog_t *d) { edit_save_buf_clear(); textview_set_text(d->edit, NULL); } static void edit_dialog_ok (GtkWidget *w, dialog_t *d) { gtk_widget_destroy(d->dialog); } static int ols_model_window (windata_t *vwin) { if (vwin->role == VIEW_MODEL) { MODEL *pmod = (MODEL *) vwin->data; if (pmod->ci == OLS) { return 1; } } return 0; } void edit_dialog (const char *title, const char *info, const char *deflt, void (*okfunc)(), void *okptr, guint cmdcode, guint varclick, int *canceled) { dialog_t *d; GtkWidget *w; GtkWidget *top_vbox, *button_box; int hlpcode, modal = 0; int clear = 0; if (open_edit_dialog != NULL && cmdcode != MINIBUF) { gdk_window_raise(open_edit_dialog->window); return; } d = dialog_data_new(okptr, cmdcode, title, canceled); if (d == NULL) return; open_edit_dialog = d->dialog; set_dialog_border_widths(d->dialog); gretl_dialog_set_resizeable(d->dialog, FALSE); /* convenience pointers */ top_vbox = GTK_DIALOG(d->dialog)->vbox; button_box = GTK_DIALOG(d->dialog)->action_area; gtk_button_box_set_layout(GTK_BUTTON_BOX(button_box), GTK_BUTTONBOX_END); if (cmdcode == SYSTEM && d->data != NULL) { /* revisiting saved equation system */ dlg_display_sys(d); } else if (cmdcode == NLS || cmdcode == MLE || cmdcode == SYSTEM || cmdcode == RESTRICT || cmdcode == GMM) { int hsize = 62; gchar *lbl; lbl = g_strdup_printf("%s\n%s", info, _("(Please refer to Help for guidance)")); w = gtk_label_new(lbl); gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_CENTER); gtk_box_pack_start(GTK_BOX(top_vbox), w, TRUE, TRUE, 10); gtk_widget_show(w); g_free(lbl); d->edit = dlg_text_edit_new(&hsize, TRUE); dialog_table_setup(d, hsize); /* insert previous text, if any and if the command is the same as previously -- or insert skeleton of command */ if (dlg_text_set_previous(d) || dlg_text_set_gmm_skel(d)) { clear = 1; } if (cmdcode != RESTRICT && cmdcode != GMM) { g_signal_connect(G_OBJECT(d->edit), "button_press_event", G_CALLBACK(edit_dialog_popup_handler), d); } } else { if (info != NULL) { w = gtk_label_new(info); gtk_box_pack_start(GTK_BOX(top_vbox), w, TRUE, TRUE, 5); gtk_widget_show(w); } d->edit = gtk_entry_new(); gtk_box_pack_start(GTK_BOX(top_vbox), d->edit, TRUE, TRUE, 5); /* make the Enter key do the business */ if (okfunc != NULL) { g_signal_connect(G_OBJECT(d->edit), "activate", G_CALLBACK(okfunc), d); } if (deflt != NULL && *deflt != '\0') { gtk_entry_set_text(GTK_ENTRY(d->edit), deflt); gtk_editable_select_region(GTK_EDITABLE(d->edit), 0, strlen(deflt)); } gtk_widget_show(d->edit); g_signal_connect(G_OBJECT(GTK_EDITABLE(d->edit)), "changed", G_CALLBACK(raise_and_focus_dialog), d); } if (cmdcode == SMPLBOOL && dataset_is_restricted()) { sample_replace_buttons(top_vbox, d); } else if (cmdcode == SYSTEM) { system_estimator_list(top_vbox, d); } else if (cmdcode == NLS || cmdcode == MLE) { dialog_option_switch(top_vbox, d, OPT_V); dialog_option_switch(top_vbox, d, OPT_R); } else if (cmdcode == GMM) { dialog_option_switch(top_vbox, d, OPT_V); build_gmm_radios(top_vbox, d); } else if (cmdcode == RESTRICT && ols_model_window(okptr)) { dialog_option_switch(top_vbox, d, OPT_B); } if (varclick == VARCLICK_INSERT_ID) { active_edit_id = d->edit; } else if (varclick == VARCLICK_INSERT_NAME) { active_edit_name = d->edit; } else if (varclick == VARCLICK_INSERT_TEXT) { active_edit_text = d->edit; } else if (cmdcode != SYSTEM) { modal = 1; } gtk_widget_grab_focus(d->edit); /* "Clear" button? */ if (clear) { w = gtk_button_new_from_stock(GTK_STOCK_CLEAR); gtk_container_add(GTK_CONTAINER(button_box), w); g_signal_connect(G_OBJECT(w), "clicked", G_CALLBACK(clear_dlg_previous), d); gtk_widget_show(w); } /* "Cancel" button? */ if (cmdcode != CREATE_USERDIR) { cancel_delete_button(button_box, d->dialog, canceled); } /* "OK" button */ w = ok_button(button_box); if (okfunc != NULL) { g_signal_connect(G_OBJECT(w), "clicked", G_CALLBACK(okfunc), d); } else { g_signal_connect(G_OBJECT(w), "clicked", G_CALLBACK(edit_dialog_ok), d); } gtk_widget_grab_default(w); gtk_widget_show(w); /* "Help" button, if wanted */ hlpcode = edit_dialog_help_code(cmdcode, okptr); if (hlpcode > 0) { context_help_button(button_box, hlpcode); modal = 0; } gtk_window_set_destroy_with_parent(GTK_WINDOW(d->dialog), TRUE); gtk_widget_show(d->dialog); if (modal) { gretl_set_window_modal(d->dialog); } if (d->blocking) { gtk_main(); } } char *entry_box_get_trimmed_text (GtkWidget *w) { const gchar *s = gtk_entry_get_text(GTK_ENTRY(w)); char *ret = NULL; int i, len; if (s == NULL || *s == '\0') { return NULL; } while (isspace(*s)) s++; if (*s == '\0') { return NULL; } len = strlen(s); for (i=len-1; i>0; i--) { if (!isspace(s[i])) break; len--; } if (len > 0) { ret = g_strndup(s, len); } return ret; }