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

fnsave.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.
 *
 */

#include "gretl.h"
#include "dlgutils.h"
#include "textbuf.h"
#include "fileselect.h"
#include "webget.h"
#include "fnsave.h"

#ifdef G_OS_WIN32
# include "gretlwin32.h"
#endif

#include "gretl_func.h"

#define NENTRIES 4

typedef struct function_info_ function_info;
typedef struct login_info_ login_info;

struct function_info_ {
    GtkWidget *dlg;
    GtkWidget *entries[NENTRIES];
    GtkWidget *text;
    GtkWidget *ifsel;
    GtkWidget *codesel;
    GtkWidget *check;
    fnpkg *pkg;
    char *fname;
    char *author;
    char *version;
    char *date;
    char *pkgdesc;
    char **help;
    int *publist;
    int *privlist;
    int n_public;
    int iface;
    FuncDataReq dreq;
    float minver;
    int upload;
    int saveas;
};

struct login_info_ {
    GtkWidget *dlg;
    GtkWidget *login_entry;
    GtkWidget *pass_entry;
    char *login;
    char *pass;
    int canceled;
};

function_info *finfo_new (void)
{
    function_info *finfo;

    finfo = mymalloc(sizeof *finfo);
    if (finfo == NULL) {
      return NULL;
    }

    finfo->pkg = NULL;
    finfo->fname = NULL;
    finfo->author = NULL;
    finfo->version = NULL;
    finfo->date = NULL;
    finfo->pkgdesc = NULL;
    finfo->upload = 0;
    finfo->saveas = 0;
    finfo->iface = -1;

    finfo->n_public = 0;
    finfo->help = NULL;
    finfo->publist = NULL;
    finfo->privlist = NULL;
    finfo->dreq = 0;
    finfo->minver = 1.5;

    return finfo;
}

static int finfo_init (function_info *finfo)
{
    finfo->n_public = finfo->publist[0];

    finfo->help = strings_array_new(finfo->n_public);
    if (finfo->help == NULL) {
      nomem();
      return E_ALLOC;
    }

    return 0;
}

static void finfo_free (function_info *finfo)
{
    free(finfo->fname);
    free(finfo->author);
    free(finfo->version);
    free(finfo->date);
    free(finfo->pkgdesc);
    free(finfo->publist);
    free(finfo->privlist);

    free_strings_array(finfo->help, finfo->n_public);

    free(finfo);
}

static void login_init_or_free (login_info *linfo, int freeit)
{
    static char *login;
    static char *pass;

    if (freeit) {
      if (!linfo->canceled) {
          free(login);
          free(pass);
          login = g_strdup(linfo->login);
          pass = g_strdup(linfo->pass);
      }
      free(linfo->login);
      free(linfo->pass);
    } else {
      linfo->login = (login == NULL)? NULL : g_strdup(login);
      linfo->pass = (pass == NULL)? NULL : g_strdup(pass);
      linfo->canceled = 0;
    }
}

static void login_init (login_info *linfo)
{
    login_init_or_free(linfo, 0);
}

static void linfo_free (login_info *linfo)
{
    login_init_or_free(linfo, 1);
}

static char *trim_text (const char *s)
{
    char *ret = NULL;
    int i, len;

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

static int help_text_index (function_info *finfo)
{
    int i;

    i = gtk_option_menu_get_history(GTK_OPTION_MENU(finfo->ifsel));
    return finfo->publist[i+1];
}

static void login_finalize (GtkWidget *w, login_info *linfo)
{
    linfo->login = entry_box_get_trimmed_text(linfo->login_entry);
    linfo->pass = entry_box_get_trimmed_text(linfo->pass_entry);

    gtk_widget_destroy(linfo->dlg);
}

static void real_finfo_save (function_info *finfo)
{
    char **fields[] = {
      &finfo->author,
      &finfo->version,
      &finfo->date,
      &finfo->pkgdesc
    };
    int i, hidx = 0;
    int err = 0;

    for (i=0; i<NENTRIES && !err; i++) {
      free(*fields[i]);
      *fields[i] = entry_box_get_trimmed_text(finfo->entries[i]);
      if (*fields[i] == NULL) {
          err = 1;
      }
    }

    if (err) {
      errbox(_("Some required information is missing"));
      return;
    }

    finfo->upload = 
      gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(finfo->check));

    if (finfo->n_public > 1) {
      hidx = help_text_index(finfo);
    } 

    if (hidx >= 0) {
      char *tmp = textview_get_text(finfo->text);

      finfo->help[hidx] = trim_text(tmp);
      free(tmp);
    }

    if (finfo->saveas) {
      file_selector(_("Save function package"), SAVE_FUNCTIONS, 
                  FSEL_DATA_MISC, finfo);
    } else {
      save_user_functions(finfo->fname, finfo);
    }
}

static void finfo_save_as (GtkWidget *w, function_info *finfo)
{
    finfo->saveas = 1;
    real_finfo_save(finfo);
}

static void finfo_save (GtkWidget *w, function_info *finfo)
{
    finfo->saveas = (finfo->fname == NULL);

    real_finfo_save(finfo);
}

static void finfo_destroy (GtkWidget *w, function_info *finfo)
{
    finfo_free(finfo);
}

static void login_cancel (GtkWidget *w, login_info *linfo)
{
    linfo->canceled = 1;
    gtk_widget_destroy(linfo->dlg);
}

enum {
    HIDX_INIT,
    HIDX_SWITCH
};

static void 
set_dialog_info_from_fn (function_info *finfo, int idx, int code)
{
    const char *attrib = NULL;
    const char *keys[] = {
      "author",
      "version",
      "date",
      "pkgdesc"
    };
    const char *etxt;

    static int old_hidx;
    int i, new_hidx;

    if (code == HIDX_INIT) {
      old_hidx = new_hidx = 0;
    } else {
      new_hidx = help_text_index(finfo);
    }

    for (i=0; i<NENTRIES; i++) {
      etxt = gtk_entry_get_text(GTK_ENTRY(finfo->entries[i]));
      if (*etxt == '\0') {
          gretl_function_get_info(idx, keys[i], &attrib);
          if (attrib != NULL) {
            etxt = gtk_entry_get_text(GTK_ENTRY(finfo->entries[i]));
          }
      }
    }

    if (new_hidx != old_hidx) {
      /* we're switching the "active" interface, so save the 
         help text for the previous interface */
      char *old_help = textview_get_text(finfo->text);

      free(finfo->help[old_hidx]);
      finfo->help[old_hidx] = old_help;
    }

    if (code == HIDX_INIT || new_hidx != old_hidx) {
      /* initializing or switching: insert new help text */
      const char *new_help;

      gretl_function_get_info(idx, "help", &new_help);
      textview_set_text(finfo->text, new_help);
    }

    old_hidx = new_hidx;
}

static gboolean update_public (GtkOptionMenu *menu, 
                         function_info *finfo)
{
    int i = gtk_option_menu_get_history(menu);

    set_dialog_info_from_fn(finfo, finfo->publist[i+1], HIDX_SWITCH);

    return FALSE;
}

static gboolean update_iface (GtkOptionMenu *menu, 
                        function_info *finfo)
{
    int i = gtk_option_menu_get_history(menu);

    if (i < finfo->publist[0]) {
      finfo->iface = finfo->publist[i+1];
    } else {
      i -= finfo->publist[0];
      finfo->iface = finfo->privlist[i+1];
    }

    return FALSE;
}

static void edit_code_callback (GtkWidget *w, function_info *finfo)
{
    windata_t *vwin;
    GtkWidget *orig;
    const char *funname;
    GQuark q;
    PRN *prn = NULL;

    if (finfo->iface < 0) {
      return;
    }

    funname = user_function_name_by_index(finfo->iface);
    q = g_quark_from_string(funname);

    orig = match_window_by_data(GINT_TO_POINTER(q));
    if (orig != NULL) {
      gtk_window_present(GTK_WINDOW(orig));
      return;
    }

    if (bufopen(&prn)) {
      return;
    }

    gretl_function_print_code(finfo->iface, prn);

    vwin = view_buffer(prn, 78, 350, funname,
                   EDIT_FUNC_CODE, GINT_TO_POINTER(q));

    if (vwin != NULL) {
      build_path(vwin->fname, paths.userdir, "pkgedit", NULL);
      gretl_tempname(vwin->fname);
      g_object_set_data(G_OBJECT(vwin->w), "iface", 
                    GINT_TO_POINTER(finfo->iface));
    }
}

static GtkWidget *label_hbox (GtkWidget *w, const char *txt)
{
    GtkWidget *hbox, *label;

    hbox = gtk_hbox_new(FALSE, 5);
    gtk_box_pack_start(GTK_BOX(w), hbox, FALSE, FALSE, 0);

    label = gtk_label_new(txt);
    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
    gtk_widget_show(label);

    return hbox;
}

enum {
    REGULAR_BUTTON,
    CHECK_BUTTON
};

static GtkWidget *button_in_hbox (GtkWidget *w, int btype, const char *txt)
{
    GtkWidget *hbox, *button;

    hbox = gtk_hbox_new(FALSE, 5);
    gtk_box_pack_start(GTK_BOX(w), hbox, FALSE, FALSE, 0);
    if (btype == CHECK_BUTTON) {
      button = gtk_check_button_new_with_label(txt);
    } else {
      button = gtk_button_new_with_label(txt);
    }
    gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5);
    gtk_widget_show(button);
    gtk_widget_show(hbox);

    return button;
}

enum {
    IFACE_PUBLIC,
    IFACE_ALL
};

static GtkWidget *interface_selector (function_info *finfo, int iface)
{
    GtkWidget *ifmenu, *menu, *tmp;
    const char *fnname;
    int i;

    finfo->iface = finfo->publist[1];

    ifmenu = gtk_option_menu_new();
    menu = gtk_menu_new();

    for (i=1; i<=finfo->publist[0]; i++) {
      fnname = user_function_name_by_index(finfo->publist[i]);
      tmp = gtk_menu_item_new_with_label(fnname);
      gtk_menu_shell_append(GTK_MENU_SHELL(menu), tmp);
    }

    if (iface == IFACE_ALL && finfo->privlist != NULL) {
      for (i=1; i<=finfo->privlist[0]; i++) {
          fnname = user_function_name_by_index(finfo->privlist[i]);
          tmp = gtk_menu_item_new_with_label(fnname);
          gtk_menu_shell_append(GTK_MENU_SHELL(menu), tmp);
      }
    } 

    gtk_option_menu_set_menu(GTK_OPTION_MENU(ifmenu), menu);
    gtk_widget_show_all(ifmenu);

    return ifmenu;
}

static void dreq_select (GtkOptionMenu *menu, function_info *finfo)
{
    finfo->dreq = gtk_option_menu_get_history(menu);
}

static void add_data_requirement_menu (GtkWidget *tbl, int i, 
                               function_info *finfo)
{
    const char *datareq[] = {
      N_("No special requirement"),
      N_("Time-series data"),
      N_("Quarterly or monthly data"),
      N_("Panel data")
    };
    GtkWidget *menu, *datamenu, *tmp;
    int j;

    tmp = gtk_label_new(_("Data requirement"));
    gtk_table_attach_defaults(GTK_TABLE(tbl), tmp, 0, 1, i, i+1);
    gtk_widget_show(tmp);

    datamenu = gtk_option_menu_new();
    menu = gtk_menu_new();
    for (j=0; j<=FN_NEEDS_PANEL; j++) {
      tmp = gtk_menu_item_new_with_label(_(datareq[j]));
      gtk_menu_shell_append(GTK_MENU_SHELL(menu), tmp);
    }
    gtk_option_menu_set_menu(GTK_OPTION_MENU(datamenu), menu);
    gtk_option_menu_set_history(GTK_OPTION_MENU(datamenu), finfo->dreq);

    tmp = gtk_hbox_new(FALSE, 0);
    gtk_box_pack_start(GTK_BOX(tmp), datamenu, FALSE, FALSE, 0);
    gtk_table_attach_defaults(GTK_TABLE(tbl), tmp, 1, 2, i, i+1);
    gtk_widget_show_all(tmp);

    g_signal_connect(G_OBJECT(datamenu), "changed",
                 G_CALLBACK(dreq_select), finfo);
}

static void get_maj_min_pl (float minver, int *maj, int *min, int *pl)
{
    char vstr[5], minstr[2], plstr[2];

    gretl_push_c_numeric_locale();
    sprintf(vstr, "%.2f", (double) minver);
    gretl_pop_c_numeric_locale();

    sscanf(vstr, "%d.%1s%1s", maj, minstr, plstr);
    *min = atoi(minstr);
    *pl = atoi(plstr);
}

static void adjust_minver (GtkWidget *w, function_info *finfo)
{
    int val = (int) gtk_spin_button_get_value(GTK_SPIN_BUTTON(w));
    int lev = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w), "level"));
    int maj, min, pl;

    get_maj_min_pl(finfo->minver, &maj, &min, &pl);

    if (lev == 1) {
      finfo->minver = (float) val + min / 10.0 + pl / 100.0;
    } else if (lev == 2) {
      finfo->minver = (float) maj + val / 10.0 + pl / 100.0;
    } else if (lev == 3) {
      finfo->minver = (float) maj + min / 10.0 + val / 100.0;
    }
}

static void add_minver_selector (GtkWidget *tbl, int i, 
                         function_info *finfo)
{
    GtkWidget *tmp, *spin, *hbox;
    int maj, min, pl;

    get_maj_min_pl(finfo->minver, &maj, &min, &pl);

    tmp = gtk_label_new(_("Minimum gretl version"));
    gtk_table_attach_defaults(GTK_TABLE(tbl), tmp, 0, 1, i, i+1);
    gtk_widget_show(tmp);

    hbox = gtk_hbox_new(FALSE, 0);

    spin = gtk_spin_button_new_with_range(1, 3, 1);
    if (maj > 1) {
      gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin), (double) maj);
    }
    gtk_box_pack_start(GTK_BOX(hbox), spin, FALSE, FALSE, 2);
    g_object_set_data(G_OBJECT(spin), "level", GINT_TO_POINTER(1));
    g_signal_connect(G_OBJECT(spin), "value-changed",
                 G_CALLBACK(adjust_minver), finfo);
    tmp = gtk_label_new(".");
    gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 2);

    spin = gtk_spin_button_new_with_range(0, 9, 1);
    if (min > 0) {
      gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin), (double) min);
    }
    gtk_box_pack_start(GTK_BOX(hbox), spin, FALSE, FALSE, 2);
    g_object_set_data(G_OBJECT(spin), "level", GINT_TO_POINTER(2));
    g_signal_connect(G_OBJECT(spin), "value-changed",
                 G_CALLBACK(adjust_minver), finfo);
    tmp = gtk_label_new(".");
    gtk_box_pack_start(GTK_BOX(hbox), tmp, FALSE, FALSE, 2);

    spin = gtk_spin_button_new_with_range(0, 9, 1);
    if (pl > 0) {
      gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin), (double) pl);
    }
    gtk_box_pack_start(GTK_BOX(hbox), spin, FALSE, FALSE, 2);
    g_object_set_data(G_OBJECT(spin), "level", GINT_TO_POINTER(3));
    g_signal_connect(G_OBJECT(spin), "value-changed",
                 G_CALLBACK(adjust_minver), finfo);

    gtk_table_attach_defaults(GTK_TABLE(tbl), hbox, 1, 2, i, i+1);
    gtk_widget_show_all(hbox);
}

static void finfo_dialog (function_info *finfo)
{
    GtkWidget *button, *label;
    GtkWidget *tbl, *vbox, *hbox;
    const char *entry_labels[] = {
      N_("Author"),
      N_("Version"),
      N_("Date (YYYY-MM-DD)"),
      N_("Package description")
    };
    char *entry_texts[] = {
      finfo->author,
      finfo->version,
      finfo->date,
      finfo->pkgdesc
    };
    const char *fnname;
    int i;

    if (finfo_init(finfo)) {
      return;
    }

    finfo->dlg = gtk_window_new(GTK_WINDOW_TOPLEVEL);

    g_signal_connect(G_OBJECT(finfo->dlg), "destroy", 
                 G_CALLBACK(finfo_destroy), finfo);

    gtk_window_set_title(GTK_WINDOW(finfo->dlg), 
                   _("gretl: function package editor")); 
    gtk_window_set_default_size(GTK_WINDOW(finfo->dlg), 640, 480);

    vbox = gtk_vbox_new(FALSE, 5);
    gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
    gtk_container_add(GTK_CONTAINER(finfo->dlg), vbox);
    gtk_widget_show(vbox);
                   
    tbl = gtk_table_new(NENTRIES + 1, 2, FALSE);
    gtk_table_set_row_spacings(GTK_TABLE(tbl), 4);
    gtk_box_pack_start(GTK_BOX(vbox), tbl, FALSE, FALSE, 5);

    for (i=0; i<NENTRIES; i++) {
      GtkWidget *entry;

      label = gtk_label_new(_(entry_labels[i]));
      gtk_table_attach_defaults(GTK_TABLE(tbl), label, 0, 1, i, i+1);
      gtk_widget_show(label);

      entry = gtk_entry_new();
      gtk_entry_set_width_chars(GTK_ENTRY(entry), 40);
      gtk_entry_set_editable(GTK_ENTRY(entry), TRUE);
      gtk_table_attach_defaults(GTK_TABLE(tbl), entry, 1, 2, i, i+1);
      gtk_widget_show(entry); 

      finfo->entries[i] = entry;

      if (entry_texts[i] != NULL) {
          gtk_entry_set_text(GTK_ENTRY(entry), entry_texts[i]);
      }

      if (i == 1) {
          gtk_widget_grab_focus(entry);
      }
    }

    add_minver_selector(tbl, i++, finfo);
    add_data_requirement_menu(tbl, i, finfo);
    gtk_widget_show(tbl);

    if (finfo->n_public > 1) {
      /* drop-down selector for public interfaces */
      hbox = label_hbox(vbox, _("Help text for"));
      finfo->ifsel = interface_selector(finfo, IFACE_PUBLIC);
      gtk_box_pack_start(GTK_BOX(hbox), finfo->ifsel, FALSE, FALSE, 5);
      g_signal_connect(G_OBJECT(GTK_OPTION_MENU(finfo->ifsel)), "changed",
                   G_CALLBACK(update_public), finfo);
      gtk_widget_show(hbox);
    } else {
      /* only one public interface */
      gchar *ltxt;

      fnname = user_function_name_by_index(finfo->publist[1]);
      ltxt = g_strdup_printf(_("Help text for %s:"), fnname);
      hbox = label_hbox(vbox, ltxt);
      gtk_widget_show(hbox);
      g_free(ltxt);
    }

    finfo->text = create_text(NULL, -1, -1, TRUE);
    text_table_setup(vbox, finfo->text);

    set_dialog_info_from_fn(finfo, finfo->publist[1], HIDX_INIT);

    /* edit code button, possibly with selector */
    hbox = gtk_hbox_new(FALSE, 5);
    gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);

    button = gtk_button_new_with_label(_("Edit function code"));
    gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5);
    g_signal_connect(G_OBJECT(button), "clicked", 
                 G_CALLBACK(edit_code_callback), finfo);

    if (finfo->publist[0] > 1 || finfo->privlist != NULL) {
      finfo->codesel = interface_selector(finfo, IFACE_ALL);
      gtk_box_pack_start(GTK_BOX(hbox), finfo->codesel, FALSE, FALSE, 5);
      g_signal_connect(G_OBJECT(GTK_OPTION_MENU(finfo->codesel)), "changed",
                   G_CALLBACK(update_iface), finfo);
    } else {
      finfo->iface = finfo->publist[1];
    }

    gtk_widget_show_all(hbox);

    /* check box for upload option */
    finfo->check = button_in_hbox(vbox, CHECK_BUTTON, 
                          _("Upload package to server on save"));

    /* control button area */
    hbox = gtk_hbutton_box_new();
    gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_END);
    gtk_button_box_set_spacing(GTK_BUTTON_BOX(hbox), 10);
    gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);

    /* SaveAs button */
    button = gtk_button_new_from_stock(GTK_STOCK_SAVE_AS);
    GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
    gtk_container_add(GTK_CONTAINER(hbox), button);
    g_signal_connect(G_OBJECT(button), "clicked",
                 G_CALLBACK(finfo_save_as), finfo);

    /* Save button */
    button = gtk_button_new_from_stock(GTK_STOCK_SAVE);
    GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
    gtk_container_add(GTK_CONTAINER(hbox), button);
    g_signal_connect(G_OBJECT(button), "clicked",
                 G_CALLBACK(finfo_save), finfo);
    gtk_widget_grab_default(button);

    /* Close button */
    button = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
    GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
    gtk_container_add(GTK_CONTAINER(hbox), button);
    g_signal_connect(G_OBJECT (button), "clicked", 
                 G_CALLBACK(delete_widget), finfo->dlg);

    gtk_widget_show_all(hbox);

    gtk_widget_show(finfo->dlg);
}

static void web_get_login (GtkWidget *w, gpointer p)
{
    browser_open("http://ricardo.ecn.wfu.edu/gretl/apply/");
}

static void login_dialog (login_info *linfo)
{
    GtkWidget *button, *label;
    GtkWidget *tbl, *hbox;
    int i;

    login_init(linfo);

    linfo->dlg = 
      gretl_dialog_new(_("gretl: upload"), NULL, GRETL_DLG_BLOCK);

    hbox = label_hbox(GTK_DIALOG(linfo->dlg)->vbox, _("Upload function package"));
    gtk_widget_show(hbox);

    tbl = gtk_table_new(2, 2, FALSE);
    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(linfo->dlg)->vbox), tbl, FALSE, FALSE, 5);

    for (i=0; i<2; i++) {
      char *src = (i == 0)? linfo->login : linfo->pass;
      GtkWidget *entry;

      label = gtk_label_new((i == 0)? _("Login") : _("Password"));
      gtk_table_attach(GTK_TABLE(tbl), label, 0, 1, i, i+1,
                   GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
                   5, 5);
      gtk_widget_show(label);

      entry = gtk_entry_new();
      gtk_entry_set_width_chars(GTK_ENTRY(entry), 34);
      gtk_entry_set_editable(GTK_ENTRY(entry), TRUE);
      gtk_table_attach_defaults(GTK_TABLE(tbl), entry, 1, 2, i, i+1);
      if (src != NULL) {
          gtk_entry_set_text(GTK_ENTRY(entry), src);
      }
      gtk_widget_show(entry); 

      if (i == 0) {
          linfo->login_entry = entry;
      } else {
          gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
          linfo->pass_entry = entry;
      }
    }

    gtk_widget_show(tbl);

    hbox = label_hbox(GTK_DIALOG(linfo->dlg)->vbox, 
                  _("If you don't have a login to the gretl server\n"
                  "please see http://ricardo.ecn.wfu.edu/gretl/apply/.\n"
                  "The 'Website' button below should open this page\n"
                  "in your web browser."));
    gtk_widget_show(hbox);

    /* control button area */

    hbox = GTK_DIALOG(linfo->dlg)->action_area;

    /* Cancel */
    button = cancel_button(hbox);
    g_signal_connect(G_OBJECT(button), "clicked", 
                 G_CALLBACK(login_cancel), linfo);
    gtk_widget_show(button);

    /* OK */
    button = ok_button(hbox);
    g_signal_connect(G_OBJECT(button), "clicked",
                 G_CALLBACK(login_finalize), linfo);
    gtk_widget_grab_default(button);
    gtk_widget_show(button);

    /* Website */
    button = gtk_button_new_with_label("Website");
    GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
    gtk_container_add(GTK_CONTAINER(hbox), button);
    gtk_button_box_set_child_secondary(GTK_BUTTON_BOX(hbox),
                               button, TRUE);
    g_signal_connect(G_OBJECT(button), "clicked", 
                 G_CALLBACK(web_get_login), NULL);
    gtk_widget_show(button);

    gtk_widget_show(linfo->dlg);
}

static void do_upload (const char *fname)
{
    login_info linfo;

    login_dialog(&linfo);

    if (!linfo.canceled) {
      char *errbuf = NULL;
      int err = upload_function_package(linfo.login,
                                linfo.pass,
                                fname,
                                &errbuf);
      if (err) {
          errbox(errbuf);
      }
      free(errbuf);
    }

    linfo_free(&linfo);
}

void save_user_functions (const char *fname, gpointer p)
{
    function_info *finfo = p;
    int i, err;

    /* sync filename with functions editor */
    if (finfo->fname == NULL) {
      finfo->fname = g_strdup(fname);
    } else if (strcmp(fname, finfo->fname)) {
      g_free(finfo->fname);
      finfo->fname = g_strdup(fname);
    }

    if (finfo->privlist != NULL) {
      for (i=1; i<=finfo->privlist[0]; i++) {
          gretl_function_set_private(finfo->privlist[i], TRUE);
      }
    }

    for (i=1; i<=finfo->publist[0]; i++) {
      gretl_function_set_info(finfo->publist[i], finfo->help[i-1]);
      gretl_function_set_private(finfo->publist[i], FALSE);
    }

#if 0
    fprintf(stderr, "author='%s'\n", finfo->author);
    fprintf(stderr, "version='%s'\n", finfo->version);
    fprintf(stderr, "date='%s'\n", finfo->date);
    fprintf(stderr, "pkgdesc='%s'\n", finfo->pkgdesc);
    printlist(finfo->publist, "finfo->publist");
    printlist(finfo->privlist, "finfo->privlist");
    fprintf(stderr, "dreq=%d\n", finfo->dreq);
    fprintf(stderr, "minver=%.2f\n", (double) finfo->minver);
#endif
            
    err = write_function_package(finfo->pkg,
                         fname,
                         finfo->publist, 
                         finfo->privlist,
                         finfo->author,
                         finfo->version,
                         finfo->date,
                         finfo->pkgdesc,
                         finfo->dreq,
                         finfo->minver);

    if (err) {
      gui_errmsg(err);
    } else if (finfo->upload) {
      do_upload(fname);
    }
}

/* called from function selection dialog: a set of functions has been
   selected and now we need to add info on author, version, etc.
*/

void prepare_functions_save (void)
{
    function_info *finfo;
    int *list = NULL;

    if (storelist == NULL) {
      return;
    }

    finfo = finfo_new();
    if (finfo == NULL) {
      return;
    }

    list = gretl_list_from_string(storelist);
    if (list == NULL) {
      nomem();
      free(finfo);
      return;
    }

    if (gretl_list_has_separator(list)) {
      if (gretl_list_split_on_separator(list, &finfo->publist, 
                                &finfo->privlist)) {
          nomem();
          free(finfo);
          free(list);
          return;
      } else {
          free(list);
      }
    } else {
      finfo->publist = list;
      finfo->privlist = NULL;
    }

    /* Call dialog to do the actual editing */
    finfo_dialog(finfo);
}

void edit_function_package (const char *fname)
{
    function_info *finfo;
    int err = 0;

    if (!user_function_file_is_loaded(fname)) {
      err = load_user_function_file(fname);
      if (err) {
          fprintf(stderr, "load_user_function_file: failed on %s\n", fname);
          errbox(_("Couldn't open %s"), fname);
          return;
      }
    }

    finfo = finfo_new();
    if (finfo == NULL) {
      return;
    }

    err = function_package_get_info(fname,
                            &finfo->pkg,
                            &finfo->publist,
                            &finfo->privlist,
                            &finfo->author,
                            &finfo->version,
                            &finfo->date,
                            &finfo->pkgdesc,
                            &finfo->dreq,
                            &finfo->minver);

    if (err) {
      fprintf(stderr, "function_package_get_info: failed on %s\n", fname);
      errbox("Couldn't get function package information");
      finfo_free(finfo);
      return;
    }

    finfo->fname = g_strdup(fname);

    finfo_dialog(finfo);
}



Generated by  Doxygen 1.6.0   Back to index