Logo Search packages:      
Sourcecode: gretl version File versions  Download package

dlgutils.c

/*
 *  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 = standard_button(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 = standard_button(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 = standard_button(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 = standard_button(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 = standard_button(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 = standard_button(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 = standard_button(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 = standard_button(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();
    }

    if (d->code == GENR_RANDOM) {
      /* pointer to double */
      free(d->data);
    } 

    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 data, gint code, const char *title,
             int *canceled)
{
    dialog_t *d = mymalloc(sizeof *d);

    if (d == NULL) {
      return NULL;
    }

    d->data = data;
    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;
    }
}

/* 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; i<n_items; i++) {
      if (d->code == 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_C;
    } 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 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 {
      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 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; i<SYS_MAX; i++) {
      strs[i] = g_strdup_printf("%s (%s)", _(system_method_full_string(i)),
                          system_method_short_string(i));
      items = g_list_append(items, strs[i]);
      if (sys != NULL && sys->method == 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);
}

void edit_dialog (const char *diagtxt, const char *infotxt, const char *deftext, 
              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, diagtxt, 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) {
      int hsize = 62;
      gchar *lbl;

      lbl = g_strdup_printf("%s\n%s", infotxt,
                        _("(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 */
      if (dlg_text_set_previous(d)) {
          clear = 1;
      }

      if (cmdcode != RESTRICT) {
          g_signal_connect(G_OBJECT(d->edit), "button_press_event", 
                       G_CALLBACK(edit_dialog_popup_handler), d);
      }
    } else {
      if (infotxt != NULL) {
          w = gtk_label_new(infotxt);
          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 (deftext != NULL && *deftext != '\0') {
          gtk_entry_set_text(GTK_ENTRY(d->edit), deftext);
          gtk_editable_select_region(GTK_EDITABLE(d->edit), 0, strlen(deftext));
      } 

      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);
    } 

    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;
}


Generated by  Doxygen 1.6.0   Back to index