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

gladeform.c

/*  Gaby
 *  Copyright (C) 1998-2000 Frederic Peters
 *
 *  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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include <gaby.h>
#include <glade/glade.h>
#include <tables.h>
#include <records.h>
#include <f_desc.h>           /* for get_plugin_options */
#include <f_config.h>
#include <gtk_config_dlg.h>   /* for gaby_property_box_changed */
#include <gtk_main.h>
#include <gtk_menu.h>         /* for gaby_quit_callback */
#include <windows.h>          /* for update_bound_windows */
#include <actions.h>          /* for do_action_script_fu */


mstatic void gladeform_create ( gabywindow *window, gboolean first );
mstatic void gladeform_fill ( gabywindow *window );
mstatic GtkWidget* gladeform_get_widget(gabywindow *window, gchar *s);

static gboolean initialized = FALSE;

#ifndef FOLLOW_MIGUEL
int init_view_plugin (ViewPluginData *vpd)
{
      vpd->view_create = gladeform_create;
      vpd->view_fill = gladeform_fill;
      vpd->configure = NULL;
      vpd->view_get_widget = gladeform_get_widget;
      vpd->view_records = NULL;

      vpd->name = "gladeform";
      vpd->i18n_name = _("Glade form");
      vpd->type = ONE_RECORD;
      vpd->capabilities = EDITABLE;

#ifdef DEBUG_GABY
      debug_print(_("Initialization of view plugin '%s' done succesfully.\n"),
                  vpd->i18n_name );
#endif

      return 0;
}
#endif

static void glade_get_widgets(GladeXML *xml, subtable *st, GtkWidget **fields);
static void glade_set_labels(GladeXML *xml, subtable *st);
static void glade_set_actions(GladeXML *xml, gabywindow *win);

static gboolean analyse_options(gabywindow *window, char *filename);

static void gladeform_real_next_record(GtkWidget *null, gabywindow *window);
static void gladeform_real_previous_record(GtkWidget *null, gabywindow *window);
static void gladeform_real_first_record(GtkWidget *null, gabywindow *window);
static void gladeform_real_last_record(GtkWidget *null, gabywindow *window);
static void gladeform_real_new_record(GtkWidget *null, gabywindow *window);
static void gladeform_real_save_record(GtkWidget *null, gabywindow *window);
static void gladeform_real_remove_record(GtkWidget *null, gabywindow *window);

mstatic void gladeform_create ( gabywindow *window, gboolean first )
{
      GtkWidget *vbox;
      GtkWidget *wid;
      GladeXML *xml;
      char filename[PATH_MAX];
      GtkWidget **fields;
      int *id;
      record *r;

      if ( initialized == FALSE ) {
            glade_init();
            initialized = TRUE;
      }

      if ( analyse_options(window, filename) == FALSE ) {
            gaby_errno = CUSTOM_ERROR;
            gaby_message = g_strdup(
                  _("No filename specified as template for libglade"));
            gaby_perror_in_a_box();
            return;
      }
      
#ifdef DEBUG_GABY
      debug_print("[glade:create] trying %s\n", filename);
#endif

#if 0
      xml = glade_xml_new(filename, NULL );
      glade_xml_signal_autoconnect(xml);
      
      wid = glade_xml_get_widget(xml, "form");
      /* 
       * gtk_container_remove (and gtk_widget_unparent) seems to _destroy_
       * the widget (GTK_IS_WIDGET(wid) fails after them) and this is not
       * what I want ... so I simply set parent to NULL which will cause lots
       * of trouble if the previous container is shown ...
       */
      wid->parent = NULL;
#else
      /* James Henstridge <james@daa.com.au> mailed me and told me that this
       * will work - I need to update libglade before trying it */
            
      xml = glade_xml_new(filename, "data-entry");
      if ( xml == NULL ) return;
      glade_xml_signal_autoconnect(xml);
      wid = glade_xml_get_widget(xml, "data-entry");
      if ( wid == NULL ) return;
#endif
      
      vbox = gtk_vbox_new(FALSE, 0);
#ifdef DEBUG_GABY
      debug_print("[gladeform] widget is %p\n", vbox);
#endif
      window->widget = vbox;
      gtk_widget_show(vbox);

      fields = g_malloc(sizeof(GtkWidget *) * window->view->subtable->nb_fields);
      glade_set_labels(xml, window->view->subtable);
      glade_set_actions(xml, window);
      glade_get_widgets(xml, window->view->subtable, fields);
      gtk_object_set_data(GTK_OBJECT(vbox), "fields", fields);
      gtk_object_set_data(GTK_OBJECT(vbox), "window", window);
      gtk_object_set_data(GTK_OBJECT(vbox), "xml", xml);
      gtk_box_pack_start(GTK_BOX(vbox), wid, TRUE, TRUE, 0 );
      gtk_widget_show(wid);
      gtk_widget_show(vbox);

      id = &(window->id);
      r = table_first(window->view->subtable->table, -1);
      *id = ( r == NULL ) ? 0 : r->id;
      
      return; 
}

static gboolean analyse_options(gabywindow *window, char *filename)
{
      /* this function reads the respective plugins_options part 
       * from the descfile */
      GList *options, *orig_options;
      char sectname[100];
      char *stmp;
      char tfn[PATH_MAX];
      FILE *f;

      sprintf(sectname, "GladeForm:%s", window->view->subtable->name);
      options = get_plugin_options(sectname);
      if ( options == NULL )
            return FALSE;
      orig_options = options;
      while ( options != NULL ) {
            stmp = options->data;
            if ( strncmp(stmp, "filename=", 9) == 0 ) {
                  strcpy(tfn, stmp+9);
                  g_free(stmp);
                  break;
            }
            g_free(options->data);
            options = g_list_next(options);
      }
      g_list_free(orig_options);
      if ( options == NULL )
            return FALSE;     /* we reached the end of the list without
                           finding an appropriate filename */
      
      if ( tfn[0] == '/' ) { /* absolute pathname */
            strcpy(filename, tfn);
            return TRUE;
      }

      sprintf(filename, "%s/.gaby/%s", g_get_home_dir(), tfn);
      f = fopen(filename, "r");
      if ( f == NULL ) sprintf(filename, GLADE_DIR"/%s", tfn);
      else fclose(f);

      return TRUE;
}

mstatic void gladeform_fill ( gabywindow *window )
{
      view *v = window->view;
      subtable *st = v->subtable;
      GtkWidget *wid = window->widget;
      GtkWidget **fields = gtk_object_get_data(GTK_OBJECT(wid), "fields");
      GString *str;
      int *id = &(window->id);
      int i;

      for ( i=0; i < st->nb_fields; i++ ) {
            str = get_subtable_stringed_field_id(st, *id, i);

            if ( GTK_IS_ENTRY(fields[i]) ) {
                  gtk_entry_set_text(GTK_ENTRY(fields[i]), str->str);
            } else if ( GTK_IS_COMBO(fields[i]) ) {
                  gtk_entry_set_text( 
                        GTK_ENTRY( GTK_COMBO(fields[i])->entry),
                        str->str);
            } else if ( GTK_IS_TEXT(fields[i]) ) {            
                  gtk_text_set_point(GTK_TEXT(fields[i]), 0);
                  gtk_text_forward_delete(GTK_TEXT(fields[i]), 
                        gtk_text_get_length(GTK_TEXT(fields[i])));
                  gtk_text_insert(GTK_TEXT(fields[i]), NULL, NULL,
                              NULL, str->str,-1);
                  gtk_text_set_point(GTK_TEXT(fields[i]), 0);
            }
            g_string_free(str, 1);
      }
}

static void glade_get_widgets(GladeXML *xml, subtable *st, GtkWidget **fields)
{
      int i;
      char str[50];
      
      for ( i=0; i < st->nb_fields; i++ ) {
            sprintf(str, "entry-%s", st->fields[i].name);
            fields[i] = glade_xml_get_widget(xml, str);
#ifdef DEBUG_GABY
            debug_print("[glade_get_widgets] %d : %p\n", i, fields[i]);
#endif
      }
}

static void glade_set_labels(GladeXML *xml, subtable *st)
{
      int i;
      char str[50];
      GtkWidget *wid;
      
      debug_print("[gladeform::gsl] --\n");
      for ( i=0; i < st->nb_fields; i++ ) {
            sprintf(str, "label-%s", st->fields[i].name);
            wid = glade_xml_get_widget(xml, str);
            if ( GTK_IS_LABEL(wid) ) {
                  gtk_label_set_text(GTK_LABEL(wid),
                                    st->fields[i].i18n_name);
            }
      }
}

static void glade_set_actions(GladeXML *xml, gabywindow *win)
{
      GtkWidget *wid;
      struct { char *name; char *i18n; GtkSignalFunc func; } buttons[] =
            {
              {"Previous Record",   N_("Previous"),
                              gladeform_real_previous_record},
              {"Next Record", N_("Next"),
                              gladeform_real_next_record },
              {"Last Record", N_("Last"),
                              gladeform_real_last_record},
              {"First Record",      N_("First"),
                              gladeform_real_first_record },
              {"New Record",  N_("New"),
                              gladeform_real_new_record },
              {"Remove Record",     N_("Remove"),
                              gladeform_real_remove_record },
              {NULL, NULL, NULL }
            };
      int i=-1;
      
      while ( buttons[++i].name != NULL ) {
            wid = glade_xml_get_widget(xml, buttons[i].name);
            if ( wid == NULL ) continue;
            gtk_signal_connect(GTK_OBJECT(wid), "clicked", 
                                    buttons[i].func, win );
            if ( GTK_IS_BUTTON(wid) ) {
                  GtkButton *wi = GTK_BUTTON(wid);
                  debug_print("widget is button, translation is %s\n",
                              _(buttons[i].i18n));
                  gtk_label_set_text(GTK_LABEL(wi->child), 
                                          _(buttons[i].i18n) );
            }
      }

}

mstatic GtkWidget* gladeform_get_widget(gabywindow *window, gchar *s)
{
      GladeXML *xml;
      GtkWidget *wid;

      xml = gtk_object_get_data(GTK_OBJECT(window->widget), "xml");
      
      wid = glade_xml_get_widget(xml, s);

      return wid;
}

static void gaby_hello_world(GtkWidget *item, gpointer data)
{
      /* this is to test function calls from buttons defined within glade */
      g_print("hello, world !\n");
}

static gabywindow* resolve_gabywindow(GtkWidget *item)
{
      GtkWidget *wid;
      gabywindow *win = NULL;
      
      wid = item;
      while ( wid->parent ) {
            debug_print("wid: %p\n", wid);
            win = gtk_object_get_data(GTK_OBJECT(wid), "window");
            if ( win ) {
                  gtk_object_set_data(GTK_OBJECT(item), "window", win);
                  break;
            }
            wid = wid->parent;
      }
      debug_print("[gladeform::rgw] window: %p\n", win);

      return win;
}

void gaby_next_record(GtkWidget *item, gpointer data)
{
      gabywindow *win;
      
      debug_print("[gladeform::gnr] moving to the next record\n");
      
      win = gtk_object_get_data(GTK_OBJECT(item), "window");
      if ( win == NULL ) {
            win = resolve_gabywindow(item);
      }

      gladeform_real_next_record(NULL, win);
}

void gaby_previous_record(GtkWidget *item, gpointer data)
{
      gabywindow *win;
      
      debug_print("[gladeform::gnr] moving to the next record\n");
      
      win = gtk_object_get_data(GTK_OBJECT(item), "window");
      if ( win == NULL ) {
            win = resolve_gabywindow(item);
      }

      gladeform_real_previous_record(NULL, win);
}

void gaby_first_record(GtkWidget *item, gpointer data)
{
      gabywindow *win;
      
      debug_print("[gladeform::gnr] moving to the next record\n");
      
      win = gtk_object_get_data(GTK_OBJECT(item), "window");
      if ( win == NULL ) {
            win = resolve_gabywindow(item);
      }

      gladeform_real_first_record(NULL, win);
}

void gaby_last_record(GtkWidget *item, gpointer data)
{
      gabywindow *win;
      
      debug_print("[gladeform::gnr] moving to the next record\n");
      
      win = gtk_object_get_data(GTK_OBJECT(item), "window");
      if ( win == NULL ) {
            win = resolve_gabywindow(item);
      }

      gladeform_real_last_record(NULL, win);
}

static void gladeform_real_next_record(GtkWidget *null, gabywindow *window)
{
      record *r;
      table *tab = window->view->subtable->table;

      gladeform_real_save_record(NULL, window);
      
      r = get_record_no(tab, window->id);
      r = table_next(tab, r, -1);
      window->id = ( r == NULL ) ? 0 : r->id;
      
      gladeform_fill(window);

      update_bound_windows(window);
}

static void gladeform_real_previous_record(GtkWidget *null, gabywindow *window)
{
      record *r;
      table *tab = window->view->subtable->table;

      gladeform_real_save_record(NULL, window);
      
      r = get_record_no(tab, window->id);
      r = table_prev(tab, r, -1);
      window->id = ( r == NULL ) ? 0 : r->id;
      
      gladeform_fill(window);

      update_bound_windows(window);
}

static void gladeform_real_first_record(GtkWidget *null, gabywindow *window)
{
      record *r;
      table *tab = window->view->subtable->table;

      gladeform_real_save_record(NULL, window);
      
      r = table_first(tab, -1);
      window->id = ( r == NULL ) ? 0 : r->id;
      
      gladeform_fill(window);

      update_bound_windows(window);
}

static void gladeform_real_last_record(GtkWidget *null, gabywindow *window)
{
      record *r;
      table *tab = window->view->subtable->table;

      gladeform_real_save_record(NULL, window);
      
      r = table_last(tab, -1);
      window->id = ( r == NULL ) ? 0 : r->id;
      
      gladeform_fill(window);

      update_bound_windows(window);
}

static void gladeform_real_new_record(GtkWidget *null, gabywindow *window)
{
      if ( window->id == 0 ) {
            return;
      }

      gladeform_real_save_record(NULL, window);
      window->id = 0;
      gladeform_fill(window);
}

static record* gladeform_get_record(gabywindow *window, record *r)
{
      GtkWidget **wid_fields;
      char *tmp = NULL;
      int i;
      
      wid_fields = gtk_object_get_data(GTK_OBJECT(window->widget), "fields");

      if ( r == NULL ) {
            r = record_defaults(window->view->subtable->table);
/*          r->id = 0;
            r->cont = g_new0(union data,
                        window->view->subtable->table->nb_fields); */   
      } else {
            r = record_duplicate(window->view->subtable->table, r);
            r->id = 0;
      }

      for ( i=0; i<window->view->subtable->nb_fields; i++ ) {
            if ( wid_fields[i] == NULL ) continue;
            if ( GTK_IS_ENTRY(wid_fields[i]) ) {
                  tmp = gtk_entry_get_text(GTK_ENTRY(wid_fields[i]));
            } else if ( GTK_IS_COMBO(wid_fields[i]) ) {
                  GtkCombo *cb = GTK_COMBO(wid_fields[i]);
                  tmp = gtk_entry_get_text(GTK_ENTRY(cb->entry));
            } else if ( GTK_IS_TEXT(wid_fields[i]) ) {
                  tmp = gtk_editable_get_chars(
                              GTK_EDITABLE(wid_fields[i]), 0, -1);
            }
            set_subtable_stringed_field(window->view->subtable, r, i, tmp);
            if ( GTK_IS_TEXT(wid_fields[i]) ) {
                  g_free(tmp);
            }
      }
            
      return r;
}

static void gladeform_real_save_record(GtkWidget *null, gabywindow *window)
{
      record *oldr, *r;
      table *t = window->view->subtable->table;
      /* TODO (post-2.0): check for memory leaks
       *  I'm feeling really bad with this function :( 
       *  delayed since gladeform won't be the popular view in 2.0
       */
      
      if ( window->id == 0 ) { /* new record */
            r = gladeform_get_record(window, NULL);
            if ( record_add(t, r, TRUE, FALSE) == -1 ) {
                  record_free(t, r);
            }
      } else {
            oldr = get_record_no(t, window->id);
            r = gladeform_get_record(window, oldr);
            r->id = oldr->id;
            if ( records_are_different(t, get_record_no(t, window->id), r)){
                  debug_print("[grsr] records look different\n");
                  record_modify(t, r);
            } else {
                  record_free(t, r);
            }
      }

      update_windows(window);
}

static void gladeform_real_remove_record(GtkWidget *null, gabywindow *window)
{
      record *r;
      table *t = window->view->subtable->table;
      
      if ( window->id == 0 ) {
            /* we were adding a record but we changed our mind */
            /* let's go back to the last record */
            
            r = table_last(t, -1);
            if ( r != NULL ) window->id = r->id;
            gladeform_fill(window);
            return;
      }

      record_remove_id(t, window->id);
      r = table_first(t, -1);
      if ( r != NULL ) window->id = r->id;
      else window->id = 0;

      gladeform_fill(window);

      update_windows(window);
}

void gaby_launch_script(GtkWidget *null, gchar *data)
{
      action uda = {
            "user-defined action",
            "",
            SCRIPT_FU,
            EVENT_STARTUP,
            { NULL },
            0,
            NULL,
            NULL
      };

      if ( data == NULL ) return;

      uda.what.script = g_strdup(data);
      do_action_script_fu(&uda);
      g_free(uda.what.script);
}


Generated by  Doxygen 1.6.0   Back to index