filter.c File Reference


Detailed Description

Author:
Copyright 2006-2007 Neil Williams <linux@codehelp.co.uk>

Copyright 1999 Robert Lissner, Jay MacDonald,

Copyright 1999 Sam Phillips, Keith Wesolowski.

Definition in file filter.c.

#include "config.h"
#include <string.h>
#include <glib.h>
#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include <gtkextra/gtksheet.h>
#include "types.h"
#include "dim_list_menu.h"
#include "filter.h"
#include "main.h"

Go to the source code of this file.

Defines

#define RETURN_AND_FREE(x)
 whether record record_index matches the criterion and rule for field field_index.

Enumerations

enum  QlFilterMode { QL_FILTER_APPLY, QL_FILTER_EDIT, QL_FILTER_DELETE }
enum  { FILTER_COL, FROM_COL }
enum  QlRuleName {
  IN = 0, NOT_IN, EXACT, NOT,
  LESS, MORE, BLANK, NOT_BLANK
}

Functions

void filter_show_all (GtkAction G_GNUC_UNUSED *w, gpointer data)
static gboolean filter_compare_record (QlTabData *tab, gint32 field_index, gint32 record_index, gchar *criterionx, QLFilterRule rule, gboolean use_nocase)
static void filter_select (QlTabData *tab, QlFilterMode G_GNUC_UNUSED mode)
void filter_apply (GtkAction G_GNUC_UNUSED *w, gpointer data)
void filter_do_apply (QlTabData *tab, gint16 filter_index)
static void G_GNUC_UNUSED filter_entry_handler (GtkWidget *w, gpointer data)
static void G_GNUC_UNUSED filter_boolean_handler (GtkWidget *w, gpointer data)
static void filter_menuitem_select (GtkWidget *w, gpointer data)
static void filter_do_delete (QlTabData *tab, gint16 filter_index)
static void filter_action (GtkWidget G_GNUC_UNUSED *w, gpointer G_GNUC_UNUSED data)
static void filter_do_edit (QlTabData *tab, gint16 filter_index)
void filter_add (GtkAction G_GNUC_UNUSED *w, gpointer data)
void filter_edit (GtkAction G_GNUC_UNUSED *w, gpointer data)
void filter_delete (GtkAction G_GNUC_UNUSED *w, gpointer data)

Variables

static gint16 working_idx
static QlFilterInfo old_filter
static gboolean in_add = FALSE
static GHashTable * rules = NULL


Define Documentation

#define RETURN_AND_FREE (  ) 

Value:

{\
    gint z = (x);\
    if (use_nocase) g_free (entry);\
    if (use_nocase) g_free (criterion);\
    return z;\
}
whether record record_index matches the criterion and rule for field field_index.

This is a subset of applying a filter, which may call this function many times, at least once for each record. Note that this function only tests one field per call.

Definition at line 64 of file filter.c.


Enumeration Type Documentation

enum QlRuleName

Todo:
move elsewhere.

Definition at line 556 of file filter.c.

00557 {
00558     IN = 0,
00559     NOT_IN,
00560     EXACT,
00561     NOT,
00562     LESS,
00563     MORE,
00564     BLANK,
00565     NOT_BLANK
00566 } QlRuleName;


Function Documentation

static void filter_action ( GtkWidget G_GNUC_UNUSED *  w,
gpointer G_GNUC_UNUSED  data 
) [static]

Handles miscellaneous actions, typically from Edit

Definition at line 523 of file filter.c.

00524 {
00525     QlContext * qlc;
00526     QlTabData * tab;
00527 
00528     qlc = ql_get_context (w);
00529     tab = ql_get_tabdata (qlc);
00530     if (GTK_IS_DIALOG (w) || !strcmp (gtk_widget_get_name (w), "cancel"))
00531     {
00532         /* The user has requested that we cancel this operation. So first
00533          * find out what the operation is, then don't do it. :) For now, only
00534          * _filter_do_edit uses this.
00535          */
00536         if (in_add)
00537             filter_do_delete (tab, working_idx);
00538         else
00539             tab->file->filters[working_idx] = old_filter;
00540 
00541         in_add = FALSE;
00542         gtk_widget_destroy (w);
00543         return;
00544     }
00545     /* The user clicked the OK Button. Since we've already done everything,
00546      * just return.
00547      */
00548     filter_do_apply (tab, working_idx);
00549     in_add = FALSE;
00550     dim_list_filter_menu (tab->qlc);
00551     front_is_changed (tab);
00552     gtk_widget_destroy (w);
00553 }

static void G_GNUC_UNUSED filter_boolean_handler ( GtkWidget *  w,
gpointer  data 
) [static]

Bug:
remove these nasty casts

Definition at line 438 of file filter.c.

00439 {
00440     gint filter;
00441     QlContext * qlc;
00442     QlTabData * tab;
00443 
00444     qlc = ql_get_context (w);
00445     tab = ql_get_tabdata (qlc);
00446     filter = GPOINTER_TO_INT (data);
00448     if (!strcmp (gtk_widget_get_name (w), "bool"))
00449         tab->file->filters[filter].by_and
00450             = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
00451     else
00452         tab->file->filters[filter].use_nocase
00453             = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w));
00454 }

static gboolean filter_compare_record ( QlTabData tab,
gint32  field_index,
gint32  record_index,
gchar *  criterionx,
QLFilterRule  rule,
gboolean  use_nocase 
) [static]

<

Todo:
why the duplicate ?

Bug:
comparison likely to fail

Bug:
comparison likely to fail

Definition at line 89 of file filter.c.

00092 {
00093     gint32 column;
00094     gchar *entry;
00095     gchar *entryx; 
00096     gchar *criterion;
00097     QlFieldInfo * field;
00098 
00099     field = ql_get_fieldinfo (tab, field_index);
00100     column = field->sheet_column;
00101     entryx = g_strdup (gtk_sheet_cell_get_text 
00102         (tab->view->sheet, record_index, column));
00103     entry = entryx;
00104     criterion = criterionx;
00105 
00106     /* First handle the case of blank or nonblank criteria */
00107     if (!entry && rule != FILTER_ISBLANK)
00108         return FALSE;
00109     if (rule == FILTER_ISBLANK && (!entry || strlen (entry) == 0))
00110         return TRUE;
00111     switch (field->type)
00112     {
00113         /* We are required to handle string/text types ourselves */
00114         case FIELD_TYPE_TEXT:
00115         {
00116             /* We'll allow nocase comparison for strings as we do with match/find.
00117              * By default, filters are case-sensitive. That's just the Unix way.
00118              * It also happens to be the RIGHT way; if you want things to be
00119              * considered the same, type them the same.
00120              */
00121             if (use_nocase)
00122             {
00123                 entry = g_strdup (entryx);
00124                 g_strdown (entry);
00125                 criterion = g_strdup (criterionx);
00126                 g_strdown (criterion);
00127             }
00128             else
00129             {
00130                 entry = entryx;
00131                 criterion = criterionx;
00132             }
00133             switch (rule)
00134             {
00135             case FILTER_CONTAINS:
00136                 if (strstr (entry, criterion))
00137                     RETURN_AND_FREE (1);
00138                 RETURN_AND_FREE (0);
00139                 break;
00140             case FILTER_CONTAINSNO:
00141                 RETURN_AND_FREE (!strstr (entry, criterion));
00142                 break;
00143             case FILTER_IS:
00144                 RETURN_AND_FREE (!strcmp (entry, criterion));
00145                 break;
00146             case FILTER_ISNOT:
00147                 RETURN_AND_FREE (!!strcmp (entry, criterion));
00148                 break;
00149             case FILTER_LESS:
00150                 RETURN_AND_FREE ((strcmp (entry, criterion) > 0));
00151                 break;
00152             case FILTER_MORE:
00153                 RETURN_AND_FREE ((strcmp (entry, criterion) < 0));
00154                 break;
00155             case FILTER_ISBLANK:
00156                 RETURN_AND_FREE (FALSE);
00157                 break;
00158             case FILTER_ISNOTBLANK:
00159                 RETURN_AND_FREE (TRUE);
00160                 break;
00161             }
00162         }
00163         break;
00164 
00165 #undef RETURN_AND_FREE
00166 
00167         /* We must still handle all of the following for the other three types:
00168          * CONTAINS, CONTAINSNO, ISBLANK, ISNOTBLANK.
00169          */
00170         case FIELD_TYPE_NUMERIC:
00171         case FIELD_TYPE_DATE:
00172         case FIELD_TYPE_TIME:
00173         {
00174             gdouble d_entry =
00175                 qls2d (entry, field->type, field->formatting);
00176             gdouble d_criterion = qls2d (criterion,
00177                 field->type, field->formatting);
00178             switch (rule)
00179             {
00180             case FILTER_CONTAINS:
00181                 /* For contains/does not contain, we ignore the conversion and do
00182                  * text comparison.
00183                  */
00184                 if (strstr (entry, criterion))
00185                     return 1;
00186                 return 0;
00187                 break;
00188             case FILTER_CONTAINSNO:
00189                 if (strstr (entry, criterion))
00190                     return 0;
00191                 return 1;
00192                 break;
00193             case FILTER_IS:
00195                 return ((glong)d_entry == (glong)d_criterion);
00196                 break;
00197             case FILTER_ISNOT:
00199                 return ((glong)d_entry != (glong)d_criterion);
00200                 break;
00201             case FILTER_LESS:
00202                 return (d_entry < d_criterion);
00203                 break;
00204             case FILTER_MORE:
00205                 return (d_entry > d_criterion);
00206                 break;
00207             case FILTER_ISBLANK:
00208                 return FALSE;
00209                 break;
00210             case FILTER_ISNOTBLANK:
00211                 return TRUE;
00212                 break;
00213             }
00214         }
00215         break;
00216     default:
00217         {
00218             level2_error (tab, _("Internal error in tools_compare_record: "
00219                 "Invalid field type."));
00220             return 0;
00221         }
00222         break;
00223     }
00224     return 0;
00225 }

static void filter_do_delete ( QlTabData tab,
gint16  filter_index 
) [static]

This is kind of slow, but it's simple and it works. I expect all this stuff will eventually be replaced by a GList of filter structures and then this kind of crap will go away.

Todo:
make this go away

Bug:
rationalise this mess

Definition at line 487 of file filter.c.

00488 {
00494     gint reportx;
00495 
00496 /*  if (dialog1_win)
00497         cancel_level1 (dialog1_win, NULL, NULL);*/
00498     tab->file->filter_ct--;
00499 
00500     dim_list_filter_menu (tab->qlc);
00501     front_is_changed (tab);
00502 
00503     /* Handle report modifications */
00504     for (reportx = 0; reportx < tab->file->report_ct; reportx++)
00505     {
00506         if (tab->file->reports[reportx].filter == filter_index)
00507             tab->file->reports[reportx].filter = -1;
00508         else if (tab->file->reports[reportx].filter > filter_index)
00509             tab->file->reports[reportx].filter--;
00510     }
00512     if (tab->file->filter_ptr == &tab->file->filters[filter_index])
00513         tab->file->filter_ptr = NULL;
00514     if (filter_index == tab->file->filter_ct)
00515         return;
00516     if (tab->file->filter_ptr == &tab->file->filters[tab->file->filter_ct])
00517         tab->file->filter_ptr = &tab->file->filters[filter_index];
00518     tab->file->filters[filter_index] = tab->file->filters[tab->file->filter_ct];
00519 }

static void filter_do_edit ( QlTabData tab,
gint16  filter_index 
) [static]

Lets the user modify the selected filter

Bug:
the filter handling is VERY confused. FIXME.

Bug:
find a new way to handle the filter index
  • passing as a GINT_TO_POINTER is not portable.

Bug:
does this need to be [32] ?

Bug:
The attachment mechanism assumes that a pointer can store 16 bits but not necessarily 32, since some inferior platforms only do 16. So I use 4 bits for line and 12 for field. This allows only 16 lines; the current implementation is for only 6. When this is replaced with GLists of filter lines, this mechanism will have to be re-thought. Probably just go ahead and assume sizeof (void*) >= 4.

Todo:
replace with GList

Definition at line 573 of file filter.c.

00574 {
00575     GtkWidget *edit_dialog, *ok_button, *cancel_button,
00576     *field_selector_menu, *field_selector_menu_item,
00577     *rule_selector_menu, *rule_selector_menu_item,
00578     *entry[MAX_FILTER_NESTING],
00579     *line_hbox[MAX_FILTER_NESTING],
00580     *filter_name, *filter_name_label, *name_hbox, 
00581     *case_check, *boolean_check, *boolean_hbox;
00582 
00583     gint16 line_index;
00584     gint16 field_index;
00585     gint rule_index;
00586 
00587     if (!rules)
00588     {
00589         rules = g_hash_table_new (NULL, NULL);
00590         g_hash_table_insert (rules, GINT_TO_POINTER(IN), 
00591             _("contains"));
00592         g_hash_table_insert (rules, GINT_TO_POINTER(NOT_IN), 
00593             _("does not contain"));
00594         g_hash_table_insert (rules, GINT_TO_POINTER(EXACT), 
00595             _("is exactly"));
00596         g_hash_table_insert (rules, GINT_TO_POINTER(NOT), 
00597             _("is not"));
00598         g_hash_table_insert (rules, GINT_TO_POINTER(LESS), 
00599             _("is less than"));
00600         g_hash_table_insert (rules, GINT_TO_POINTER(MORE), 
00601             _("is more than"));
00602         g_hash_table_insert (rules, GINT_TO_POINTER(BLANK), 
00603             _("is blank"));
00604         g_hash_table_insert (rules, GINT_TO_POINTER(NOT_BLANK), 
00605             _("is not blank"));
00606     }
00607     old_filter = tab->file->filters[filter_index];
00608 
00609     edit_dialog = gtk_dialog_new ();
00610     gtk_window_set_modal (GTK_WINDOW (edit_dialog), TRUE);
00611     gtk_window_set_position (GTK_WINDOW (edit_dialog), GTK_WIN_POS_CENTER);
00612     gtk_window_set_resizable (GTK_WINDOW (edit_dialog), TRUE);
00613     gtk_container_set_border_width (GTK_CONTAINER (edit_dialog), 5);
00614 
00615     gtk_window_set_title (GTK_WINDOW (edit_dialog), _("Filter edit"));
00616 
00617     ok_button = gtk_button_new_from_stock (GTK_STOCK_OK);
00618     gtk_widget_set_name (ok_button, "ok");
00620     g_signal_connect (GTK_OBJECT (ok_button), "clicked",
00621         G_CALLBACK (filter_action), tab);
00622     gtk_widget_show (ok_button);
00623 
00624     cancel_button = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
00625     gtk_widget_set_name (cancel_button, "cancel");
00628 /*  g_signal_connect (GTK_OBJECT (cancel_button), "clicked",
00629         G_CALLBACK (filter_action), GINT_TO_POINTER(filter_index));
00630 */  gtk_widget_show (cancel_button);
00631 
00632 /*  g_signal_connect (GTK_OBJECT (edit_dialog), "delete_event",
00633         G_CALLBACK (filter_action), GINT_TO_POINTER(filter_index));
00634 */
00635     gtk_box_pack_start (GTK_BOX (GTK_DIALOG (edit_dialog)->action_area),
00636         ok_button, FALSE, FALSE, 5);
00637     gtk_box_pack_start (GTK_BOX (GTK_DIALOG (edit_dialog)->action_area),
00638         cancel_button, FALSE, FALSE, 5);
00639 
00640     filter_name = gtk_entry_new ();
00641     gtk_widget_set_name (filter_name, "filter");
00642     filter_name_label = gtk_label_new (_("Filter name"));
00643     boolean_check = gtk_check_button_new_with_label
00644         (_("All of these must be true"));
00645     case_check = gtk_check_button_new_with_label
00646         (_("Text is case-insensitive"));
00647     gtk_widget_set_name (boolean_check, "bool");
00648     gtk_widget_set_name (case_check, "case");
00649 
00650     if (tab->file->filters[filter_index].name != NULL)
00651         gtk_entry_set_text (GTK_ENTRY (filter_name),
00652             tab->file->filters[filter_index].name);
00653     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (boolean_check),
00654         tab->file->filters[filter_index].by_and);
00655     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (case_check),
00656         tab->file->filters[filter_index].use_nocase);
00657 /*  g_signal_connect (GTK_OBJECT (boolean_check), "toggled",
00658         G_CALLBACK (filter_boolean_handler), 
00659         GINT_TO_POINTER (filter_index));
00660     g_signal_connect (GTK_OBJECT (case_check), "toggled",
00661         G_CALLBACK (filter_boolean_handler), 
00662         GINT_TO_POINTER (filter_index));
00663 */
00664     gtk_widget_show (filter_name);
00665     gtk_widget_show (filter_name_label);
00666     gtk_widget_show (boolean_check);
00667     gtk_widget_show (case_check);
00668 
00669     name_hbox = gtk_hbox_new (TRUE, 5);
00670     boolean_hbox = gtk_hbox_new (TRUE, 5);
00671 
00672     gtk_box_pack_start (GTK_BOX (name_hbox), filter_name_label, TRUE, TRUE,
00673         5);
00674     gtk_box_pack_start (GTK_BOX (name_hbox), filter_name, TRUE, TRUE, 5);
00675     gtk_box_pack_start (GTK_BOX (GTK_DIALOG (edit_dialog)->vbox),
00676         name_hbox, TRUE, TRUE, 5);
00677     gtk_widget_show (name_hbox);
00678     gtk_box_pack_start (GTK_BOX (boolean_hbox), boolean_check, TRUE, TRUE,
00679         5);
00680     gtk_box_pack_start (GTK_BOX (boolean_hbox), case_check, TRUE, TRUE, 5);
00681     gtk_box_pack_start (GTK_BOX (GTK_DIALOG (edit_dialog)->vbox),
00682         boolean_hbox, TRUE, TRUE, 5);
00683     gtk_widget_show (boolean_hbox);
00684 
00685     for (line_index = 0; line_index < MAX_FILTER_NESTING; line_index++)
00686     {
00688         gchar nbuf[32];
00689 
00690         line_hbox[line_index] = gtk_hbox_new (TRUE, 5);
00691 
00692         entry[line_index] = gtk_entry_new ();
00693         g_snprintf (nbuf, 32, "%d", line_index);
00694         gtk_widget_set_name (entry[line_index], nbuf);
00695         gtk_entry_set_text (GTK_ENTRY (entry[line_index]),
00696             tab->file->filters[filter_index].line[line_index].compare);
00697 /*      g_signal_connect (GTK_OBJECT (entry[line_index]), "changed",
00698             G_CALLBACK (filter_entry_handler), 
00699             GINT_TO_POINTER (filter_index));
00700 */
00701         field_selector_menu = gtk_menu_new ();
00702 
00712         for (field_index = 0; field_index <= tab->file->last_field + 1;
00713             field_index++)
00714         {
00715             if (!field_index)
00716                 field_selector_menu_item = gtk_menu_item_new_with_label
00717                     (_("--- Unused ---"));
00718             else
00719             {
00720                 QlFieldInfo * field;
00721                 field = ql_get_fieldinfo (tab, (field_index - 1));
00722                 field_selector_menu_item = gtk_menu_item_new_with_label
00723                     (field->name);
00724             }
00725 
00726             gtk_widget_set_name (field_selector_menu_item, "field");
00727             {
00728                 /* workaround */
00729                 gint t;
00730                 t = (line_index << 12) | field_index;
00731                 g_signal_connect (GTK_OBJECT (field_selector_menu_item),
00732                     "activate", G_CALLBACK (filter_menuitem_select), 
00733                     GINT_TO_POINTER (t));
00734             }
00735             gtk_menu_attach (GTK_MENU (field_selector_menu),
00736                 field_selector_menu_item, 0, 1, 0, 1);
00737             if (tab->file->filters[filter_index].line[line_index].field + 1
00738                 == field_index)
00739                 gtk_menu_set_active (GTK_MENU (field_selector_menu),
00740                     field_index);
00741             gtk_widget_show (field_selector_menu_item);
00742         }
00743 //      gtk_option_menu_set_menu ((GtkOptionMenu *) field_selector,
00744 //          field_selector_menu);
00745 //      gtk_widget_show (field_selector);
00746 
00747 /*      gtk_box_pack_start (GTK_BOX (line_hbox[line_index]),
00748                 field_selector, TRUE, TRUE, 5);
00749 */
00750 //      rule_selector = gtk_option_menu_new ();
00751         rule_selector_menu = gtk_menu_new ();
00752 
00753         for (rule_index = FILTER_CONTAINS; rule_index < NOT_BLANK;
00754             rule_index++)
00755         {
00756             rule_selector_menu_item = 
00757                 gtk_menu_item_new_with_label 
00758                 (g_hash_table_lookup (rules, GINT_TO_POINTER(rule_index)));
00759             gtk_widget_set_name (rule_selector_menu_item, "rule");
00760             {
00761                 gint t;
00762                 t = (line_index << 12) | rule_index;
00763                 g_signal_connect (GTK_OBJECT (rule_selector_menu_item),
00764                     "activate", G_CALLBACK (filter_menuitem_select), 
00765                     GINT_TO_POINTER(t));
00766             }
00767             gtk_menu_attach (GTK_MENU (rule_selector_menu),
00768                 rule_selector_menu_item, 0, 1, 0, 1);
00769             if (tab->file->filters[filter_index].line[line_index].type
00770                 == rule_index)
00771                 gtk_menu_set_active (GTK_MENU (rule_selector_menu),
00772                     rule_index);
00773             gtk_widget_show (rule_selector_menu_item);
00774         }
00775 //      gtk_option_menu_set_menu ((GtkOptionMenu *) rule_selector,
00776 //          rule_selector_menu);
00777 //      gtk_widget_show (rule_selector);
00778 
00779 /*      gtk_box_pack_start (GTK_BOX (line_hbox[line_index]),
00780                 rule_selector, TRUE, TRUE, 5);
00781     gtk_widget_show (line_hbox[line_index]);
00782 */
00783         gtk_widget_show (entry[line_index]);
00784         gtk_box_pack_start (GTK_BOX (line_hbox[line_index]),
00785             entry[line_index], TRUE, TRUE, 5);
00786 
00787         gtk_box_pack_start (GTK_BOX (GTK_DIALOG (edit_dialog)->vbox),
00788             line_hbox[line_index], TRUE, TRUE, 5);
00789     }
00790     gtk_widget_show (edit_dialog);
00791 }

static void G_GNUC_UNUSED filter_entry_handler ( GtkWidget *  w,
gpointer  data 
) [static]

Bug:
remove use of widget names as flags

Definition at line 407 of file filter.c.

00408 {
00409     QlContext * qlc;
00410     QlTabData * tab;
00411     gint filter_idx = GPOINTER_TO_INT (data);
00412 
00413     qlc = ql_get_context (GTK_WIDGET(w));
00414     tab = ql_get_tabdata (qlc);
00415 
00416     if (filter_idx < 0 || !gtk_widget_get_name (w))
00417     {
00418         level2_error (tab, _("** PANIC ** in _filter_entry_handler"));
00419         return;
00420     }
00421     if (!strcmp (gtk_widget_get_name (w), "filter"))
00422     {
00423         strncpy (tab->file->filters[filter_idx].name,
00424             gtk_entry_get_text (GTK_ENTRY (w)),
00425             sizeof (tab->file->filters[filter_idx].name));
00426     }
00427     else
00428     {
00430 /*      gint line_idx = atoi (gtk_widget_get_name (w));
00431         strncpy (tab->file->filters[filter_idx].line[line_idx].compare,
00432             gtk_entry_get_text (GTK_ENTRY (w)), sizeof
00433             (tab->file->filters[filter_idx].line[line_idx].compare));
00434 */  }
00435 }

static void filter_menuitem_select ( GtkWidget *  w,
gpointer  data 
) [static]

Handle the selection of a menu item. Since the only menuitems we work with are in the add/edit field select and rule select operations, we just do all of them right here.

Todo:
these casts stink. replace.

Definition at line 462 of file filter.c.

00463 {
00464     QlContext * qlc;
00465     QlTabData * tab;
00466     gchar *name;
00467     gint16 line;
00468 
00469     qlc = ql_get_context (w);
00470     tab = ql_get_tabdata (qlc);
00471     name = g_strdup (gtk_widget_get_name (w));
00472     line = (*(gint16 *) (data) & (gint16) 0xf000) >> 12;
00473     if (!strcmp (name, "field"))
00474     {
00475         gint16 field = *(gint16 *) (data) & (gint16) 0x0fff;
00476         tab->file->filters[working_idx].line[line].field = field - 1;
00477     }
00478     if (!strcmp (name, "rule"))
00479     {
00480         gint16 rule = *(gint16 *) (data) & (gint16) 0x0fff;
00481         tab->file->filters[working_idx].line[line].type = rule;
00482     }
00483 }

static void filter_select ( QlTabData tab,
QlFilterMode G_GNUC_UNUSED  mode 
) [static]

This is roughly adapted from the sort selection dialog in sort.c.

Todo:
complete migration to Gtk2.

Definition at line 232 of file filter.c.

00233 {
00234     /* Selects a filter to work with and places its index 
00235     in working_idx */
00236     GtkWidget *fsel_dialog, *cancel_button, *scroll_w;
00237     GtkWidget *tree_hbox, * ok_button;
00238     gchar *select_entries[2] = { "", NULL };
00239     gint16 idx;
00240     guint width;
00241     GtkTreeView * treeview;
00242     GtkTreeModel * model;
00243     GtkTreeStore * treestore;
00244     GtkTreeIter parent_iter, child_iter;
00245     GtkCellRenderer *renderer;
00246     GtkTreeViewColumn *column;
00247     GtkTreeSortable * sort;
00248     GtkTreeSelection * fselect;
00249 
00250     fsel_dialog = gtk_dialog_new ();
00251     gtk_window_set_modal (GTK_WINDOW (fsel_dialog), TRUE);
00252     gtk_window_set_position (GTK_WINDOW (fsel_dialog), GTK_WIN_POS_CENTER);
00253     gtk_window_set_resizable (GTK_WINDOW (fsel_dialog), TRUE);
00254     gtk_container_set_border_width (GTK_CONTAINER (fsel_dialog), 5);
00255 
00256     width = 0;
00257     gtk_window_set_title (GTK_WINDOW (fsel_dialog), _("Select a filter"));
00258     g_signal_connect (GTK_OBJECT (fsel_dialog), "delete_event",
00259         G_CALLBACK(close_dlg), fsel_dialog);
00260 
00261     ok_button = gtk_button_new_from_stock (GTK_STOCK_OK);
00262     gtk_box_pack_start (GTK_BOX (GTK_DIALOG (fsel_dialog)->action_area),
00263         ok_button, TRUE, TRUE, 0);
00264     gtk_widget_show (ok_button);
00265 /*  g_signal_connect (GTK_OBJECT (ok_button), "clicked",
00266         G_CALLBACK (add_ok), NULL);*/
00267 
00268     cancel_button = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
00269     g_signal_connect (GTK_OBJECT (cancel_button), "clicked",
00270         G_CALLBACK(close_dlg), fsel_dialog);
00271     gtk_box_pack_start (GTK_BOX (GTK_DIALOG (fsel_dialog)->action_area),
00272         cancel_button, FALSE, FALSE, 0);
00273     gtk_widget_show (cancel_button);
00274 
00275     gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (fsel_dialog)->vbox), 10);
00276 
00277     tree_hbox = gtk_hbox_new (FALSE, 5);
00278     gtk_box_pack_start (GTK_BOX (GTK_DIALOG (fsel_dialog)->vbox),
00279         tree_hbox, TRUE, TRUE, 0);
00280 
00281     treeview = GTK_TREE_VIEW (gtk_tree_view_new ());
00282     model = gtk_tree_view_get_model (treeview);
00283     treestore = gtk_tree_store_new (SINGLE_COL, G_TYPE_STRING);
00284     sort = GTK_TREE_SORTABLE (treestore);
00285     gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), 
00286         GTK_TREE_MODEL (sort));
00287     gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (treeview), TRUE);
00288     gtk_tree_view_set_reorderable (GTK_TREE_VIEW (treeview), TRUE);
00289     gtk_tree_store_append (treestore, &parent_iter, NULL);
00290     gtk_tree_store_set (treestore, &parent_iter, FILTER_COL,
00291         _("Available columns"), -1);
00292     renderer = gtk_cell_renderer_text_new ();
00293     column = gtk_tree_view_column_new_with_attributes
00294         (_("Column Name"), renderer, "text", FILTER_COL, NULL);
00295     gtk_tree_view_column_set_sort_column_id (column, FROM_COL);
00296     gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
00297     fselect = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
00298     gtk_tree_selection_set_mode (GTK_TREE_SELECTION(fselect), GTK_SELECTION_SINGLE);
00299 
00300     scroll_w = gtk_scrolled_window_new (NULL, NULL);
00301     gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll_w),
00302         GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
00303     gtk_container_set_border_width (GTK_CONTAINER (scroll_w), 5);
00304     gtk_container_add (GTK_CONTAINER (scroll_w), 
00305         GTK_WIDGET(treeview));
00306 
00307     gtk_box_pack_start (GTK_BOX (tree_hbox), scroll_w, TRUE, TRUE, 0);
00308 
00309     /* now populate the treeview with filter names */
00310     for (idx = 0; idx < tab->file->filter_ct; idx++)
00311     {
00312         select_entries[0] = tab->file->filters[idx].name;
00313         gtk_tree_store_append (treestore, &child_iter, &parent_iter);
00314         gtk_tree_store_set (treestore, &child_iter, FILTER_COL, 
00315             select_entries[0], -1);
00316         width = (strlen(select_entries[0]) > width) ? 
00317             strlen(select_entries[0]) : width;
00318     }
00319     gtk_widget_set_size_request (GTK_WIDGET(treeview), 
00320         width + 200, 200);
00321     gtk_tree_view_expand_all (GTK_TREE_VIEW(treeview));
00322     gtk_widget_show_all (fsel_dialog);
00323 }


Variable Documentation

GHashTable* rules = NULL [static]

Todo:
move elsewhere and handle init and clean up separately.

Definition at line 569 of file filter.c.


Generated on Mon Jan 28 22:02:11 2008 for quicklist by  doxygen 1.5.4