Added e-table-search.lo.
2002-03-12 Christopher James Lahey <clahey@ximian.com> * gal/Makefile.am (libgal_la_LIBADD): Added e-table-search.lo. * gal/util/e-util.c, gal/util/e-util.h (e_marshal_BOOL__STRING): Added this marshal function. From gal/e-table/ChangeLog: 2002-03-12 Christopher James Lahey <clahey@ximian.com> * Makefile.am (libetable_la_SOURCES): Added e-table-search.c. (libetableinclude_HEADERS): Added e-table-search.h. * e-cell.h: Added ETableSearchFun here. * e-table-col.h: Added search here. * e-table-column-specification.c, e-table-column-specification.h: Added search here. * e-table-extras.c, e-table-extras.h (e_table_extras_add_search): Added ETableSearchFuncs here. * e-table-memory-store.c (e_table_memory_store_insert, e_table_memory_store_insert_adopt): Handle row == -1 here. * e-table-search.c, e-table-search.h: New class to reusably handle the semantics of searching for a string. * e-table-simple.c, e-table-simple.h: Added a bunch of simple functions here for if your table is all strings. Should be reusable. * e-table-utils.c (et_col_spec_to_col): Added support for searches here. * e-table.c, e-table.h: Added an ETableSearch here. svn path=/trunk/; revision=16119
This commit is contained in:
committed by
Chris Lahey
parent
8358586161
commit
fd4ffbd38c
@ -834,6 +834,27 @@ e_marshal_NONE__DOUBLE (GtkObject *object,
|
||||
func_data);
|
||||
}
|
||||
|
||||
typedef gboolean (*GtkSignal_BOOL__STRING) (GtkObject *,
|
||||
char *,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
e_marshal_BOOL__STRING (GtkObject *object,
|
||||
GtkSignalFunc func,
|
||||
gpointer func_data,
|
||||
GtkArg *args)
|
||||
{
|
||||
GtkSignal_BOOL__STRING rfunc;
|
||||
gboolean *return_val;
|
||||
|
||||
rfunc = (GtkSignal_BOOL__STRING) func;
|
||||
return_val = GTK_RETLOC_BOOL (args[1]);
|
||||
|
||||
*return_val = (*rfunc) (object,
|
||||
GTK_VALUE_STRING (args[0]),
|
||||
func_data);
|
||||
}
|
||||
|
||||
gchar**
|
||||
e_strsplit (const gchar *string,
|
||||
const gchar *delimiter,
|
||||
|
||||
@ -277,6 +277,10 @@ void e_marshal_NONE__DOUBLE (GtkO
|
||||
GtkSignalFunc func,
|
||||
gpointer func_data,
|
||||
GtkArg *args);
|
||||
void e_marshal_BOOL__STRING (GtkObject *object,
|
||||
GtkSignalFunc func,
|
||||
gpointer func_data,
|
||||
GtkArg *args);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@ -39,6 +39,9 @@ BEGIN_GNOME_DECLS
|
||||
#define E_IS_CELL(o) (GTK_CHECK_TYPE ((o), E_CELL_TYPE))
|
||||
#define E_IS_CELL_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_CELL_TYPE))
|
||||
|
||||
typedef gboolean (*ETableSearchFunc) (gconstpointer haystack,
|
||||
const char *needle);
|
||||
|
||||
typedef enum {
|
||||
E_CELL_SELECTED = 1 << 0,
|
||||
|
||||
|
||||
@ -47,26 +47,27 @@ typedef enum {
|
||||
* Information about a single column
|
||||
*/
|
||||
typedef struct {
|
||||
GtkObject base;
|
||||
char *text;
|
||||
GdkPixbuf *pixbuf;
|
||||
int min_width;
|
||||
int width;
|
||||
double expansion;
|
||||
short x;
|
||||
GCompareFunc compare;
|
||||
unsigned int is_pixbuf:1;
|
||||
unsigned int selected:1;
|
||||
unsigned int resizable:1;
|
||||
unsigned int disabled:1;
|
||||
unsigned int sortable:1;
|
||||
unsigned int groupable:1;
|
||||
int col_idx;
|
||||
int priority;
|
||||
GtkObject base;
|
||||
char *text;
|
||||
GdkPixbuf *pixbuf;
|
||||
int min_width;
|
||||
int width;
|
||||
double expansion;
|
||||
short x;
|
||||
GCompareFunc compare;
|
||||
ETableSearchFunc search;
|
||||
unsigned int is_pixbuf:1;
|
||||
unsigned int selected:1;
|
||||
unsigned int resizable:1;
|
||||
unsigned int disabled:1;
|
||||
unsigned int sortable:1;
|
||||
unsigned int groupable:1;
|
||||
int col_idx;
|
||||
int priority;
|
||||
|
||||
GtkJustification justification;
|
||||
GtkJustification justification;
|
||||
|
||||
ECell *ecell;
|
||||
ECell *ecell;
|
||||
} ETableCol;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@ -41,6 +41,7 @@ free_strings (ETableColumnSpecification *etcs)
|
||||
g_free(etcs->pixbuf);
|
||||
g_free(etcs->cell);
|
||||
g_free(etcs->compare);
|
||||
g_free(etcs->search);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -75,6 +76,7 @@ etcs_init (ETableColumnSpecification *specification)
|
||||
|
||||
specification->cell = NULL;
|
||||
specification->compare = NULL;
|
||||
specification->search = NULL;
|
||||
specification->priority = 0;
|
||||
}
|
||||
|
||||
@ -105,6 +107,7 @@ e_table_column_specification_load_from_node (ETableColumnSpecification *etcs,
|
||||
|
||||
etcs->cell = e_xml_get_string_prop_by_name (node, "cell");
|
||||
etcs->compare = e_xml_get_string_prop_by_name (node, "compare");
|
||||
etcs->search = e_xml_get_string_prop_by_name (node, "search");
|
||||
etcs->priority = e_xml_get_integer_prop_by_name_with_default (node, "priority", 0);
|
||||
|
||||
if (etcs->title == NULL)
|
||||
@ -132,6 +135,7 @@ e_table_column_specification_save_to_node (ETableColumnSpecification *specificat
|
||||
|
||||
e_xml_set_string_prop_by_name(node, "cell", specification->cell);
|
||||
e_xml_set_string_prop_by_name(node, "compare", specification->compare);
|
||||
e_xml_set_string_prop_by_name(node, "search", specification->search);
|
||||
if (specification->priority != 0)
|
||||
e_xml_set_integer_prop_by_name (node, "priority", specification->priority);
|
||||
|
||||
|
||||
@ -52,6 +52,7 @@ typedef struct {
|
||||
|
||||
char *cell;
|
||||
char *compare;
|
||||
char *search;
|
||||
int priority;
|
||||
} ETableColumnSpecification;
|
||||
|
||||
|
||||
@ -33,6 +33,7 @@
|
||||
#include "gal/e-table/e-cell-size.h"
|
||||
#include "gal/e-table/e-cell-tree.h"
|
||||
#include "e-table-extras.h"
|
||||
#include <string.h>
|
||||
|
||||
#define PARENT_TYPE (gtk_object_get_type())
|
||||
|
||||
@ -65,14 +66,17 @@ ete_destroy (GtkObject *object)
|
||||
|
||||
g_hash_table_foreach (ete->cells, (GHFunc) cell_hash_free, NULL);
|
||||
g_hash_table_foreach (ete->compares, (GHFunc) g_free, NULL);
|
||||
g_hash_table_foreach (ete->searches, (GHFunc) g_free, NULL);
|
||||
g_hash_table_foreach (ete->pixbufs, (GHFunc) pixbuf_hash_free, NULL);
|
||||
|
||||
g_hash_table_destroy (ete->cells);
|
||||
g_hash_table_destroy (ete->compares);
|
||||
g_hash_table_destroy (ete->searches);
|
||||
g_hash_table_destroy (ete->pixbufs);
|
||||
|
||||
ete->cells = NULL;
|
||||
ete->compares = NULL;
|
||||
ete->searches = NULL;
|
||||
ete->pixbufs = NULL;
|
||||
|
||||
GTK_OBJECT_CLASS (ete_parent_class)->destroy (object);
|
||||
@ -95,17 +99,30 @@ e_strint_compare(gconstpointer data1, gconstpointer data2)
|
||||
return g_int_compare(GINT_TO_POINTER(int1), GINT_TO_POINTER(int2));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
e_string_search(gconstpointer haystack, const char *needle)
|
||||
{
|
||||
int length = g_utf8_strlen (needle, -1);
|
||||
if (g_utf8_strncasecmp (haystack, needle, length) == 0)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
ete_init (ETableExtras *extras)
|
||||
{
|
||||
extras->cells = g_hash_table_new(g_str_hash, g_str_equal);
|
||||
extras->compares = g_hash_table_new(g_str_hash, g_str_equal);
|
||||
extras->searches = g_hash_table_new(g_str_hash, g_str_equal);
|
||||
extras->pixbufs = g_hash_table_new(g_str_hash, g_str_equal);
|
||||
|
||||
e_table_extras_add_compare(extras, "string", g_str_compare);
|
||||
e_table_extras_add_compare(extras, "integer", g_int_compare);
|
||||
e_table_extras_add_compare(extras, "string-integer", e_strint_compare);
|
||||
|
||||
e_table_extras_add_search(extras, "string", e_string_search);
|
||||
|
||||
e_table_extras_add_cell(extras, "checkbox", e_cell_checkbox_new());
|
||||
e_table_extras_add_cell(extras, "date", e_cell_date_new (NULL, GTK_JUSTIFY_LEFT));
|
||||
e_table_extras_add_cell(extras, "number", e_cell_number_new (NULL, GTK_JUSTIFY_RIGHT));
|
||||
@ -162,8 +179,8 @@ e_table_extras_add_compare (ETableExtras *extras,
|
||||
gchar *old_key;
|
||||
GCompareFunc old_compare;
|
||||
|
||||
if (g_hash_table_lookup_extended (extras->cells, id, (gpointer *)&old_key, (gpointer *)&old_compare)) {
|
||||
g_hash_table_remove (extras->cells, old_key);
|
||||
if (g_hash_table_lookup_extended (extras->compares, id, (gpointer *)&old_key, (gpointer *)&old_compare)) {
|
||||
g_hash_table_remove (extras->compares, old_key);
|
||||
g_free (old_key);
|
||||
}
|
||||
|
||||
@ -177,6 +194,29 @@ e_table_extras_get_compare (ETableExtras *extras,
|
||||
return g_hash_table_lookup(extras->compares, id);
|
||||
}
|
||||
|
||||
void
|
||||
e_table_extras_add_search (ETableExtras *extras,
|
||||
char *id,
|
||||
ETableSearchFunc search)
|
||||
{
|
||||
gchar *old_key;
|
||||
ETableSearchFunc old_search;
|
||||
|
||||
if (g_hash_table_lookup_extended (extras->searches, id, (gpointer *)&old_key, (gpointer *)&old_search)) {
|
||||
g_hash_table_remove (extras->searches, old_key);
|
||||
g_free (old_key);
|
||||
}
|
||||
|
||||
g_hash_table_insert(extras->searches, g_strdup(id), search);
|
||||
}
|
||||
|
||||
ETableSearchFunc
|
||||
e_table_extras_get_search (ETableExtras *extras,
|
||||
char *id)
|
||||
{
|
||||
return g_hash_table_lookup(extras->searches, id);
|
||||
}
|
||||
|
||||
void
|
||||
e_table_extras_add_pixbuf (ETableExtras *extras,
|
||||
char *id,
|
||||
|
||||
@ -43,32 +43,39 @@ typedef struct {
|
||||
GHashTable *cells;
|
||||
GHashTable *compares;
|
||||
GHashTable *pixbufs;
|
||||
GHashTable *searches;
|
||||
} ETableExtras;
|
||||
|
||||
typedef struct {
|
||||
GtkObjectClass parent_class;
|
||||
} ETableExtrasClass;
|
||||
|
||||
GtkType e_table_extras_get_type (void);
|
||||
ETableExtras *e_table_extras_new (void);
|
||||
GtkType e_table_extras_get_type (void);
|
||||
ETableExtras *e_table_extras_new (void);
|
||||
|
||||
void e_table_extras_add_cell (ETableExtras *extras,
|
||||
char *id,
|
||||
ECell *cell);
|
||||
ECell *e_table_extras_get_cell (ETableExtras *extras,
|
||||
char *id);
|
||||
void e_table_extras_add_cell (ETableExtras *extras,
|
||||
char *id,
|
||||
ECell *cell);
|
||||
ECell *e_table_extras_get_cell (ETableExtras *extras,
|
||||
char *id);
|
||||
|
||||
void e_table_extras_add_compare (ETableExtras *extras,
|
||||
char *id,
|
||||
GCompareFunc compare);
|
||||
GCompareFunc e_table_extras_get_compare (ETableExtras *extras,
|
||||
char *id);
|
||||
void e_table_extras_add_compare (ETableExtras *extras,
|
||||
char *id,
|
||||
GCompareFunc compare);
|
||||
GCompareFunc e_table_extras_get_compare (ETableExtras *extras,
|
||||
char *id);
|
||||
|
||||
void e_table_extras_add_pixbuf (ETableExtras *extras,
|
||||
char *id,
|
||||
GdkPixbuf *pixbuf);
|
||||
GdkPixbuf *e_table_extras_get_pixbuf (ETableExtras *extras,
|
||||
char *id);
|
||||
void e_table_extras_add_search (ETableExtras *extras,
|
||||
char *id,
|
||||
ETableSearchFunc search);
|
||||
ETableSearchFunc e_table_extras_get_search (ETableExtras *extras,
|
||||
char *id);
|
||||
|
||||
void e_table_extras_add_pixbuf (ETableExtras *extras,
|
||||
char *id,
|
||||
GdkPixbuf *pixbuf);
|
||||
GdkPixbuf *e_table_extras_get_pixbuf (ETableExtras *extras,
|
||||
char *id);
|
||||
|
||||
END_GNOME_DECLS
|
||||
|
||||
|
||||
@ -320,7 +320,10 @@ e_table_memory_store_insert (ETableMemoryStore *etms, int row, void **store, gpo
|
||||
int i;
|
||||
|
||||
e_table_memory_insert (E_TABLE_MEMORY (etms), row, data);
|
||||
|
||||
row_count = e_table_model_row_count (E_TABLE_MODEL (etms));
|
||||
if (row == -1)
|
||||
row = row_count - 1;
|
||||
etms->priv->store = g_realloc (etms->priv->store, etms->priv->col_count * row_count * sizeof (void *));
|
||||
memmove (etms->priv->store + etms->priv->col_count * (row + 1),
|
||||
etms->priv->store + etms->priv->col_count * row,
|
||||
@ -357,14 +360,15 @@ e_table_memory_store_insert_adopt (ETableMemoryStore *etms, int row, void **stor
|
||||
int row_count;
|
||||
int i;
|
||||
|
||||
row_count = e_table_model_row_count (E_TABLE_MODEL (etms));
|
||||
|
||||
e_table_memory_insert (E_TABLE_MEMORY (etms), row, data);
|
||||
|
||||
etms->priv->store = g_realloc (etms->priv->store, etms->priv->col_count * (row_count + 1) * sizeof (void *));
|
||||
row_count = e_table_model_row_count (E_TABLE_MODEL (etms));
|
||||
if (row == -1)
|
||||
row = row_count - 1;
|
||||
etms->priv->store = g_realloc (etms->priv->store, etms->priv->col_count * row_count * sizeof (void *));
|
||||
memmove (etms->priv->store + etms->priv->col_count * (row + 1),
|
||||
etms->priv->store + etms->priv->col_count * row,
|
||||
etms->priv->col_count * (row_count - row) * sizeof (void *));
|
||||
etms->priv->col_count * (row_count - row - 1) * sizeof (void *));
|
||||
|
||||
for (i = 0; i < etms->priv->col_count; i++) {
|
||||
STORE_LOCATOR(etms, i, row) = store[i];
|
||||
|
||||
219
widgets/table/e-table-search.c
Normal file
219
widgets/table/e-table-search.c
Normal file
@ -0,0 +1,219 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
|
||||
/*
|
||||
* e-table-search.c
|
||||
* Copyright 2000, 2001, Ximian, Inc.
|
||||
*
|
||||
* Authors:
|
||||
* Chris Lahey <clahey@ximian.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License, version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <gtk/gtksignal.h>
|
||||
#include "e-table-search.h"
|
||||
#include "gal/util/e-util.h"
|
||||
|
||||
#define ETS_CLASS(e) ((ETableSearchClass *)((GtkObject *)e)->klass)
|
||||
|
||||
#define PARENT_TYPE gtk_object_get_type ()
|
||||
|
||||
#define d(x)
|
||||
|
||||
d(static gint depth = 0);
|
||||
|
||||
struct _ETableSearchPrivate {
|
||||
guint timeout_id;
|
||||
|
||||
char *search_string;
|
||||
gunichar last_character;
|
||||
};
|
||||
|
||||
static GtkObjectClass *e_table_search_parent_class;
|
||||
|
||||
enum {
|
||||
SEARCH_SEARCH,
|
||||
SEARCH_ACCEPT,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint e_table_search_signals [LAST_SIGNAL] = { 0, };
|
||||
|
||||
static gboolean
|
||||
e_table_search_search (ETableSearch *e_table_search, char *string)
|
||||
{
|
||||
gboolean ret_val;
|
||||
g_return_val_if_fail (e_table_search != NULL, FALSE);
|
||||
g_return_val_if_fail (E_IS_TABLE_SEARCH (e_table_search), FALSE);
|
||||
|
||||
gtk_signal_emit (GTK_OBJECT (e_table_search),
|
||||
e_table_search_signals [SEARCH_SEARCH], string, &ret_val);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
static void
|
||||
e_table_search_accept (ETableSearch *e_table_search)
|
||||
{
|
||||
g_return_if_fail (e_table_search != NULL);
|
||||
g_return_if_fail (E_IS_TABLE_SEARCH (e_table_search));
|
||||
|
||||
gtk_signal_emit (GTK_OBJECT (e_table_search),
|
||||
e_table_search_signals [SEARCH_ACCEPT]);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ets_accept (gpointer data)
|
||||
{
|
||||
ETableSearch *ets = data;
|
||||
e_table_search_accept (ets);
|
||||
g_free (ets->priv->search_string);
|
||||
|
||||
ets->priv->timeout_id = 0;
|
||||
ets->priv->search_string = g_strdup ("");
|
||||
ets->priv->last_character = 0;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
drop_timeout (ETableSearch *ets)
|
||||
{
|
||||
if (ets->priv->timeout_id) {
|
||||
g_source_remove (ets->priv->timeout_id);
|
||||
}
|
||||
ets->priv->timeout_id = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
add_timeout (ETableSearch *ets)
|
||||
{
|
||||
drop_timeout (ets);
|
||||
ets->priv->timeout_id = g_timeout_add (1000, ets_accept, ets);
|
||||
}
|
||||
|
||||
static void
|
||||
e_table_search_destroy (GtkObject *object)
|
||||
{
|
||||
if (e_table_search_parent_class->destroy)
|
||||
(*e_table_search_parent_class->destroy)(object);
|
||||
}
|
||||
|
||||
static void
|
||||
e_table_search_class_init (GtkObjectClass *object_class)
|
||||
{
|
||||
ETableSearchClass *klass = E_TABLE_SEARCH_CLASS(object_class);
|
||||
e_table_search_parent_class = gtk_type_class (PARENT_TYPE);
|
||||
|
||||
object_class->destroy = e_table_search_destroy;
|
||||
|
||||
e_table_search_signals [SEARCH_SEARCH] =
|
||||
gtk_signal_new ("search",
|
||||
GTK_RUN_LAST,
|
||||
E_OBJECT_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (ETableSearchClass, search),
|
||||
e_marshal_BOOL__STRING,
|
||||
GTK_TYPE_BOOL, 1, GTK_TYPE_STRING);
|
||||
|
||||
e_table_search_signals [SEARCH_ACCEPT] =
|
||||
gtk_signal_new ("accept",
|
||||
GTK_RUN_LAST,
|
||||
E_OBJECT_CLASS_TYPE (object_class),
|
||||
GTK_SIGNAL_OFFSET (ETableSearchClass, accept),
|
||||
gtk_marshal_NONE__NONE,
|
||||
GTK_TYPE_NONE, 0);
|
||||
|
||||
E_OBJECT_CLASS_ADD_SIGNALS (object_class, e_table_search_signals, LAST_SIGNAL);
|
||||
|
||||
klass->search = NULL;
|
||||
klass->accept = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
e_table_search_init (ETableSearch *ets)
|
||||
{
|
||||
ets->priv = g_new (ETableSearchPrivate, 1);
|
||||
|
||||
ets->priv->timeout_id = 0;
|
||||
ets->priv->search_string = g_strdup ("");
|
||||
ets->priv->last_character = 0;
|
||||
}
|
||||
|
||||
|
||||
guint
|
||||
e_table_search_get_type (void)
|
||||
{
|
||||
static guint type = 0;
|
||||
|
||||
if (!type)
|
||||
{
|
||||
GtkTypeInfo info =
|
||||
{
|
||||
"ETableSearch",
|
||||
sizeof (ETableSearch),
|
||||
sizeof (ETableSearchClass),
|
||||
(GtkClassInitFunc) e_table_search_class_init,
|
||||
(GtkObjectInitFunc) e_table_search_init,
|
||||
/* reserved_1 */ NULL,
|
||||
/* reserved_2 */ NULL,
|
||||
(GtkClassInitFunc) NULL,
|
||||
};
|
||||
|
||||
type = gtk_type_unique (PARENT_TYPE, &info);
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
ETableSearch *
|
||||
e_table_search_new (void)
|
||||
{
|
||||
ETableSearch *ets = gtk_type_new (e_table_search_get_type());
|
||||
|
||||
return ets;
|
||||
}
|
||||
|
||||
/**
|
||||
* e_table_search_column_count:
|
||||
* @e_table_search: The e-table-search to operate on
|
||||
*
|
||||
* Returns: the number of columns in the table search.
|
||||
*/
|
||||
void
|
||||
e_table_search_input_character (ETableSearch *ets, gunichar character)
|
||||
{
|
||||
char character_utf8[7];
|
||||
|
||||
g_return_if_fail (ets != NULL);
|
||||
g_return_if_fail (E_IS_TABLE_SEARCH (ets));
|
||||
|
||||
character_utf8 [g_unichar_to_utf8 (character, character_utf8)] = 0;
|
||||
|
||||
if (character != ets->priv->last_character) {
|
||||
char *temp_string;
|
||||
temp_string = g_strdup_printf ("%s%s", ets->priv->search_string, character_utf8);
|
||||
if (e_table_search_search (ets, temp_string)) {
|
||||
g_free (ets->priv->search_string);
|
||||
ets->priv->search_string = temp_string;
|
||||
add_timeout (ets);
|
||||
} else {
|
||||
g_free (temp_string);
|
||||
}
|
||||
} else {
|
||||
e_table_search_search (ets, ets->priv->search_string);
|
||||
add_timeout (ets);
|
||||
}
|
||||
ets->priv->last_character = character;
|
||||
}
|
||||
68
widgets/table/e-table-search.h
Normal file
68
widgets/table/e-table-search.h
Normal file
@ -0,0 +1,68 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
|
||||
/*
|
||||
* e-table-search.h
|
||||
* Copyright 2000, 2001, Ximian, Inc.
|
||||
*
|
||||
* Authors:
|
||||
* Chris Lahey <clahey@ximian.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License, version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _E_TABLE_SEARCH_H_
|
||||
#define _E_TABLE_SEARCH_H_
|
||||
|
||||
#include <gtk/gtkobject.h>
|
||||
#include <libgnome/gnome-defs.h>
|
||||
#include <gal/unicode/gunicode.h>
|
||||
|
||||
BEGIN_GNOME_DECLS
|
||||
|
||||
#define E_TABLE_SEARCH_TYPE (e_table_search_get_type ())
|
||||
#define E_TABLE_SEARCH(o) (GTK_CHECK_CAST ((o), E_TABLE_SEARCH_TYPE, ETableSearch))
|
||||
#define E_TABLE_SEARCH_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_TABLE_SEARCH_TYPE, ETableSearchClass))
|
||||
#define E_IS_TABLE_SEARCH(o) (GTK_CHECK_TYPE ((o), E_TABLE_SEARCH_TYPE))
|
||||
#define E_IS_TABLE_SEARCH_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_SEARCH_TYPE))
|
||||
|
||||
typedef struct _ETableSearchPrivate ETableSearchPrivate;
|
||||
|
||||
typedef struct {
|
||||
GtkObject base;
|
||||
|
||||
ETableSearchPrivate *priv;
|
||||
} ETableSearch;
|
||||
|
||||
typedef struct {
|
||||
GtkObjectClass parent_class;
|
||||
|
||||
/*
|
||||
* Signals
|
||||
*/
|
||||
gboolean (*search) (ETableSearch *ets, char *string /* utf8 */);
|
||||
void (*accept) (ETableSearch *ets);
|
||||
void (*cancelled) (ETableSearch *ets);
|
||||
} ETableSearchClass;
|
||||
|
||||
GtkType e_table_search_get_type (void);
|
||||
ETableSearch *e_table_search_new (void);
|
||||
|
||||
/**/
|
||||
void e_table_search_input_character (ETableSearch *e_table_search,
|
||||
gunichar character);
|
||||
void e_table_search_cancel (ETableSearch *e_table_search);
|
||||
|
||||
END_GNOME_DECLS
|
||||
|
||||
#endif /* _E_TABLE_SEARCH_H_ */
|
||||
@ -281,3 +281,33 @@ e_table_simple_new (ETableSimpleColumnCountFn col_count,
|
||||
|
||||
return (ETableModel *) et;
|
||||
}
|
||||
|
||||
void *
|
||||
e_table_simple_string_duplicate_value (ETableModel *etm, int col, const void *val, void *data)
|
||||
{
|
||||
return g_strdup (val);
|
||||
}
|
||||
|
||||
void
|
||||
e_table_simple_string_free_value (ETableModel *etm, int col, void *val, void *data)
|
||||
{
|
||||
g_free (val);
|
||||
}
|
||||
|
||||
void *
|
||||
e_table_simple_string_initialize_value (ETableModel *etm, int col, void *data)
|
||||
{
|
||||
return g_strdup ("");
|
||||
}
|
||||
|
||||
gboolean
|
||||
e_table_simple_string_value_is_empty (ETableModel *etm, int col, const void *val, void *data)
|
||||
{
|
||||
return !(val && * (char *) val);
|
||||
}
|
||||
|
||||
char *
|
||||
e_table_simple_string_value_to_string (ETableModel *etm, int col, const void *val, void *data)
|
||||
{
|
||||
return g_strdup (val);
|
||||
}
|
||||
|
||||
@ -26,10 +26,9 @@
|
||||
#define _E_TABLE_SIMPLE_H_
|
||||
|
||||
#include <gal/e-table/e-table-model.h>
|
||||
#include <libgnome/gnome-defs.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
BEGIN_GNOME_DECLS
|
||||
|
||||
#define E_TABLE_SIMPLE_TYPE (e_table_simple_get_type ())
|
||||
#define E_TABLE_SIMPLE(o) (GTK_CHECK_CAST ((o), E_TABLE_SIMPLE_TYPE, ETableSimple))
|
||||
@ -72,7 +71,7 @@ typedef struct {
|
||||
ETableSimpleFreeValueFn free_value;
|
||||
ETableSimpleInitializeValueFn initialize_value;
|
||||
ETableSimpleValueIsEmptyFn value_is_empty;
|
||||
ETableSimpleValueToStringFn value_to_string;
|
||||
ETableSimpleValueToStringFn value_to_string;
|
||||
void *data;
|
||||
} ETableSimple;
|
||||
|
||||
@ -80,29 +79,45 @@ typedef struct {
|
||||
ETableModelClass parent_class;
|
||||
} ETableSimpleClass;
|
||||
|
||||
GtkType e_table_simple_get_type (void);
|
||||
GtkType e_table_simple_get_type (void);
|
||||
ETableModel *e_table_simple_new (ETableSimpleColumnCountFn col_count,
|
||||
ETableSimpleRowCountFn row_count,
|
||||
ETableSimpleAppendRowFn append_row,
|
||||
ETableSimpleValueAtFn value_at,
|
||||
ETableSimpleSetValueAtFn set_value_at,
|
||||
ETableSimpleIsCellEditableFn is_cell_editable,
|
||||
ETableSimpleHasSaveIdFn has_save_id,
|
||||
ETableSimpleGetSaveIdFn get_save_id,
|
||||
ETableSimpleDuplicateValueFn duplicate_value,
|
||||
ETableSimpleFreeValueFn free_value,
|
||||
ETableSimpleInitializeValueFn initialize_value,
|
||||
ETableSimpleValueIsEmptyFn value_is_empty,
|
||||
ETableSimpleValueToStringFn value_to_string,
|
||||
void *data);
|
||||
|
||||
ETableModel *e_table_simple_new (ETableSimpleColumnCountFn col_count,
|
||||
ETableSimpleRowCountFn row_count,
|
||||
ETableSimpleAppendRowFn append_row,
|
||||
|
||||
ETableSimpleValueAtFn value_at,
|
||||
ETableSimpleSetValueAtFn set_value_at,
|
||||
ETableSimpleIsCellEditableFn is_cell_editable,
|
||||
/* Helper functions for if your values are all just strings. */
|
||||
void *e_table_simple_string_duplicate_value (ETableModel *etm,
|
||||
int col,
|
||||
const void *val,
|
||||
void *data);
|
||||
void e_table_simple_string_free_value (ETableModel *etm,
|
||||
int col,
|
||||
void *val,
|
||||
void *data);
|
||||
void *e_table_simple_string_initialize_value (ETableModel *etm,
|
||||
int col,
|
||||
void *data);
|
||||
gboolean e_table_simple_string_value_is_empty (ETableModel *etm,
|
||||
int col,
|
||||
const void *val,
|
||||
void *data);
|
||||
char *e_table_simple_string_value_to_string (ETableModel *etm,
|
||||
int col,
|
||||
const void *val,
|
||||
void *data);
|
||||
|
||||
ETableSimpleHasSaveIdFn has_save_id,
|
||||
ETableSimpleGetSaveIdFn get_save_id,
|
||||
|
||||
ETableSimpleDuplicateValueFn duplicate_value,
|
||||
ETableSimpleFreeValueFn free_value,
|
||||
ETableSimpleInitializeValueFn initialize_value,
|
||||
ETableSimpleValueIsEmptyFn value_is_empty,
|
||||
ETableSimpleValueToStringFn value_to_string,
|
||||
void *data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
END_GNOME_DECLS
|
||||
|
||||
#endif /* _E_TABLE_SIMPLE_H_ */
|
||||
|
||||
|
||||
@ -71,11 +71,16 @@ et_col_spec_to_col (ETableColumnSpecification *col_spec,
|
||||
ETableExtras *ete)
|
||||
{
|
||||
ETableCol *col = NULL;
|
||||
ECell *cell;
|
||||
GCompareFunc compare;
|
||||
ECell *cell = NULL;
|
||||
GCompareFunc compare = NULL;
|
||||
ETableSearchFunc search = NULL;
|
||||
|
||||
cell = e_table_extras_get_cell(ete, col_spec->cell);
|
||||
compare = e_table_extras_get_compare(ete, col_spec->compare);
|
||||
if (col_spec->cell)
|
||||
cell = e_table_extras_get_cell(ete, col_spec->cell);
|
||||
if (col_spec->compare)
|
||||
compare = e_table_extras_get_compare(ete, col_spec->compare);
|
||||
if (col_spec->search)
|
||||
search = e_table_extras_get_search(ete, col_spec->search);
|
||||
|
||||
if (cell && compare) {
|
||||
if (col_spec->pixbuf && *col_spec->pixbuf) {
|
||||
@ -97,6 +102,7 @@ et_col_spec_to_col (ETableColumnSpecification *col_spec,
|
||||
col_spec->expansion, col_spec->minimum_width,
|
||||
cell, compare, col_spec->resizable, col_spec->disabled, col_spec->priority);
|
||||
}
|
||||
col->search = search;
|
||||
}
|
||||
return col;
|
||||
}
|
||||
|
||||
@ -255,6 +255,16 @@ et_destroy (GtkObject *object)
|
||||
|
||||
et_disconnect_model (et);
|
||||
|
||||
if (et->search) {
|
||||
if (et->search_search_id)
|
||||
gtk_signal_disconnect (GTK_OBJECT (et->search),
|
||||
et->search_search_id);
|
||||
if (et->search_accept_id)
|
||||
gtk_signal_disconnect (GTK_OBJECT (et->search),
|
||||
et->search_accept_id);
|
||||
gtk_object_unref (GTK_OBJECT (et->search));
|
||||
}
|
||||
|
||||
if (et->group_info_change_id)
|
||||
gtk_signal_disconnect (GTK_OBJECT (et->sort_info),
|
||||
et->group_info_change_id);
|
||||
@ -305,6 +315,76 @@ et_unrealize (GtkWidget *widget)
|
||||
GTK_WIDGET_CLASS (parent_class)->unrealize (widget);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_row (ETable *et, int model_row, int col, ETableSearchFunc search, char *string)
|
||||
{
|
||||
const void *value;
|
||||
|
||||
value = e_table_model_value_at (et->model, col, model_row);
|
||||
|
||||
return search (value, string);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
et_search_search (ETableSearch *search, char *string, ETable *et)
|
||||
{
|
||||
int cursor;
|
||||
int rows;
|
||||
int i;
|
||||
int col;
|
||||
ETableSearchFunc search_func;
|
||||
|
||||
col = et->current_search_col;
|
||||
if (col == -1)
|
||||
return FALSE;
|
||||
|
||||
rows = e_table_model_row_count (et->model);
|
||||
|
||||
search_func = et->current_search;
|
||||
|
||||
gtk_object_get(GTK_OBJECT(et->selection),
|
||||
"cursor_row", &cursor,
|
||||
NULL);
|
||||
|
||||
cursor = e_sorter_model_to_sorted (E_SORTER (et->sorter), cursor);
|
||||
|
||||
for (i = cursor + 1; i < rows; i++) {
|
||||
int model_row = e_sorter_sorted_to_model (E_SORTER (et->sorter), i);
|
||||
if (check_row (et, model_row, col, search_func, string)) {
|
||||
e_selection_model_select_as_key_press(E_SELECTION_MODEL (et->selection), model_row, col, GDK_CONTROL_MASK);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < cursor; i++) {
|
||||
int model_row = e_sorter_sorted_to_model (E_SORTER (et->sorter), i);
|
||||
if (check_row (et, model_row, col, search_func, string)) {
|
||||
e_selection_model_select_as_key_press(E_SELECTION_MODEL (et->selection), model_row, col, GDK_CONTROL_MASK);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
cursor = e_sorter_sorted_to_model (E_SORTER (et->sorter), cursor);
|
||||
|
||||
/* Check if the cursor row is the only matching row. */
|
||||
return (cursor < rows && cursor >= 0 && check_row (et, cursor, col, search_func, string));
|
||||
}
|
||||
|
||||
static void
|
||||
et_search_accept (ETableSearch *search, ETable *et)
|
||||
{
|
||||
int col, cursor;
|
||||
|
||||
col = et->current_search_col;
|
||||
if (col == -1)
|
||||
return;
|
||||
|
||||
gtk_object_get(GTK_OBJECT(et->selection),
|
||||
"cursor_row", &cursor,
|
||||
NULL);
|
||||
e_selection_model_select_as_key_press(E_SELECTION_MODEL (et->selection), cursor, col, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
e_table_init (GtkObject *object)
|
||||
{
|
||||
@ -351,6 +431,18 @@ e_table_init (GtkObject *object)
|
||||
e_table->selection = e_table_selection_model_new();
|
||||
e_table->cursor_loc = E_TABLE_CURSOR_LOC_NONE;
|
||||
e_table->spec = NULL;
|
||||
|
||||
e_table->search = e_table_search_new();
|
||||
|
||||
e_table->search_search_id =
|
||||
gtk_signal_connect (GTK_OBJECT (e_table->search), "search",
|
||||
GTK_SIGNAL_FUNC (et_search_search), e_table);
|
||||
e_table->search_accept_id =
|
||||
gtk_signal_connect (GTK_OBJECT (e_table->search), "accept",
|
||||
GTK_SIGNAL_FUNC (et_search_accept), e_table);
|
||||
|
||||
e_table->current_search = NULL;
|
||||
e_table->current_search_col = -1;
|
||||
}
|
||||
|
||||
/* Grab_focus handler for the ETable */
|
||||
@ -642,6 +734,11 @@ group_key_press (ETableGroup *etg, int row, int col, GdkEvent *event, ETable *et
|
||||
return_val = 1;
|
||||
break;
|
||||
default:
|
||||
if ((key->keyval >= GDK_a && key->keyval <= GDK_z) ||
|
||||
(key->keyval >= GDK_A && key->keyval <= GDK_Z) ||
|
||||
(key->keyval >= GDK_0 && key->keyval <= GDK_9)) {
|
||||
e_table_search_input_character (et->search, key->keyval);
|
||||
}
|
||||
gtk_signal_emit (GTK_OBJECT (et),
|
||||
et_signals [KEY_PRESS],
|
||||
row, col, event, &return_val);
|
||||
@ -1220,6 +1317,7 @@ et_real_construct (ETable *e_table, ETableModel *etm, ETableExtras *ete,
|
||||
ETableSpecification *specification, ETableState *state)
|
||||
{
|
||||
int row = 0;
|
||||
int col_count, i;
|
||||
|
||||
if (ete)
|
||||
gtk_object_ref(GTK_OBJECT(ete));
|
||||
@ -1236,6 +1334,16 @@ et_real_construct (ETable *e_table, ETableModel *etm, ETableExtras *ete,
|
||||
e_table->cursor_mode = specification->cursor_mode;
|
||||
e_table->full_header = e_table_spec_to_full_header(specification, ete);
|
||||
|
||||
col_count = e_table_header_count (e_table->full_header);
|
||||
for (i = 0; i < col_count; i++) {
|
||||
ETableCol *col = e_table_header_get_column(e_table->full_header, i);
|
||||
if (col && col->search) {
|
||||
e_table->current_search_col = col->col_idx;
|
||||
e_table->current_search = col->search;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gtk_object_set(GTK_OBJECT(e_table->selection),
|
||||
"selection_mode", specification->selection_mode,
|
||||
"cursor_mode", specification->cursor_mode,
|
||||
|
||||
@ -39,6 +39,7 @@
|
||||
#include <gal/widgets/e-printable.h>
|
||||
#include <gal/e-table/e-table-state.h>
|
||||
#include <gal/e-table/e-table-sorter.h>
|
||||
#include <gal/e-table/e-table-search.h>
|
||||
#include <libgnome/gnome-defs.h>
|
||||
|
||||
BEGIN_GNOME_DECLS
|
||||
@ -74,6 +75,14 @@ typedef struct {
|
||||
ETableCursorLoc cursor_loc;
|
||||
ETableSpecification *spec;
|
||||
|
||||
ETableSearch *search;
|
||||
|
||||
ETableSearchFunc current_search;
|
||||
int current_search_col;
|
||||
|
||||
guint search_search_id;
|
||||
guint search_accept_id;
|
||||
|
||||
int table_model_change_id;
|
||||
int table_row_change_id;
|
||||
int table_cell_change_id;
|
||||
|
||||
Reference in New Issue
Block a user