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

filter.c

/*  Gaby
 *  Copyright (C) 1998-1999 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 <f_desc.h>     /* for subtable_get_field_no */
#include <tables.h>
#include <records.h>
#include <windows.h>

mstatic void filter_create ( gabywindow *window, gboolean first );
mstatic void filter_fill ( gabywindow *window );

#ifndef FOLLOW_MIGUEL
int init_view_plugin (ViewPluginData *vpd)
{
      vpd->view_create = filter_create;
      vpd->view_fill = filter_fill;
      vpd->view_records = NULL;
      vpd->configure = NULL;

      vpd->name = "filter";
      vpd->i18n_name = _("Filter");
      vpd->type = FILTER;
      vpd->capabilities = NONE;

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

      return 0;
}
#endif

static gabywindow* get_first_list_window(subtable *st);
static void fill_windows_list(GtkWidget *list, subtable *st);
static GtkWidget* create_conditions_table(view *v, int nb_rows);
static void update_clicked(GtkWidget *but, gabywindow *window);
static void apply_clicked(GtkWidget *but, gabywindow *window);

mstatic void filter_create ( gabywindow *window, gboolean first )
{
      GtkWidget *vbox, *hbox, *sep, *table, *button;
      GtkWidget *affected_window, *update, *label, *radio;
      gabywindow *win;
      condition *c = g_new0(condition, 1);
      view *v = window->view;
      
      vbox = gtk_vbox_new (FALSE, 5);
      window->widget = vbox;
      
      hbox = gtk_hbox_new (FALSE, 5);
      gtk_widget_show(hbox);
      gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
      
      label = gtk_label_new(_("Affected window :"));
      gtk_widget_show(label);
      gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0 );
      
      affected_window = gtk_combo_new();

      win = get_first_list_window(v->subtable);
      if ( win == NULL ) {
            gaby_errno = CUSTOM_ERROR;
            gaby_message = g_strdup(_("There are no views you can filter"));
            gaby_perror_in_a_box();
      } else {
            fill_windows_list(GTK_COMBO(affected_window)->list, v->subtable);
            gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(affected_window)->entry),
                                                win->name );
      }
      gtk_widget_show(affected_window);
      gtk_box_pack_start(GTK_BOX(hbox), affected_window, TRUE, TRUE, 0 );

      update = gtk_button_new_with_label(_("Update"));
      gtk_signal_connect(GTK_OBJECT(update), "clicked",
                        GTK_SIGNAL_FUNC(update_clicked), window );
      gtk_widget_show(update);
      gtk_box_pack_start(GTK_BOX(hbox), update, TRUE, TRUE, 0 );

#if 0
      sep = gtk_hseparator_new();
      gtk_widget_show(sep);
      gtk_box_pack_start(GTK_BOX(vbox), sep, FALSE, FALSE, 3 );
#endif

      hbox = gtk_hbox_new (FALSE, 5);
      gtk_widget_show(hbox);
      gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
      
      label = gtk_label_new(_("Between conditions :"));
      gtk_widget_show(label);
      gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0 );

      radio = gtk_radio_button_new_with_label(NULL, _("and"));
      gtk_object_set_data(GTK_OBJECT(vbox), "radio_and", radio);
      gtk_widget_show(radio);
      gtk_box_pack_start(GTK_BOX(hbox), radio, TRUE, TRUE, 0 );
      radio = gtk_radio_button_new_with_label_from_widget( 
                              GTK_RADIO_BUTTON(radio), _("or"));
      gtk_widget_show(radio);
      gtk_box_pack_start(GTK_BOX(hbox), radio, TRUE, TRUE, 0 );
      
      sep = gtk_hseparator_new();
      gtk_widget_show(sep);
      gtk_box_pack_start(GTK_BOX(vbox), sep, FALSE, FALSE, 3 );

      table = create_conditions_table(v, 2);
      gtk_widget_show(table);
      gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 5 );
      gtk_object_set_data(GTK_OBJECT(vbox), "condnb", GINT_TO_POINTER(2));

      sep = gtk_hseparator_new();
      gtk_widget_show(sep);
      gtk_box_pack_start(GTK_BOX(vbox), sep, FALSE, FALSE, 3 );

      button = gtk_button_new_with_label(_("Apply"));
      gtk_signal_connect(GTK_OBJECT(button), "clicked", apply_clicked,window);
      gtk_widget_show(button);
      gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 3 );

      gtk_object_set_data(GTK_OBJECT(vbox), "cond", c);
      
      gtk_object_set_data(GTK_OBJECT(vbox), "affwincombo", affected_window);
      gtk_object_set_data(GTK_OBJECT(vbox), "table", table);
      
      gtk_widget_show(vbox);
      return;
}

mstatic void filter_fill ( gabywindow *window )
{
      ;
}

static gabywindow* get_first_list_window(subtable *st)
{
      GtkWidget *its_parent;
      view *v;
      GList *tmp = g_list_first(list_windows);
      gabywindow *window;

      while ( tmp != NULL ) {
            window = tmp->data;
            tmp = g_list_next(tmp);
            if ( ! GTK_IS_OBJECT(window->widget) ) continue;
            its_parent = window->parent;
            if ( GTK_IS_WINDOW(its_parent) ) {
                  v = window->view;
                  if ( v->subtable->table == st->table &&
                              v->type->capabilities & FILTERABLE ) {
                        return window;
                  }
            }
      }

      return NULL;            
}

static void fill_windows_list(GtkWidget *list, subtable *st)
{
      /* a copy of this function exists in print/html2/html2.c
       *  -> duplicate the fixes
       */
      GtkWidget *its_parent, *li;
      view *v;
      GList *tmp = g_list_first(list_windows);
      gchar *name;
      gabywindow *window;

      gtk_list_clear_items(GTK_LIST(list), 0, -1);

      while ( tmp != NULL ) {
            window = tmp->data;
            tmp = g_list_next(tmp);
            if ( ! GTK_IS_OBJECT(window->widget) ) continue;
            its_parent = window->parent;
            if ( GTK_IS_WINDOW(its_parent) ) {
                  v = window->view;
                  name = window->name;
                  if ( v->subtable->table == st->table &&
                              v->type->capabilities & FILTERABLE ) {
                        
                        li = gtk_list_item_new_with_label(name);
                        gtk_widget_show(li);
                        gtk_container_add(GTK_CONTAINER(list), li);
                  }
            }
      }
}

static void update_clicked(GtkWidget *but, gabywindow *window)
{
      GtkWidget *box = window->widget;
      GtkWidget *combo = gtk_object_get_data(GTK_OBJECT(box), "affwincombo");
      view *v = window->view;

      fill_windows_list(GTK_COMBO(combo)->list, v->subtable);
}

static void line_enabled_clicked(GtkWidget *check, gpointer data)
{
      GtkWidget *cb = gtk_object_get_data(GTK_OBJECT(check), "combo" );
      GtkWidget *om = gtk_object_get_data(GTK_OBJECT(check), "om" );
      GtkWidget *en = gtk_object_get_data(GTK_OBJECT(check), "entry" );
      gboolean sensitive = gtk_toggle_button_get_active(
                                    GTK_TOGGLE_BUTTON(check));
      
      gtk_widget_set_sensitive(cb, sensitive);
      gtk_widget_set_sensitive(om, sensitive);
      gtk_widget_set_sensitive(en, sensitive);
}

static GtkWidget* create_conditions_table (view *v, int nb_rows)
{
      GtkWidget *table;
      GtkWidget *listfields, *li, *om, *menu, *item, *entry, *enabled;
      GSList *group;
      int i, j;
      char *buf;
      char *conditions[] = {
            gettext_noop("is"),
            gettext_noop("is not"),
            gettext_noop("is more than"),
            gettext_noop("is less than"),
            gettext_noop("starts with"),
            gettext_noop("has"),
            gettext_noop("matches (regex)")
      };
      condition *c;
      
      table = gtk_table_new(nb_rows, 4, FALSE);
      
      for ( i=0; i < nb_rows; i++ ) {
            c = g_new0(condition, 1);
            c->c.val = g_string_new("");
            buf = g_malloc(4);
            sprintf(buf, "c%d", i);
            gtk_object_set_data(GTK_OBJECT(table), buf, c);
            listfields = gtk_combo_new();
            gtk_entry_set_editable(
                        GTK_ENTRY(GTK_COMBO(listfields)->entry), FALSE);
            buf = g_malloc(4);
            sprintf(buf, "f%d", i);
            gtk_object_set_data(GTK_OBJECT(table), buf, listfields);
            
            for ( j=0; j < v->subtable->nb_fields; j++ ) {
                  li = gtk_list_item_new_with_label(
                              v->subtable->fields[j].i18n_name );
                  gtk_widget_show(li);
                  gtk_container_add(
                        GTK_CONTAINER(GTK_COMBO(listfields)->list),li);
            }
            gtk_widget_show(listfields);
            gtk_table_attach_defaults(GTK_TABLE(table), listfields,
                        1, 2, i, i+1);

            om = gtk_option_menu_new();
            
            menu = gtk_menu_new();
            group = NULL;
            for ( j=0; j < 7; j++ ) {
                  item = gtk_radio_menu_item_new_with_label(
                                    group, _(conditions[j]));
                  group = gtk_radio_menu_item_group(
                                    GTK_RADIO_MENU_ITEM(item));
                  gtk_widget_show(item);
                  gtk_menu_append(GTK_MENU(menu), item);
            }
            gtk_widget_show(menu);
            gtk_option_menu_set_menu(GTK_OPTION_MENU(om), menu);
            buf = g_malloc(4);
            sprintf(buf, "t%d", i);
            gtk_object_set_data(GTK_OBJECT(table), buf, group);
#ifdef DEBUG_GABY
            debug_print("[filter:cct] %s : %p\n", buf, group);
#endif
            gtk_widget_show(om);
            gtk_table_attach_defaults(GTK_TABLE(table), om,
                        2, 3, i, i+1);
            
            entry = gtk_entry_new();
            buf = g_malloc(4);
            sprintf(buf, "e%d", i);
            gtk_object_set_data(GTK_OBJECT(table), buf, entry);
            gtk_widget_show(entry);
            gtk_table_attach_defaults(GTK_TABLE(table), entry,
                        3, 4, i, i+1);
            
            enabled = gtk_check_button_new();
            buf = g_malloc(4);
            sprintf(buf, "k%d", i);
            gtk_object_set_data(GTK_OBJECT(table), buf, enabled);
            gtk_widget_show(enabled);
            gtk_table_attach_defaults(GTK_TABLE(table), enabled,
                        0, 1, i, i+1);
            gtk_object_set_data(GTK_OBJECT(enabled), "combo", listfields);
            gtk_object_set_data(GTK_OBJECT(enabled), "om", om );
            gtk_object_set_data(GTK_OBJECT(enabled), "entry", entry );
            gtk_signal_connect(GTK_OBJECT(enabled), "toggled",
                        GTK_SIGNAL_FUNC(line_enabled_clicked), NULL);
            gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(enabled),
                                                ( i == 0 ) );
            line_enabled_clicked(enabled, NULL);
      }
      
      return table;
}

static void apply_clicked(GtkWidget *but, gabywindow *window)
{
      GtkWidget *box = window->widget;
      gabywindow *affwin;
      GtkWidget *combo = gtk_object_get_data(GTK_OBJECT(box), "affwincombo");
      GtkWidget *table = gtk_object_get_data(GTK_OBJECT(box), "table");
      GtkWidget *radio = gtk_object_get_data(GTK_OBJECT(box), "radio_and");
      view *v = window->view;
      GtkCheckMenuItem *item;
      GtkWidget *fields, *entry, *enabled;
      GSList *a;
      int cndno, cndnb, i;
      condition *c, *ct;
      ViewPluginData *vpd;
      char buf[5];
      gchar *name;
      
#ifdef DEBUG_GABY
      debug_print("[filter:apply_clicked]\n");
#endif
      
      name = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(combo)->entry));
      affwin = get_window_by_name(name);  
      
      if ( affwin == NULL ) {
            gaby_message = g_strdup(_("No valid window (extended list) has been found."));
            gaby_errno = CUSTOM_ERROR;
            gaby_perror_in_a_box();
            return;
      }

      if ( g_list_find(list_windows, affwin) == NULL ) {
#ifdef DEBUG_GABY
            debug_print("[filter:apply_clicked] affwin no more in all_wins\n");
#endif            
            return;
      }

      if ( ! GTK_IS_OBJECT(affwin->widget) ) {
#ifdef DEBUG_GABY
            debug_print("[filter:apply_clicked] affwin no more a gtk object\n");
#endif
            return;
      }

      cndnb = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(box), "condnb"));
      c = gtk_object_get_data(GTK_OBJECT(box), "cond");
      c->val_true = TRUE;
      c->type = ( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio)) ) ?
                  C_AND : C_OR;
      c->field_no = 0;  /* doesn't matter*/
      if ( c->c.conditions != NULL ) {
            g_list_free(c->c.conditions);
            c->c.conditions = NULL;
      }

      for ( i=0; i<cndnb; i++ ) {
            sprintf(buf, " %d", i);

            buf[0] = 't';
            a = gtk_object_get_data(GTK_OBJECT(table), buf);
            buf[0] = 'c';
            ct = gtk_object_get_data(GTK_OBJECT(table), buf);
            buf[0] = 'f';
            fields = gtk_object_get_data(GTK_OBJECT(table), buf);
            buf[0] = 'e';
            entry = gtk_object_get_data(GTK_OBJECT(table), buf);
            buf[0] = 'k';
            enabled = gtk_object_get_data(GTK_OBJECT(table), buf);

            if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(enabled)))
                  continue;
            
#ifdef DEBUG_GABY
            debug_print("[apply_clicked] a:%p, ct:%p, f:%p, e:%p\n",
                                          a, ct, fields, entry);
#endif
            cndno = 8;
            while ( a != NULL ) {
                  item = a->data;
                  if ( item->active ) break;
                  cndno--;
                  a = g_slist_next(a);
            }

            ct->val_true = TRUE;
            ct->type = cndno;
            name = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(fields)->entry));
            ct->field_no = subtable_get_field_no(v->subtable, name );
            
            name = gtk_entry_get_text(GTK_ENTRY(entry));
            ct->c.val = g_string_assign(ct->c.val, name );

#ifdef DEBUG_GABY
            debug_print("[apply_clicked] ct->type : %d\n", ct->type );
#endif

            c->c.conditions = g_list_append(c->c.conditions, ct );
      }

      vpd = affwin->view->type;
      gtk_object_set_data(GTK_OBJECT(affwin->widget), "condition", c);
      vpd->view_fill(affwin);
}


Generated by  Doxygen 1.6.0   Back to index