aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--widgets/table/e-table-config-no-group.glade172
-rw-r--r--widgets/table/e-table-config.c301
-rw-r--r--widgets/table/e-table-config.glade228
-rw-r--r--widgets/table/e-table-config.h8
-rw-r--r--widgets/table/e-table-memory-store.c363
-rw-r--r--widgets/table/e-table-memory-store.h109
-rw-r--r--widgets/table/e-table-sorter.c36
-rw-r--r--widgets/table/e-table-sorter.h3
-rw-r--r--widgets/table/e-table-subset-variable.c15
-rw-r--r--widgets/table/e-table-subset-variable.h41
-rw-r--r--widgets/table/e-table-subset.c9
11 files changed, 1101 insertions, 184 deletions
diff --git a/widgets/table/e-table-config-no-group.glade b/widgets/table/e-table-config-no-group.glade
index 6f32c14e0c..1e49a59a06 100644
--- a/widgets/table/e-table-config-no-group.glade
+++ b/widgets/table/e-table-config-no-group.glade
@@ -188,32 +188,17 @@
</child>
<widget>
- <class>GtkScrolledWindow</class>
- <name>scrolledwindow1</name>
- <hscrollbar_policy>GTK_POLICY_AUTOMATIC</hscrollbar_policy>
- <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy>
- <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
- <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
+ <class>Custom</class>
+ <name>custom-available</name>
+ <creation_function>e_table_proxy_etable_available_new</creation_function>
+ <int1>0</int1>
+ <int2>0</int2>
+ <last_modification_time>Thu, 21 Feb 2002 05:42:43 GMT</last_modification_time>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
-
- <widget>
- <class>GtkViewport</class>
- <name>viewport1</name>
- <shadow_type>GTK_SHADOW_IN</shadow_type>
-
- <widget>
- <class>Custom</class>
- <name>available-field-list</name>
- <creation_function>e_table_proxy_etable_new</creation_function>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Sun, 18 Mar 2001 23:59:35 GMT</last_modification_time>
- </widget>
- </widget>
</widget>
</widget>
@@ -238,32 +223,17 @@
</child>
<widget>
- <class>GtkScrolledWindow</class>
- <name>scrolledwindow2</name>
- <hscrollbar_policy>GTK_POLICY_AUTOMATIC</hscrollbar_policy>
- <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy>
- <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
- <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
+ <class>Custom</class>
+ <name>custom-shown</name>
+ <creation_function>e_table_proxy_etable_shown_new</creation_function>
+ <int1>0</int1>
+ <int2>0</int2>
+ <last_modification_time>Thu, 21 Feb 2002 15:52:40 GMT</last_modification_time>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
-
- <widget>
- <class>GtkViewport</class>
- <name>viewport2</name>
- <shadow_type>GTK_SHADOW_IN</shadow_type>
-
- <widget>
- <class>Custom</class>
- <name>fields-shown</name>
- <creation_function>e_table_proxy_etable_new</creation_function>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Sun, 18 Mar 2001 23:59:49 GMT</last_modification_time>
- </widget>
- </widget>
</widget>
<widget>
@@ -1605,13 +1575,67 @@
<class>GtkTable</class>
<name>table1</name>
<border_width>2</border_width>
- <rows>1</rows>
+ <rows>2</rows>
<columns>3</columns>
<homogeneous>False</homogeneous>
<row_spacing>2</row_spacing>
<column_spacing>4</column_spacing>
<widget>
+ <class>GtkButton</class>
+ <name>button-sort</name>
+ <can_default>True</can_default>
+ <can_focus>True</can_focus>
+ <signal>
+ <name>clicked</name>
+ <handler>on_sort_clicked</handler>
+ <last_modification_time>Tue, 03 Oct 2000 22:10:58 GMT</last_modification_time>
+ </signal>
+ <label>_Sort...</label>
+ <relief>GTK_RELIEF_NORMAL</relief>
+ <child>
+ <left_attach>0</left_attach>
+ <right_attach>1</right_attach>
+ <top_attach>1</top_attach>
+ <bottom_attach>2</bottom_attach>
+ <xpad>0</xpad>
+ <ypad>0</ypad>
+ <xexpand>False</xexpand>
+ <yexpand>False</yexpand>
+ <xshrink>False</xshrink>
+ <yshrink>False</yshrink>
+ <xfill>True</xfill>
+ <yfill>False</yfill>
+ </child>
+ </widget>
+
+ <widget>
+ <class>GtkLabel</class>
+ <name>label-sort</name>
+ <label></label>
+ <justify>GTK_JUSTIFY_LEFT</justify>
+ <wrap>True</wrap>
+ <xalign>0</xalign>
+ <yalign>0.5</yalign>
+ <xpad>0</xpad>
+ <ypad>0</ypad>
+ <child>
+ <left_attach>1</left_attach>
+ <right_attach>2</right_attach>
+ <top_attach>1</top_attach>
+ <bottom_attach>2</bottom_attach>
+ <xpad>0</xpad>
+ <ypad>0</ypad>
+ <xexpand>True</xexpand>
+ <yexpand>False</yexpand>
+ <xshrink>False</xshrink>
+ <yshrink>False</yshrink>
+ <xfill>True</xfill>
+ <yfill>True</yfill>
+ </child>
+ </widget>
+
+ <widget>
<class>GtkLabel</class>
<name>label4</name>
<label></label>
@@ -1624,8 +1648,8 @@
<child>
<left_attach>2</left_attach>
<right_attach>3</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
+ <top_attach>1</top_attach>
+ <bottom_attach>2</bottom_attach>
<xpad>0</xpad>
<ypad>0</ypad>
<xexpand>False</xexpand>
@@ -1633,25 +1657,23 @@
<xshrink>False</xshrink>
<yshrink>False</yshrink>
<xfill>True</xfill>
- <yfill>False</yfill>
+ <yfill>True</yfill>
</child>
</widget>
<widget>
- <class>GtkButton</class>
- <name>button-sort</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <signal>
- <name>clicked</name>
- <handler>on_sort_clicked</handler>
- <last_modification_time>Tue, 03 Oct 2000 22:10:58 GMT</last_modification_time>
- </signal>
- <label>_Sort...</label>
- <relief>GTK_RELIEF_NORMAL</relief>
+ <class>GtkLabel</class>
+ <name>label21</name>
+ <label></label>
+ <justify>GTK_JUSTIFY_CENTER</justify>
+ <wrap>False</wrap>
+ <xalign>0</xalign>
+ <yalign>0.5</yalign>
+ <xpad>0</xpad>
+ <ypad>0</ypad>
<child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
+ <left_attach>2</left_attach>
+ <right_attach>3</right_attach>
<top_attach>0</top_attach>
<bottom_attach>1</bottom_attach>
<xpad>0</xpad>
@@ -1661,13 +1683,13 @@
<xshrink>False</xshrink>
<yshrink>False</yshrink>
<xfill>True</xfill>
- <yfill>False</yfill>
+ <yfill>True</yfill>
</child>
</widget>
<widget>
<class>GtkLabel</class>
- <name>label-sort</name>
+ <name>label-fields</name>
<label></label>
<justify>GTK_JUSTIFY_LEFT</justify>
<wrap>True</wrap>
@@ -1690,6 +1712,34 @@
<yfill>True</yfill>
</child>
</widget>
+
+ <widget>
+ <class>GtkButton</class>
+ <name>button-fields</name>
+ <can_default>True</can_default>
+ <can_focus>True</can_focus>
+ <signal>
+ <name>clicked</name>
+ <handler>on_sort_clicked</handler>
+ <last_modification_time>Tue, 03 Oct 2000 22:10:58 GMT</last_modification_time>
+ </signal>
+ <label>_Fields Shown...</label>
+ <relief>GTK_RELIEF_NORMAL</relief>
+ <child>
+ <left_attach>0</left_attach>
+ <right_attach>1</right_attach>
+ <top_attach>0</top_attach>
+ <bottom_attach>1</bottom_attach>
+ <xpad>0</xpad>
+ <ypad>0</ypad>
+ <xexpand>False</xexpand>
+ <yexpand>False</yexpand>
+ <xshrink>False</xshrink>
+ <yshrink>False</yshrink>
+ <xfill>True</xfill>
+ <yfill>False</yfill>
+ </child>
+ </widget>
</widget>
</widget>
diff --git a/widgets/table/e-table-config.c b/widgets/table/e-table-config.c
index 030f11b2f1..6b9ec94159 100644
--- a/widgets/table/e-table-config.c
+++ b/widgets/table/e-table-config.c
@@ -44,6 +44,10 @@
#include "gal/util/e-util.h"
#include "gal/util/e-i18n.h"
+#include <e-table-scrolled.h>
+#include <e-table-without.h>
+#include <e-table-memory-store.h>
+
#define PARENT_TYPE (gtk_object_get_type())
@@ -334,14 +338,28 @@ config_group_info_update (ETableConfig *config)
}
static void
+setup_fields (ETableConfig *config)
+{
+ int i;
+
+ e_table_without_show_all (config->available_model);
+ e_table_subset_variable_clear (config->shown_model);
+
+ if (config->temp_state) {
+ for (i = 0; i < config->temp_state->col_count; i++) {
+ e_table_subset_variable_add (config->shown_model, config->temp_state->columns[i]);
+ e_table_without_hide (config->available_model, (void *) config->temp_state->columns[i]);
+ }
+ }
+}
+
+static void
config_fields_info_update (ETableConfig *config)
{
ETableColumnSpecification **column;
GString *res = g_string_new ("");
int i;
- return;
-
for (i = 0; i < config->state->col_count; i++){
for (column = config->source_spec->columns; *column; column++){
@@ -388,10 +406,10 @@ do_sort_and_group_config_dialog (ETableConfig *config, gboolean is_sort)
case 0:
if (is_sort){
e_table_sort_info_sorting_truncate (
- config->state->sort_info, 0);
+ config->temp_state->sort_info, 0);
} else {
e_table_sort_info_grouping_truncate (
- config->state->sort_info, 0);
+ config->temp_state->sort_info, 0);
}
update_sort_and_group_config_dialog (config, is_sort);
continue;
@@ -423,21 +441,101 @@ do_sort_and_group_config_dialog (ETableConfig *config, gboolean is_sort)
config_group_info_update (config);
}
-GtkWidget *e_table_proxy_etable_new (void);
+static void
+do_fields_config_dialog (ETableConfig *config)
+{
+ int button, running = 1;
+
+ config->temp_state = e_table_state_duplicate (config->state);
+
+ setup_fields (config);
+
+ do {
+ button = gnome_dialog_run (GNOME_DIALOG(config->dialog_show_fields));
+ switch (button){
+ /* OK */
+ case 0:
+ gtk_object_unref (GTK_OBJECT (config->state));
+ config->state = config->temp_state;
+ config->temp_state = 0;
+ running = 0;
+ gnome_property_box_changed (
+ GNOME_PROPERTY_BOX (config->dialog_toplevel));
+ break;
+
+ /* CANCEL */
+ case 1:
+ gtk_object_unref (GTK_OBJECT (config->temp_state));
+ config->temp_state = 0;
+ running = 0;
+ break;
+ }
+
+ } while (running);
+ gnome_dialog_close (GNOME_DIALOG (config->dialog_show_fields));
+
+ config_fields_info_update (config);
+}
+
+
+ETableMemoryStoreColumnInfo store_columns[] = {
+ E_TABLE_MEMORY_STORE_STRING,
+ E_TABLE_MEMORY_STORE_TERMINATOR
+};
+
+static ETableModel *global_store; /* Glade better not be reentrant any time soon. */
+
+static void
+create_global_store (ETableConfig *config)
+{
+ int i;
+
+ global_store = e_table_memory_store_new (store_columns);
+ for (i = 0; config->source_spec->columns[i]; i++) {
+ e_table_memory_store_insert (E_TABLE_MEMORY_STORE (global_store), i, (void **) &config->source_spec->columns[i]->title, NULL);
+ }
+}
+
+char *spec = "<ETableSpecification no-headers=\"true\" cursor-mode=\"line\" draw-grid=\"false\" draw-focus=\"true\" selection-mode=\"browse\"> \
+ <ETableColumn model_col= \"0\" _title=\"Name\" minimum_width=\"30\" resizable=\"true\" cell=\"string\" compare=\"string\"/> \
+ <ETableState> <column source=\"0\"/> \
+ <grouping/> \
+ </ETableState> \
+ </ETableSpecification>";
+
+GtkWidget *e_table_proxy_etable_shown_new (void);
GtkWidget *
-e_table_proxy_etable_new (void)
+e_table_proxy_etable_shown_new (void)
{
- return gtk_label_new ("Field selection dialog not\nimplemented here yet.");
+ ETableModel *model = NULL;
+
+ model = e_table_subset_variable_new (global_store);
+
+ return e_table_scrolled_new (model, NULL, spec, NULL);
+}
+
+GtkWidget *e_table_proxy_etable_available_new (void);
+
+GtkWidget *
+e_table_proxy_etable_available_new (void)
+{
+ ETableModel *model;
+
+ model = e_table_without_new (global_store,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+
+ e_table_without_show_all (E_TABLE_WITHOUT (model));
+
+ return e_table_scrolled_new (model, NULL, spec, NULL);
}
static void
config_button_fields (GtkWidget *widget, ETableConfig *config)
{
- gnome_dialog_run (GNOME_DIALOG(config->dialog_show_fields));
- gnome_dialog_close (GNOME_DIALOG (config->dialog_show_fields));
+ do_fields_config_dialog (config);
}
-
+
static void
config_button_sort (GtkWidget *widget, ETableConfig *config)
{
@@ -713,15 +811,197 @@ configure_group_dialog (ETableConfig *config, GladeXML *gui)
}
static void
+add_column (int model_row, gpointer closure)
+{
+ GList **columns = closure;
+ *columns = g_list_prepend (*columns, GINT_TO_POINTER (model_row));
+}
+
+static void
+config_button_add (GtkWidget *widget, ETableConfig *config)
+{
+ GList *columns = NULL;
+ GList *column;
+ int count;
+ int i;
+
+ e_table_selected_row_foreach (config->available, add_column, &columns);
+ columns = g_list_reverse (columns);
+
+ count = g_list_length (columns);
+
+ config->temp_state->columns = g_renew (int, config->temp_state->columns, config->temp_state->col_count + count);
+ config->temp_state->expansions = g_renew (double, config->temp_state->expansions, config->temp_state->col_count + count);
+ i = config->temp_state->col_count;
+ for (column = columns; column; column = column->next) {
+ config->temp_state->columns[i] = e_table_subset_view_to_model_row (E_TABLE_SUBSET (config->available_model), GPOINTER_TO_INT (column->data));
+ config->temp_state->expansions[i] = config->source_spec->columns[config->temp_state->columns[i]]->expansion;
+ i++;
+ }
+ config->temp_state->col_count += count;
+
+ g_list_free (columns);
+
+ setup_fields (config);
+}
+
+static void
+config_button_remove (GtkWidget *widget, ETableConfig *config)
+{
+ GList *columns = NULL;
+ GList *column;
+
+ e_table_selected_row_foreach (config->shown, add_column, &columns);
+
+ for (column = columns; column; column = column->next) {
+ int row = GPOINTER_TO_INT (column->data);
+
+ memmove (config->temp_state->columns + row, config->temp_state->columns + row + 1, sizeof (int) * (config->temp_state->col_count - row - 1));
+ memmove (config->temp_state->expansions + row, config->temp_state->expansions + row + 1, sizeof (double) * (config->temp_state->col_count - row - 1));
+ config->temp_state->col_count --;
+ }
+ config->temp_state->columns = g_renew (int, config->temp_state->columns, config->temp_state->col_count);
+ config->temp_state->expansions = g_renew (double, config->temp_state->expansions, config->temp_state->col_count);
+
+ g_list_free (columns);
+
+ setup_fields (config);
+}
+
+static void
+config_button_up (GtkWidget *widget, ETableConfig *config)
+{
+ GList *columns = NULL;
+ GList *column;
+ int *new_shown;
+ double *new_expansions;
+ int next_col;
+ double next_expansion;
+ int i;
+
+ e_table_selected_row_foreach (config->shown, add_column, &columns);
+ columns = g_list_reverse (columns);
+
+ new_shown = g_new (int, config->temp_state->col_count);
+ new_expansions = g_new (double, config->temp_state->col_count);
+
+ column = columns;
+
+ next_col = config->temp_state->columns[0];
+ next_expansion = config->temp_state->expansions[0];
+
+ for (i = 1; i < config->temp_state->col_count; i++) {
+ if (column && (GPOINTER_TO_INT (column->data) == i)) {
+ new_expansions[i - 1] = config->temp_state->expansions[i];
+ new_shown[i - 1] = config->temp_state->columns[i];
+ column = column->next;
+ } else {
+ new_shown[i - 1] = next_col;
+ next_col = config->temp_state->columns[i];
+
+ new_expansions[i - 1] = next_expansion;
+ next_expansion = config->temp_state->expansions[i];
+ }
+ }
+
+ new_shown[i - 1] = next_col;
+ new_expansions[i - 1] = next_expansion;
+
+ g_free (config->temp_state->columns);
+ g_free (config->temp_state->expansions);
+
+ config->temp_state->columns = new_shown;
+ config->temp_state->expansions = new_expansions;
+
+ g_list_free (columns);
+
+ setup_fields (config);
+}
+
+static void
+config_button_down (GtkWidget *widget, ETableConfig *config)
+{
+ GList *columns = NULL;
+ GList *column;
+ int *new_shown;
+ double *new_expansions;
+ int next_col;
+ double next_expansion;
+ int i;
+
+ e_table_selected_row_foreach (config->shown, add_column, &columns);
+
+ new_shown = g_new (int, config->temp_state->col_count);
+ new_expansions = g_new (double, config->temp_state->col_count);
+
+ column = columns;
+
+ next_col = config->temp_state->columns[config->temp_state->col_count - 1];
+ next_expansion = config->temp_state->expansions[config->temp_state->col_count - 1];
+
+ for (i = config->temp_state->col_count - 1; i > 0; i--) {
+ if (column && (GPOINTER_TO_INT (column->data) == i - 1)) {
+ new_expansions[i] = config->temp_state->expansions[i - 1];
+ new_shown[i] = config->temp_state->columns[i - 1];
+ column = column->next;
+ } else {
+ new_shown[i] = next_col;
+ next_col = config->temp_state->columns[i - 1];
+
+ new_expansions[i] = next_expansion;
+ next_expansion = config->temp_state->expansions[i - 1];
+ }
+ }
+
+ new_shown[0] = next_col;
+ new_expansions[0] = next_expansion;
+
+ g_free (config->temp_state->columns);
+ g_free (config->temp_state->expansions);
+
+ config->temp_state->columns = new_shown;
+ config->temp_state->expansions = new_expansions;
+
+ g_list_free (columns);
+
+ setup_fields (config);
+}
+
+static void
+configure_fields_dialog (ETableConfig *config, GladeXML *gui)
+{
+ config->available = e_table_scrolled_get_table (E_TABLE_SCROLLED (glade_xml_get_widget (gui, "custom-available")));
+ gtk_object_get (GTK_OBJECT (config->available),
+ "model", &config->available_model,
+ NULL);
+
+ config->shown = e_table_scrolled_get_table (E_TABLE_SCROLLED (glade_xml_get_widget (gui, "custom-shown")));
+ gtk_object_get (GTK_OBJECT (config->shown),
+ "model", &config->shown_model,
+ NULL);
+
+ connect_button (config, gui, "button-add", config_button_add);
+ connect_button (config, gui, "button-remove", config_button_remove);
+ connect_button (config, gui, "button-up", config_button_up);
+ connect_button (config, gui, "button-down", config_button_down);
+
+ setup_fields (config);
+}
+
+static void
setup_gui (ETableConfig *config)
{
GladeXML *gui;
+ create_global_store (config);
+
if (e_table_sort_info_get_can_group (config->state->sort_info)) {
gui = glade_xml_new_with_domain (ETABLE_GLADEDIR "/e-table-config.glade", NULL, PACKAGE);
} else {
gui = glade_xml_new_with_domain (ETABLE_GLADEDIR "/e-table-config-no-group.glade", NULL, PACKAGE);
}
+
+ gtk_object_unref (GTK_OBJECT (global_store));
config->dialog_toplevel = glade_xml_get_widget (
gui, "e-table-config");
@@ -756,6 +1036,7 @@ setup_gui (ETableConfig *config)
configure_sort_dialog (config, gui);
configure_group_dialog (config, gui);
+ configure_fields_dialog (config, gui);
gtk_signal_connect (
GTK_OBJECT (config->dialog_toplevel), "destroy",
diff --git a/widgets/table/e-table-config.glade b/widgets/table/e-table-config.glade
index 42bef34956..f7f0683f7e 100644
--- a/widgets/table/e-table-config.glade
+++ b/widgets/table/e-table-config.glade
@@ -188,32 +188,17 @@
</child>
<widget>
- <class>GtkScrolledWindow</class>
- <name>scrolledwindow1</name>
- <hscrollbar_policy>GTK_POLICY_AUTOMATIC</hscrollbar_policy>
- <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy>
- <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
- <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
+ <class>Custom</class>
+ <name>custom-available</name>
+ <creation_function>e_table_proxy_etable_available_new</creation_function>
+ <int1>0</int1>
+ <int2>0</int2>
+ <last_modification_time>Thu, 21 Feb 2002 16:09:53 GMT</last_modification_time>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
-
- <widget>
- <class>GtkViewport</class>
- <name>viewport1</name>
- <shadow_type>GTK_SHADOW_IN</shadow_type>
-
- <widget>
- <class>Custom</class>
- <name>available-field-list</name>
- <creation_function>e_table_proxy_etable_new</creation_function>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Sun, 18 Mar 2001 23:59:35 GMT</last_modification_time>
- </widget>
- </widget>
</widget>
</widget>
@@ -238,32 +223,17 @@
</child>
<widget>
- <class>GtkScrolledWindow</class>
- <name>scrolledwindow2</name>
- <hscrollbar_policy>GTK_POLICY_AUTOMATIC</hscrollbar_policy>
- <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy>
- <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
- <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
+ <class>Custom</class>
+ <name>custom-shown</name>
+ <creation_function>e_table_proxy_etable_shown_new</creation_function>
+ <int1>0</int1>
+ <int2>0</int2>
+ <last_modification_time>Thu, 21 Feb 2002 16:09:58 GMT</last_modification_time>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
-
- <widget>
- <class>GtkViewport</class>
- <name>viewport2</name>
- <shadow_type>GTK_SHADOW_IN</shadow_type>
-
- <widget>
- <class>Custom</class>
- <name>fields-shown</name>
- <creation_function>e_table_proxy_etable_new</creation_function>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Sun, 18 Mar 2001 23:59:49 GMT</last_modification_time>
- </widget>
- </widget>
</widget>
<widget>
@@ -1605,27 +1575,57 @@
<class>GtkTable</class>
<name>table1</name>
<border_width>2</border_width>
- <rows>2</rows>
+ <rows>3</rows>
<columns>3</columns>
<homogeneous>False</homogeneous>
<row_spacing>2</row_spacing>
<column_spacing>4</column_spacing>
<widget>
- <class>GtkLabel</class>
- <name>label3</name>
- <label></label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
+ <class>GtkButton</class>
+ <name>button-sort</name>
+ <can_default>True</can_default>
+ <can_focus>True</can_focus>
+ <signal>
+ <name>clicked</name>
+ <handler>on_sort_clicked</handler>
+ <last_modification_time>Tue, 03 Oct 2000 22:10:58 GMT</last_modification_time>
+ </signal>
+ <label>_Sort...</label>
+ <relief>GTK_RELIEF_NORMAL</relief>
<child>
- <left_attach>2</left_attach>
- <right_attach>3</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
+ <left_attach>0</left_attach>
+ <right_attach>1</right_attach>
+ <top_attach>2</top_attach>
+ <bottom_attach>3</bottom_attach>
+ <xpad>0</xpad>
+ <ypad>0</ypad>
+ <xexpand>False</xexpand>
+ <yexpand>False</yexpand>
+ <xshrink>False</xshrink>
+ <yshrink>False</yshrink>
+ <xfill>True</xfill>
+ <yfill>False</yfill>
+ </child>
+ </widget>
+
+ <widget>
+ <class>GtkButton</class>
+ <name>button-group</name>
+ <can_default>True</can_default>
+ <can_focus>True</can_focus>
+ <signal>
+ <name>clicked</name>
+ <handler>on_group_by_clicked</handler>
+ <last_modification_time>Tue, 03 Oct 2000 22:10:50 GMT</last_modification_time>
+ </signal>
+ <label>_Group By...</label>
+ <relief>GTK_RELIEF_NORMAL</relief>
+ <child>
+ <left_attach>0</left_attach>
+ <right_attach>1</right_attach>
+ <top_attach>1</top_attach>
+ <bottom_attach>2</bottom_attach>
<xpad>0</xpad>
<ypad>0</ypad>
<xexpand>False</xexpand>
@@ -1639,61 +1639,59 @@
<widget>
<class>GtkLabel</class>
- <name>label4</name>
+ <name>label-group</name>
<label></label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
+ <justify>GTK_JUSTIFY_LEFT</justify>
+ <wrap>True</wrap>
<xalign>0</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
- <left_attach>2</left_attach>
- <right_attach>3</right_attach>
+ <left_attach>1</left_attach>
+ <right_attach>2</right_attach>
<top_attach>1</top_attach>
<bottom_attach>2</bottom_attach>
<xpad>0</xpad>
<ypad>0</ypad>
- <xexpand>False</xexpand>
+ <xexpand>True</xexpand>
<yexpand>False</yexpand>
<xshrink>False</xshrink>
<yshrink>False</yshrink>
<xfill>True</xfill>
- <yfill>False</yfill>
+ <yfill>True</yfill>
</child>
</widget>
<widget>
- <class>GtkButton</class>
- <name>button-sort</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <signal>
- <name>clicked</name>
- <handler>on_sort_clicked</handler>
- <last_modification_time>Tue, 03 Oct 2000 22:10:58 GMT</last_modification_time>
- </signal>
- <label>_Sort...</label>
- <relief>GTK_RELIEF_NORMAL</relief>
+ <class>GtkLabel</class>
+ <name>label-sort</name>
+ <label></label>
+ <justify>GTK_JUSTIFY_LEFT</justify>
+ <wrap>True</wrap>
+ <xalign>0</xalign>
+ <yalign>0.5</yalign>
+ <xpad>0</xpad>
+ <ypad>0</ypad>
<child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
+ <left_attach>1</left_attach>
+ <right_attach>2</right_attach>
+ <top_attach>2</top_attach>
+ <bottom_attach>3</bottom_attach>
<xpad>0</xpad>
<ypad>0</ypad>
- <xexpand>False</xexpand>
+ <xexpand>True</xexpand>
<yexpand>False</yexpand>
<xshrink>False</xshrink>
<yshrink>False</yshrink>
<xfill>True</xfill>
- <yfill>False</yfill>
+ <yfill>True</yfill>
</child>
</widget>
<widget>
<class>GtkButton</class>
- <name>button-group</name>
+ <name>button-fields</name>
<can_default>True</can_default>
<can_focus>True</can_focus>
<signal>
@@ -1701,7 +1699,7 @@
<handler>on_group_by_clicked</handler>
<last_modification_time>Tue, 03 Oct 2000 22:10:50 GMT</last_modification_time>
</signal>
- <label>_Group By...</label>
+ <label>_Fields Shown...</label>
<relief>GTK_RELIEF_NORMAL</relief>
<child>
<left_attach>0</left_attach>
@@ -1721,7 +1719,7 @@
<widget>
<class>GtkLabel</class>
- <name>label-group</name>
+ <name>label-fields</name>
<label></label>
<justify>GTK_JUSTIFY_LEFT</justify>
<wrap>True</wrap>
@@ -1747,22 +1745,74 @@
<widget>
<class>GtkLabel</class>
- <name>label-sort</name>
+ <name>label3</name>
<label></label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>True</wrap>
+ <justify>GTK_JUSTIFY_CENTER</justify>
+ <wrap>False</wrap>
<xalign>0</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
+ <left_attach>2</left_attach>
+ <right_attach>3</right_attach>
<top_attach>1</top_attach>
<bottom_attach>2</bottom_attach>
<xpad>0</xpad>
<ypad>0</ypad>
- <xexpand>True</xexpand>
+ <xexpand>False</xexpand>
+ <yexpand>False</yexpand>
+ <xshrink>False</xshrink>
+ <yshrink>False</yshrink>
+ <xfill>True</xfill>
+ <yfill>True</yfill>
+ </child>
+ </widget>
+
+ <widget>
+ <class>GtkLabel</class>
+ <name>label4</name>
+ <label></label>
+ <justify>GTK_JUSTIFY_CENTER</justify>
+ <wrap>False</wrap>
+ <xalign>0</xalign>
+ <yalign>0.5</yalign>
+ <xpad>0</xpad>
+ <ypad>0</ypad>
+ <child>
+ <left_attach>2</left_attach>
+ <right_attach>3</right_attach>
+ <top_attach>2</top_attach>
+ <bottom_attach>3</bottom_attach>
+ <xpad>0</xpad>
+ <ypad>0</ypad>
+ <xexpand>False</xexpand>
+ <yexpand>False</yexpand>
+ <xshrink>False</xshrink>
+ <yshrink>False</yshrink>
+ <xfill>True</xfill>
+ <yfill>True</yfill>
+ </child>
+ </widget>
+
+ <widget>
+ <class>GtkLabel</class>
+ <name>label22</name>
+ <label></label>
+ <justify>GTK_JUSTIFY_CENTER</justify>
+ <wrap>False</wrap>
+ <xalign>0</xalign>
+ <yalign>0.5</yalign>
+ <xpad>0</xpad>
+ <ypad>0</ypad>
+ <child>
+ <left_attach>2</left_attach>
+ <right_attach>3</right_attach>
+ <top_attach>0</top_attach>
+ <bottom_attach>1</bottom_attach>
+ <xpad>0</xpad>
+ <ypad>0</ypad>
+ <xexpand>False</xexpand>
<yexpand>False</yexpand>
<xshrink>False</xshrink>
<yshrink>False</yshrink>
diff --git a/widgets/table/e-table-config.h b/widgets/table/e-table-config.h
index b87aa14d64..46bf1507ac 100644
--- a/widgets/table/e-table-config.h
+++ b/widgets/table/e-table-config.h
@@ -29,6 +29,9 @@
#include <gal/e-table/e-table-sort-info.h>
#include <gal/e-table/e-table-specification.h>
#include <gal/widgets/gtk-combo-text.h>
+#include <gal/e-table/e-table-without.h>
+#include <gal/e-table/e-table-subset-variable.h>
+#include <gal/e-table/e-table.h>
BEGIN_GNOME_DECLS
@@ -75,6 +78,11 @@ typedef struct {
ETableConfigSortWidgets sort [4];
ETableConfigSortWidgets group [4];
+ ETable *available;
+ ETableWithout *available_model;
+ ETable *shown;
+ ETableSubsetVariable *shown_model;
+
/*
* List of valid column names
*/
diff --git a/widgets/table/e-table-memory-store.c b/widgets/table/e-table-memory-store.c
new file mode 100644
index 0000000000..276bb99104
--- /dev/null
+++ b/widgets/table/e-table-memory-store.c
@@ -0,0 +1,363 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * e-table-memory-store.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 <string.h>
+#include "e-table-memory-store.h"
+
+#define PARENT_TYPE e_table_memory_get_type ()
+
+#define STORE_LOCATOR(etms, col, row) (*((etms)->priv->store + (row) * (etms)->priv->col_count + (col)))
+
+struct _ETableMemoryStorePrivate {
+ int col_count;
+ ETableMemoryStoreColumnInfo *columns;
+ void **store;
+};
+
+static void *
+duplicate_value (ETableMemoryStore *etms, int col, const void *val)
+{
+ switch (etms->priv->columns[col].type) {
+ case E_TABLE_MEMORY_STORE_COLUMN_TYPE_STRING:
+ return g_strdup (val);
+ case E_TABLE_MEMORY_STORE_COLUMN_TYPE_CUSTOM:
+ if (etms->priv->columns[col].custom.duplicate_value)
+ return etms->priv->columns[col].custom.duplicate_value (E_TABLE_MODEL (etms), col, val, NULL);
+ break;
+ default:
+ break;
+ }
+ return (void *) val;
+}
+
+static int
+etms_column_count (ETableModel *etm)
+{
+ ETableMemoryStore *etms = E_TABLE_MEMORY_STORE(etm);
+
+ return etms->priv->col_count;
+}
+
+static void *
+etms_value_at (ETableModel *etm, int col, int row)
+{
+ ETableMemoryStore *etms = E_TABLE_MEMORY_STORE(etm);
+
+ return STORE_LOCATOR (etms, col, row);
+}
+
+static void
+etms_set_value_at (ETableModel *etm, int col, int row, const void *val)
+{
+ ETableMemoryStore *etms = E_TABLE_MEMORY_STORE(etm);
+
+ STORE_LOCATOR (etms, col, row) = duplicate_value (etms, col, val);
+
+ e_table_model_cell_changed (etm, col, row);
+}
+
+static gboolean
+etms_is_cell_editable (ETableModel *etm, int col, int row)
+{
+ ETableMemoryStore *etms = E_TABLE_MEMORY_STORE(etm);
+
+ return etms->priv->columns[col].editable;
+}
+
+/* The default for etms_duplicate_value is to return the raw value. */
+static void *
+etms_duplicate_value (ETableModel *etm, int col, const void *value)
+{
+ ETableMemoryStore *etms = E_TABLE_MEMORY_STORE(etm);
+
+ return duplicate_value (etms, col, value);
+}
+
+static void
+etms_free_value (ETableModel *etm, int col, void *value)
+{
+ ETableMemoryStore *etms = E_TABLE_MEMORY_STORE(etm);
+
+ switch (etms->priv->columns[col].type) {
+ case E_TABLE_MEMORY_STORE_COLUMN_TYPE_STRING:
+ g_free (value);
+ break;
+ case E_TABLE_MEMORY_STORE_COLUMN_TYPE_CUSTOM:
+ if (etms->priv->columns[col].custom.free_value)
+ etms->priv->columns[col].custom.free_value (E_TABLE_MODEL (etms), col, value, NULL);
+ break;
+ default:
+ break;
+ }
+}
+
+static void *
+etms_initialize_value (ETableModel *etm, int col)
+{
+ ETableMemoryStore *etms = E_TABLE_MEMORY_STORE(etm);
+
+ switch (etms->priv->columns[col].type) {
+ case E_TABLE_MEMORY_STORE_COLUMN_TYPE_STRING:
+ return g_strdup ("");
+ case E_TABLE_MEMORY_STORE_COLUMN_TYPE_CUSTOM:
+ if (etms->priv->columns[col].custom.initialize_value)
+ return etms->priv->columns[col].custom.initialize_value (E_TABLE_MODEL (etms), col, NULL);
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static gboolean
+etms_value_is_empty (ETableModel *etm, int col, const void *value)
+{
+ ETableMemoryStore *etms = E_TABLE_MEMORY_STORE(etm);
+
+ switch (etms->priv->columns[col].type) {
+ case E_TABLE_MEMORY_STORE_COLUMN_TYPE_STRING:
+ return !(value && *(char *) value);
+ case E_TABLE_MEMORY_STORE_COLUMN_TYPE_CUSTOM:
+ if (etms->priv->columns[col].custom.value_is_empty)
+ return etms->priv->columns[col].custom.value_is_empty (E_TABLE_MODEL (etms), col, value, NULL);
+ break;
+ default:
+ break;
+ }
+ return value == 0;
+}
+
+static char *
+etms_value_to_string (ETableModel *etm, int col, const void *value)
+{
+ ETableMemoryStore *etms = E_TABLE_MEMORY_STORE(etm);
+
+ switch (etms->priv->columns[col].type) {
+ case E_TABLE_MEMORY_STORE_COLUMN_TYPE_STRING:
+ return g_strdup (value);
+ case E_TABLE_MEMORY_STORE_COLUMN_TYPE_CUSTOM:
+ if (etms->priv->columns[col].custom.value_is_empty)
+ return etms->priv->columns[col].custom.value_to_string (E_TABLE_MODEL (etms), col, value, NULL);
+ break;
+ default:
+ break;
+ }
+ return g_strdup_printf ("%d", GPOINTER_TO_INT (value));
+}
+
+static void
+etms_append_row (ETableModel *etm, ETableModel *source, int row)
+{
+ ETableMemoryStore *etms = E_TABLE_MEMORY_STORE(etm);
+ void **new_data;
+ int i;
+ int row_count;
+
+ new_data = g_new (void *, etms->priv->col_count);
+
+ for (i = 0; i < etms->priv->col_count; i++) {
+ new_data[i] = e_table_model_value_at (source, i, row);
+ }
+
+ row_count = e_table_model_row_count (E_TABLE_MODEL (etms));
+
+ e_table_memory_store_insert (etms, row_count, new_data, NULL);
+}
+
+static void
+e_table_memory_store_init (ETableMemoryStore *etms)
+{
+ etms->priv = g_new (ETableMemoryStorePrivate, 1);
+
+ etms->priv->col_count = 0;
+ etms->priv->columns = NULL;
+ etms->priv->store = NULL;
+}
+
+static void
+e_table_memory_store_class_init (GtkObjectClass *object_class)
+{
+ ETableModelClass *model_class = (ETableModelClass *) object_class;
+
+ model_class->column_count = etms_column_count;
+ model_class->value_at = etms_value_at;
+ model_class->set_value_at = etms_set_value_at;
+ model_class->is_cell_editable = etms_is_cell_editable;
+ model_class->duplicate_value = etms_duplicate_value;
+ model_class->free_value = etms_free_value;
+ model_class->initialize_value = etms_initialize_value;
+ model_class->value_is_empty = etms_value_is_empty;
+ model_class->value_to_string = etms_value_to_string;
+ model_class->append_row = etms_append_row;
+}
+
+GtkType
+e_table_memory_store_get_type (void)
+{
+ static GtkType type = 0;
+
+ if (!type){
+ GtkTypeInfo info = {
+ "ETableMemoryStore",
+ sizeof (ETableMemoryStore),
+ sizeof (ETableMemoryStoreClass),
+ (GtkClassInitFunc) e_table_memory_store_class_init,
+ (GtkObjectInitFunc) e_table_memory_store_init,
+ NULL, /* reserved 1 */
+ NULL, /* reserved 2 */
+ (GtkClassInitFunc) NULL
+ };
+
+ type = gtk_type_unique (PARENT_TYPE, &info);
+ }
+
+ return type;
+}
+
+/**
+ * e_table_memory_store_new:
+ * @col_count:
+ * @value_at:
+ * @set_value_at:
+ * @is_cell_editable:
+ * @duplicate_value:
+ * @free_value:
+ * @initialize_value:
+ * @value_is_empty:
+ * @value_to_string:
+ * @data: closure pointer.
+ *
+ * This initializes a new ETableMemoryStoreModel object. ETableMemoryStoreModel is
+ * an implementaiton of the abstract class ETableModel. The ETableMemoryStoreModel
+ * is designed to allow people to easily create ETableModels without having
+ * to create a new GtkType derived from ETableModel every time they need one.
+ *
+ * Instead, ETableMemoryStoreModel uses a setup based in callback functions, every
+ * callback function signature mimics the signature of each ETableModel method
+ * and passes the extra @data pointer to each one of the method to provide them
+ * with any context they might want to use.
+ *
+ * Returns: An ETableMemoryStoreModel object (which is also an ETableModel
+ * object).
+ */
+ETableModel *
+e_table_memory_store_new (ETableMemoryStoreColumnInfo *columns)
+{
+ ETableMemoryStore *et;
+
+ et = gtk_type_new (e_table_memory_store_get_type ());
+
+ if (e_table_memory_store_construct (et, columns)) {
+ return (ETableModel *) et;
+ } else {
+ gtk_object_unref (GTK_OBJECT (et));
+ return NULL;
+ }
+}
+
+ETableModel *
+e_table_memory_store_construct (ETableMemoryStore *etms, ETableMemoryStoreColumnInfo *columns)
+{
+ int i;
+ for (i = 0; columns[i].type != E_TABLE_MEMORY_STORE_COLUMN_TYPE_TERMINATOR; i++)
+ /* Intentionally blank */;
+ etms->priv->col_count = i;
+
+ etms->priv->columns = g_new (ETableMemoryStoreColumnInfo, etms->priv->col_count + 1);
+
+ memcpy (etms->priv->columns, columns, (etms->priv->col_count + 1) * sizeof (ETableMemoryStoreColumnInfo));
+
+ return E_TABLE_MODEL (etms);
+}
+
+
+void
+e_table_memory_store_adopt_value_at (ETableMemoryStore *etms, int col, int row, void *value)
+{
+ STORE_LOCATOR (etms, col, row) = value;
+
+ e_table_model_cell_changed (E_TABLE_MODEL (etms), col, row);
+}
+
+/* The size of these arrays is the number of columns. */
+void
+e_table_memory_store_insert (ETableMemoryStore *etms, int row, void **store, gpointer data)
+{
+ int row_count;
+ int i;
+
+ e_table_memory_insert (E_TABLE_MEMORY (etms), row, data);
+ row_count = e_table_model_row_count (E_TABLE_MODEL (etms));
+ 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 - 1) * sizeof (void *));
+
+ for (i = 0; i < etms->priv->col_count; i++) {
+ STORE_LOCATOR(etms, i, row) = duplicate_value(etms, i, store[i]);
+ }
+}
+
+void
+e_table_memory_store_insert_adopt (ETableMemoryStore *etms, int row, void **store, gpointer data)
+{
+ 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 *));
+ 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 *));
+
+ for (i = 0; i < etms->priv->col_count; i++) {
+ STORE_LOCATOR(etms, i, row) = store[i];
+ }
+}
+
+void
+e_table_memory_store_remove (ETableMemoryStore *etms, int row)
+{
+ int row_count;
+
+ e_table_memory_remove (E_TABLE_MEMORY (etms), row);
+
+ row_count = e_table_model_row_count (E_TABLE_MODEL (etms));
+ memmove (etms->priv->store + etms->priv->col_count * row,
+ etms->priv->store + etms->priv->col_count * (row + 1),
+ etms->priv->col_count * (row_count - row) * sizeof (void *));
+ etms->priv->store = g_realloc (etms->priv->store, etms->priv->col_count * row_count * sizeof (void *));
+}
+
+void
+e_table_memory_store_clear (ETableMemoryStore *etms)
+{
+ e_table_memory_clear (E_TABLE_MEMORY (etms));
+
+ g_free (etms->priv->store);
+ etms->priv->store = NULL;
+}
diff --git a/widgets/table/e-table-memory-store.h b/widgets/table/e-table-memory-store.h
new file mode 100644
index 0000000000..33a84a2b1b
--- /dev/null
+++ b/widgets/table/e-table-memory-store.h
@@ -0,0 +1,109 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * e-table-memory-store.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_MEMORY_STORE_H_
+#define _E_TABLE_MEMORY_STORE_H_
+
+#include <gal/e-table/e-table-memory.h>
+#include <gal/e-table/e-table-memory-callbacks.h>
+#include <libgnome/gnome-defs.h>
+
+BEGIN_GNOME_DECLS
+
+#define E_TABLE_MEMORY_STORE_TYPE (e_table_memory_store_get_type ())
+#define E_TABLE_MEMORY_STORE(o) (GTK_CHECK_CAST ((o), E_TABLE_MEMORY_STORE_TYPE, ETableMemoryStore))
+#define E_TABLE_MEMORY_STORE_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_TABLE_MEMORY_STORE_TYPE, ETableMemoryStoreClass))
+#define E_IS_TABLE_MEMORY_STORE(o) (GTK_CHECK_TYPE ((o), E_TABLE_MEMORY_STORE_TYPE))
+#define E_IS_TABLE_MEMORY_STORE_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_MEMORY_STORE_TYPE))
+
+typedef enum {
+ E_TABLE_MEMORY_STORE_COLUMN_TYPE_TERMINATOR,
+ E_TABLE_MEMORY_STORE_COLUMN_TYPE_INTEGER,
+ E_TABLE_MEMORY_STORE_COLUMN_TYPE_STRING,
+ E_TABLE_MEMORY_STORE_COLUMN_TYPE_CUSTOM
+} ETableMemoryStoreColumnType;
+
+typedef struct {
+ ETableMemoryCalbacksDuplicateValueFn duplicate_value;
+ ETableMemoryCalbacksFreeValueFn free_value;
+ ETableMemoryCalbacksInitializeValueFn initialize_value;
+ ETableMemoryCalbacksValueIsEmptyFn value_is_empty;
+ ETableMemoryCalbacksValueToStringFn value_to_string;
+} ETableMemoryStoreCustomColumn;
+
+typedef struct {
+ ETableMemoryStoreColumnType type;
+ ETableMemoryStoreCustomColumn custom;
+ guint editable : 1;
+} ETableMemoryStoreColumnInfo;
+
+#define E_TABLE_MEMORY_STORE_TERMINATOR { E_TABLE_MEMORY_STORE_COLUMN_TYPE_TERMINATOR, { NULL }, FALSE }
+#define E_TABLE_MEMORY_STORE_INTEGER { E_TABLE_MEMORY_STORE_COLUMN_TYPE_INTEGER, { NULL }, FALSE }
+#define E_TABLE_MEMORY_STORE_STRING { E_TABLE_MEMORY_STORE_COLUMN_TYPE_STRING, { NULL }, FALSE }
+#define E_TABLE_MEMORY_STORE_EDITABLE_STRING { E_TABLE_MEMORY_STORE_COLUMN_TYPE_STRING, { NULL }, TRUE }
+#define E_TABLE_MEMORY_STORE_CUSTOM(editable, duplicate, free, initialize, empty, string) \
+ { E_TABLE_MEMORY_STORE_COLUMN_TYPE_CUSTOM, \
+ { (duplicate), (free), (initialize), (empty), (string) }, editable }
+
+typedef struct _ETableMemoryStorePrivate ETableMemoryStorePrivate;
+
+typedef struct {
+ ETableMemory parent;
+
+ ETableMemoryStorePrivate *priv;
+} ETableMemoryStore;
+
+typedef struct {
+ ETableMemoryClass parent_class;
+} ETableMemoryStoreClass;
+
+GtkType e_table_memory_store_get_type (void);
+
+/* Object Creation */
+ETableModel *e_table_memory_store_new (ETableMemoryStoreColumnInfo *columns);
+ETableModel *e_table_memory_store_construct (ETableMemoryStore *store,
+ ETableMemoryStoreColumnInfo *columns);
+
+/* Adopt a value instead of copying it. */
+void e_table_memory_store_adopt_value_at (ETableMemoryStore *etms,
+ int col,
+ int row,
+ void *value);
+
+/* The size of these arrays is the number of columns. */
+void e_table_memory_store_insert (ETableMemoryStore *etms,
+ int row,
+ void **store,
+ gpointer data);
+void e_table_memory_store_insert_adopt (ETableMemoryStore *etms,
+ int row,
+ void **store,
+ gpointer data);
+void e_table_memory_store_remove (ETableMemoryStore *etms,
+ int row);
+void e_table_memory_store_clear (ETableMemoryStore *etms);
+
+END_GNOME_DECLS
+
+#endif /* _E_TABLE_MEMORY_STORE_H_ */
+
diff --git a/widgets/table/e-table-sorter.c b/widgets/table/e-table-sorter.c
index 879234b742..6afafb6824 100644
--- a/widgets/table/e-table-sorter.c
+++ b/widgets/table/e-table-sorter.c
@@ -45,6 +45,8 @@ static ESorterClass *parent_class;
static void ets_model_changed (ETableModel *etm, ETableSorter *ets);
static void ets_model_row_changed (ETableModel *etm, int row, ETableSorter *ets);
static void ets_model_cell_changed (ETableModel *etm, int col, int row, ETableSorter *ets);
+static void ets_model_rows_inserted (ETableModel *etm, int row, int count, ETableSorter *ets);
+static void ets_model_rows_deleted (ETableModel *etm, int row, int count, ETableSorter *ets);
static void ets_sort_info_changed (ETableSortInfo *info, ETableSorter *ets);
static void ets_clean (ETableSorter *ets);
static void ets_sort (ETableSorter *ets);
@@ -67,13 +69,22 @@ ets_destroy (GtkObject *object)
ets->table_model_row_changed_id);
gtk_signal_disconnect (GTK_OBJECT (ets->source),
ets->table_model_cell_changed_id);
+ gtk_signal_disconnect (GTK_OBJECT (ets->source),
+ ets->table_model_rows_inserted_id);
+ gtk_signal_disconnect (GTK_OBJECT (ets->source),
+ ets->table_model_rows_deleted_id);
gtk_signal_disconnect (GTK_OBJECT (ets->sort_info),
ets->sort_info_changed_id);
+ gtk_signal_disconnect (GTK_OBJECT (ets->sort_info),
+ ets->group_info_changed_id);
ets->table_model_changed_id = 0;
ets->table_model_row_changed_id = 0;
ets->table_model_cell_changed_id = 0;
+ ets->table_model_rows_inserted_id = 0;
+ ets->table_model_rows_deleted_id = 0;
ets->sort_info_changed_id = 0;
+ ets->group_info_changed_id = 0;
if (ets->sort_info)
gtk_object_unref(GTK_OBJECT(ets->sort_info));
@@ -95,6 +106,8 @@ ets_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
if (ets->sort_info) {
if (ets->sort_info_changed_id)
gtk_signal_disconnect(GTK_OBJECT(ets->sort_info), ets->sort_info_changed_id);
+ if (ets->group_info_changed_id)
+ gtk_signal_disconnect(GTK_OBJECT(ets->sort_info), ets->group_info_changed_id);
gtk_object_unref(GTK_OBJECT(ets->sort_info));
}
@@ -102,6 +115,8 @@ ets_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
gtk_object_ref(GTK_OBJECT(ets->sort_info));
ets->sort_info_changed_id = gtk_signal_connect (GTK_OBJECT (ets->sort_info), "sort_info_changed",
GTK_SIGNAL_FUNC (ets_sort_info_changed), ets);
+ ets->group_info_changed_id = gtk_signal_connect (GTK_OBJECT (ets->sort_info), "group_info_changed",
+ GTK_SIGNAL_FUNC (ets_sort_info_changed), ets);
ets_clean (ets);
break;
@@ -155,7 +170,10 @@ ets_init (ETableSorter *ets)
ets->table_model_changed_id = 0;
ets->table_model_row_changed_id = 0;
ets->table_model_cell_changed_id = 0;
+ ets->table_model_rows_inserted_id = 0;
+ ets->table_model_rows_deleted_id = 0;
ets->sort_info_changed_id = 0;
+ ets->group_info_changed_id = 0;
}
E_MAKE_TYPE(e_table_sorter, "ETableSorter", ETableSorter, ets_class_init, ets_init, PARENT_TYPE);
@@ -178,8 +196,14 @@ e_table_sorter_new (ETableModel *source, ETableHeader *full_header, ETableSortIn
GTK_SIGNAL_FUNC (ets_model_row_changed), ets);
ets->table_model_cell_changed_id = gtk_signal_connect (GTK_OBJECT (source), "model_cell_changed",
GTK_SIGNAL_FUNC (ets_model_cell_changed), ets);
+ ets->table_model_rows_inserted_id = gtk_signal_connect (GTK_OBJECT (source), "model_rows_inserted",
+ GTK_SIGNAL_FUNC (ets_model_rows_inserted), ets);
+ ets->table_model_rows_deleted_id = gtk_signal_connect (GTK_OBJECT (source), "model_rows_deleted",
+ GTK_SIGNAL_FUNC (ets_model_rows_deleted), ets);
ets->sort_info_changed_id = gtk_signal_connect (GTK_OBJECT (sort_info), "sort_info_changed",
GTK_SIGNAL_FUNC (ets_sort_info_changed), ets);
+ ets->group_info_changed_id = gtk_signal_connect (GTK_OBJECT (sort_info), "group_info_changed",
+ GTK_SIGNAL_FUNC (ets_sort_info_changed), ets);
return ets;
}
@@ -203,6 +227,18 @@ ets_model_cell_changed (ETableModel *etm, int col, int row, ETableSorter *ets)
}
static void
+ets_model_rows_inserted (ETableModel *etm, int row, int count, ETableSorter *ets)
+{
+ ets_clean(ets);
+}
+
+static void
+ets_model_rows_deleted (ETableModel *etm, int row, int count, ETableSorter *ets)
+{
+ ets_clean(ets);
+}
+
+static void
ets_sort_info_changed (ETableSortInfo *info, ETableSorter *ets)
{
d(g_print ("sort info changed\n"));
diff --git a/widgets/table/e-table-sorter.h b/widgets/table/e-table-sorter.h
index 02d51c5522..b0097b9155 100644
--- a/widgets/table/e-table-sorter.h
+++ b/widgets/table/e-table-sorter.h
@@ -56,7 +56,10 @@ typedef struct {
int table_model_changed_id;
int table_model_row_changed_id;
int table_model_cell_changed_id;
+ int table_model_rows_inserted_id;
+ int table_model_rows_deleted_id;
int sort_info_changed_id;
+ int group_info_changed_id;
} ETableSorter;
typedef struct {
diff --git a/widgets/table/e-table-subset-variable.c b/widgets/table/e-table-subset-variable.c
index a55f162bcf..6d298d6050 100644
--- a/widgets/table/e-table-subset-variable.c
+++ b/widgets/table/e-table-subset-variable.c
@@ -203,6 +203,21 @@ e_table_subset_variable_remove (ETableSubsetVariable *etssv,
}
void
+e_table_subset_variable_clear (ETableSubsetVariable *etssv)
+{
+ ETableModel *etm = E_TABLE_MODEL(etssv);
+ ETableSubset *etss = E_TABLE_SUBSET(etssv);
+
+ e_table_model_pre_change (etm);
+ etss->n_map = 0;
+ g_free (etss->map_table);
+ etss->map_table = g_new (unsigned int, 1);
+ etssv->n_vals_allocated = 1;
+
+ e_table_model_changed (etm);
+}
+
+void
e_table_subset_variable_increment (ETableSubsetVariable *etssv,
gint position,
gint amount)
diff --git a/widgets/table/e-table-subset-variable.h b/widgets/table/e-table-subset-variable.h
index 4ee55f5670..eae291b1d2 100644
--- a/widgets/table/e-table-subset-variable.h
+++ b/widgets/table/e-table-subset-variable.h
@@ -56,26 +56,27 @@ typedef struct {
gint row);
} ETableSubsetVariableClass;
-GtkType e_table_subset_variable_get_type (void);
-ETableModel *e_table_subset_variable_new (ETableModel *etm);
-ETableModel *e_table_subset_variable_construct (ETableSubsetVariable *etssv,
- ETableModel *source);
-void e_table_subset_variable_add (ETableSubsetVariable *ets,
- gint row);
-void e_table_subset_variable_add_array (ETableSubsetVariable *ets,
- const gint *array,
- gint count);
-void e_table_subset_variable_add_all (ETableSubsetVariable *ets);
-gboolean e_table_subset_variable_remove (ETableSubsetVariable *ets,
- gint row);
-void e_table_subset_variable_increment (ETableSubsetVariable *ets,
- gint position,
- gint amount);
-void e_table_subset_variable_decrement (ETableSubsetVariable *ets,
- gint position,
- gint amount);
-void e_table_subset_variable_set_allocation (ETableSubsetVariable *ets,
- gint total);
+GtkType e_table_subset_variable_get_type (void);
+ETableModel *e_table_subset_variable_new (ETableModel *etm);
+ETableModel *e_table_subset_variable_construct (ETableSubsetVariable *etssv,
+ ETableModel *source);
+void e_table_subset_variable_add (ETableSubsetVariable *ets,
+ gint row);
+void e_table_subset_variable_add_array (ETableSubsetVariable *ets,
+ const gint *array,
+ gint count);
+void e_table_subset_variable_add_all (ETableSubsetVariable *ets);
+gboolean e_table_subset_variable_remove (ETableSubsetVariable *ets,
+ gint row);
+void e_table_subset_variable_clear (ETableSubsetVariable *ets);
+void e_table_subset_variable_increment (ETableSubsetVariable *ets,
+ gint position,
+ gint amount);
+void e_table_subset_variable_decrement (ETableSubsetVariable *ets,
+ gint position,
+ gint amount);
+void e_table_subset_variable_set_allocation (ETableSubsetVariable *ets,
+ gint total);
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/widgets/table/e-table-subset.c b/widgets/table/e-table-subset.c
index d57867bd2a..c5399ce402 100644
--- a/widgets/table/e-table-subset.c
+++ b/widgets/table/e-table-subset.c
@@ -163,9 +163,7 @@ etss_is_cell_editable (ETableModel *etm, int col, int row)
static gboolean
etss_has_save_id (ETableModel *etm)
{
- ETableSubset *etss = (ETableSubset *)etm;
-
- return e_table_model_has_save_id (etss->source);
+ return TRUE;
}
static char *
@@ -173,7 +171,10 @@ etss_get_save_id (ETableModel *etm, int row)
{
ETableSubset *etss = (ETableSubset *)etm;
- return e_table_model_get_save_id (etss->source, etss->map_table [row]);
+ if (e_table_model_has_save_id (etss->source))
+ return e_table_model_get_save_id (etss->source, etss->map_table [row]);
+ else
+ return g_strdup_printf ("%d", etss->map_table[row]);
}
static void